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

来源:互联网 发布:tcp通信安卓app源码 编辑:程序博客网 时间:2024/05/22 09:51
#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;}