批处理作业问题——分支限界法
来源:互联网 发布: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;}
阅读全文
0 0
- 批处理作业问题——分支限界法
- 0040算法笔记——【分支限界法】批处理作业调度问题
- 0040算法笔记——【分支限界法】批处理作业调度问题
- 算法java实现--分支限界法--批处理作业调度问题
- 批处理作业调度问题(分支限界法)
- 算法作业-批处理作业调度-回溯|分支限界法
- 0033算法笔记——【分支限界法】分支限界法与单源最短路径问题
- 0033算法笔记——【分支限界法】分支限界法与单源最短路径问题
- 0035算法笔记——【分支限界法】布线问题
- 0035算法笔记——【分支限界法】布线问题
- 分支限界——01背包问题
- 分配问题-分支限界法
- 布线问题-分支限界法
- 分支限界法:布线问题
- 分支限界批处理的算法
- 算法——分支限界
- 0034算法笔记——【分支限界法】最优装载问题
- 0036算法笔记——【分支限界法】0-1背包问题
- HDOJ 1215 七夕节
- Linux中的自动安装脚本
- 2017-10-31每日一练
- 刷题——5.5
- LeetCode 121: Best Time to Buy and Sell Stock
- 批处理作业问题——分支限界法
- 重命名UE4项目
- 译文及题解 电话线Telephone Wire(动态规划)
- 关于未来,仅供参考
- 第一次实验
- vue组件通信
- Android基础复习(二)
- 每日练习20171031
- bzoj 2669: [cqoi2012]局部极小值