批处理作业问题——分支限界法

#include <iostream>
using namespace std;

//最小堆的插入与删除
template<class T>
class MinHeap
{
    template<class Type>
    friend class Graph;

    public:
        MinHeap(int maxheapsize = 10);
        ~MinHeap(){delete []heap;}

        int Size() const{return currentsize;}
        MinHeap<T>& Insert(const T& x);
        MinHeap<T>& DeleteMin(T &x);


    private:
        int currentsize, maxsize;
        T *heap;
};

template <class T>
MinHeap<T>::MinHeap(int maxheapsize)//构造函数 没有返回值类型
{
    maxsize = maxheapsize;
    heap = new T[maxsize + 1];
    currentsize = 0;

}

template<class T>
MinHeap<T>&  MinHeap<T>::Insert(const T& x)//返回类型是MinHeap<T>
{
    if(currentsize == maxsize)
    {
        return *this;
    }
    int i = ++currentsize;
    while(i != 1 && x < heap[i/2])
    {
        heap[i] = heap[i/2];
        i /= 2;
    }

    heap[i] = x;
    return *this;
}

template<class T>
MinHeap<T>&  MinHeap<T>::DeleteMin(T& x) //返回类型是MinHeap<T>
{
    if(currentsize == 0)
    {
        cout<<"Empty heap!"<<endl;
        return *this;
    }

    x = heap[1];

    T y = heap[currentsize--];
    int i = 1, ci = 2;
    while(ci <= currentsize)
    {
        if(ci < currentsize && heap[ci] > heap[ci + 1])
        {
            ci++;
        }

        if(y <= heap[ci])
        {
            break;
        }
        heap[i] = heap[ci];
        i = ci;
        ci *= 2;
    }

    heap[i] = y;
    return *this;
}




//开始作业调度
class Flowshop;
class MinHeapNode
{
    friend Flowshop;
    public:
        operator int() const
        {
            return bb;
        }
    private:
        void Init(int);
        void NewNode(MinHeapNode,int,int,int,int);
        int s,          //已安排作业数
            f1,         //机器1上最后完成时间
            f2,         //机器2上最后完成时间
            sf2,        //当前机器2上完成时间和
            bb,         //当前完成时间和下界
            *x;         //当前作业调度
};

class Flowshop
{
    friend int main(void);
    public:
        int BBFlow(void);
    private:
        int Bound(MinHeapNode E,int &f1,int &f2,bool **y);
        void Sort(void);
        int n,          //作业数
            ** M,       //各作业所需的处理时间数组
            **b,        //各作业所需的处理时间排序数组
            **a,        //数组M和b的对应关系数组
            *bestx,     //最优解
            bestc;      //最小完成时间和
        bool **y;       //工作数组
};

template <class Type>
inline void Swap(Type &a, Type &b);

int main()
{
    int n=3,bf;
    int M1[3][2]={{2,1},{3,1},{2,3}};

    int **M = new int*[n];
    int **b = new int*[n];
    int **a = new int*[n];
    bool **y = new bool*[n];
    int *bestx = new int[n];

    for(int i=0;i<=n;i++)
    {
        M[i] = new int[2];
        b[i] = new int[2];
        a[i] = new int[2];
        y[i] = new bool[2];
    }
    cout<<"各作业所需要的处理时间"<<endl;
    cout<<"     机器1 机器2  "<<endl;

    for(int i=0;i<n;i++)
    {
        for(int j=0;j<2;j++)
        {
            M[i][j]=M1[i][j];
        }
    }

    for(int i=0;i<n;i++)
    {
        cout<<"作业"<<i+1<<":";
        for(int j=0;j<2;j++)
        cout<<M[i][j]<<"      ";
        cout<<endl;

    }
    cout<<endl;

    Flowshop flow;
    flow.n = n;
    flow.M = M;
    flow.b = b;
    flow.a = a;
    flow.y = y;
    flow.bestx = bestx;
    flow.bestc = 1000;//给初值

    flow.BBFlow();

    cout<<"最少花费是:"<<flow.bestc<<endl;
    cout<<"最优解空间是:";

    for(int i=0;i<n;i++)
    {
        cout<<(flow.bestx[i]+1)<<" ";
    }
    cout<<endl;

    for(int i=0;i<n;i++)
    {
        delete[] M[i];
        delete[] b[i];
        delete[] a[i];
        delete[] y[i];
    }
    return 0;
}

//最小堆节点初始化
void MinHeapNode::Init(int n)
{
    x = new int[n];
    for(int i=0; i<n; i++)
    {
        x[i] = i;
    }
    s = 0;
    f1 = 0;
    f2 = 0;
    sf2 = 0;
    bb = 0;
}

//最小堆新节点
void MinHeapNode::NewNode(MinHeapNode E,int Ef1,int Ef2,int Ebb,int n)
{
    x = new int[n];
    for(int i=0; i<n; i++)
    {
        x[i] = E.x[i];
    }
    f1 = Ef1;
    f2 = Ef2;
    sf2 = E.sf2 + f2;
    bb = Ebb;
    s =  E.s + 1;
}

//对各作业在机器1和2上所需时间排序 排序成非递减
void Flowshop::Sort(void)
{
    int *c = new int[n];
    for(int j=0; j<2; j++)
    {
        for(int i=0; i<n; i++)
        {
            b[i][j] = M[i][j];
            c[i] = i;
        }

        for(int i=0; i<n-1; i++)
        {
            for(int k=n-1; k>i; k--)
            {
                if(b[k][j]<b[k-1][j])
                {
                    Swap(b[k][j],b[k-1][j]);
                    Swap(c[k],c[k-1]);
                }
            }
        }

        for(int i=0; i<n; i++)
        {
            a[c[i]][j] = i;
        }
    }

    delete []c;
}

//计算完成时间和下界
int Flowshop::Bound(MinHeapNode E,int &f1,int &f2,bool **y)
{
    for(int k=0; k<n; k++)
    {
        for(int j=0; j<2; j++)
        {
            y[k][j] = false;
        }
    }

    for(int k=0; k<=E.s; k++)
    {
        for(int j=0; j<2; j++)
        {
            y[a[E.x[k]][j]][j] = true;
        }
    }

    f1 = E.f1 + M[E.x[E.s]][0];
    f2 = ((f1>E.f2)?f1:E.f2)+M[E.x[E.s]][1];
    int sf2 = E.sf2 + f2;
    int s1 = 0,s2 = 0,k1 = n-E.s,k2 = n-E.s,f3 = f2;

    //计算s1的值
    for(int j=0; j<n; j++)
    {
        if(!y[j][0])
        {
            k1--;
            if(k1 == n-E.s-1)
            {
                f3 = (f2>f1+b[j][0])?f2:f1+b[j][0];
            }
            s1 += f1+k1*b[j][0];
        }
    }

    //计算s2的值
    for(int j=0; j<n; j++)
    {
        if(!y[j][1])
        {
            k2--;
            s1 += b[j][1];
            s2 += f3 + k2*b[j][1];
        }
    }

    //返回完成时间和下界
    return sf2 +((s1>s2)?s1:s2);
}

//解批处理作业调度问题的优先队列式分支限界法
int Flowshop::BBFlow(void)
{
    Sort();//对各作业在机器1和2上所需时间排序
    MinHeap<MinHeapNode> H(1000);

    MinHeapNode E;
    //初始化
    E.Init(n);
    //搜索排列空间树
    while(E.s<=n)
    {
        //叶节点
        if(E.s == n)
        {
            if(E.sf2<bestc)
            {
                bestc = E.sf2;
                for(int i=0; i<n; i++)
                {
                    bestx[i] = E.x[i];
                }
            }
            delete []E.x;
        }
        else//产生当前扩展节点的儿子节点
        {
            for(int i=E.s; i<n; i++)
            {
                Swap(E.x[E.s],E.x[i]);
                int f1,f2;
                int bb = Bound(E,f1,f2,y);
                if(bb<bestc)
                {
                    //子树可能含有最优解
                    //节点插入最小堆
                    MinHeapNode N;
                    N.NewNode(E,f1,f2,bb,n);
                    H.Insert(N);
                }
                Swap(E.x[E.s],E.x[i]);
            }
            delete []E.x;//完成节点扩展
        }
        if(H.Size() == 0)
        {
            break;
        }
        H.DeleteMin(E);//取下一扩展节点
    }
    return bestc;
}

template <class Type>
inline void Swap(Type &a, Type &b)
{
    Type temp=a;
    a=b;
    b=temp;
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值