算法java实现--分支限界法--批处理作业调度问题

来源:互联网 发布:初学java看什么书好 编辑:程序博客网 时间:2024/05/01 14:51

批处理作业调度问题的java实现(优先队列式分支限界法)

具体问题描述以及C/C++实现参见网址

http://blog.csdn.net/liufeng_king/article/details/8952235

import java.util.Collections;import java.util.LinkedList;/** * 批处理作业调度问题--优先队列式分支限界法 * @author Lican * */public class BBFlow {public int n;//作业数public int bestc;//最小完成时间和public int [][]m;//个作业所需的处理时间数组public int [][]b;//个作业所需的处理时间排序数组public int[][] a;//数组m和b的对应关系数组public int[] bestx;//最优解public boolean[][] y;//工作数组public BBFlow(int n,int[][] m){this.n=n;bestc=10000;this.m=m;b=new int[n][2];a=new int[n][2];bestx=new int[n];y=new boolean[n][2];}public void swap(int[][] b,int i,int j,int k,int t){int temp=b[i][j];b[i][j]=b[k][t];b[k][t]=temp;}public void swap(int[] x,int i,int j){int temp=x[i];x[i]=x[j];x[j]=temp;}/** * 对个作业在机器1和2上所需时间排序 */public void sort(){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,k-1,j);swap(c,k,k-1);}}}for(int i=0;i<n;i++)a[c[i]][j]=i;}}/** * 计算完成时间和下界 * @param enode * @param f * @return */public int bound(Nodes enode,int[] f){for(int k=0;k<n;k++){for(int j=0;j<2;j++){y[k][j]=false;}}for(int k=0;k<enode.s;k++){for(int j=0;j<2;j++){y[a[enode.x[k]][j]][j]=true;}}f[1]=enode.f[1]+m[enode.x[enode.s]][0];f[2]=((f[1]>enode.f[2])?f[1]:enode.f[2])+m[enode.x[enode.s]][1];int sf2=enode.sf2+f[2];int s1=0;int s2=0;int k1=n-enode.s;int k2=n-enode.s;int f3=f[2];//计算s1的值for(int j=0;j<n;j++){if(!y[j][0]){k1--;if(k1==n-enode.s-1)f3=(f[2]>f[1]+b[j][0])?f[2]:f[1]+b[j][0];s1+=f[1]+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);}/** * 优先队列式分支限界法解批处理作业调度问题 * @param nn * @return */public int bbFlow(int nn){n=nn;sort();//对个作业在机器1和2上所需时间排序LinkedList<Nodes> heap=new LinkedList<Nodes>();Nodes enode =new Nodes(n);//搜索排列空间树do{if(enode.s==n){//叶节点if(enode.sf2<bestc){bestc=enode.sf2;for(int i=0;i<n;i++){bestx[i]=enode.x[i];}}}else{//产生当前扩展结点的儿子结点for(int i=enode.s;i<n;i++){swap(enode.x,enode.s,i);int[] f=new int[3];int bb=bound(enode,f);if(bb<bestc){//子树可能含有最优解//结点插入最小堆Nodes node=new Nodes(enode,f,bb,n);heap.add(node);Collections.sort(heap);}swap(enode.x,enode.s,i);}//完成结点扩展}//取下一个扩展结点enode=heap.poll();}while(enode!=null&&enode.s<=n);return bestc;}public static void main(String[] args) {int n=3;int[][] m={{2,1},{3,1},{2,3}};//m的下标从0开始BBFlow f=new BBFlow(n,m);f.bbFlow(n);System.out.println("最优批处理作业调度顺序为:");for(int i=0;i<n;i++)System.out.print((f.bestx[i]+1)+" ");System.out.println();System.out.println("最优调度所需的最短时间为:"+f.bestc);}}class Nodes implements Comparable{int s;//已安排作业数int sf2;//当前机器2上的完成时间和int bb;//当前完成时间和下界int[] f;//f[1]机器1上最后完成时间,f[2]机器2上最后完成时间int[] x;//当前作业调度public Nodes(int n){//最小堆结点初始化x=new int[n];for(int i=0;i<n;i++)x[i]=i;s=0;f=new int[3];f[1]=0;f[2]=0;sf2=0;bb=0;}public Nodes(Nodes e,int[] ef,int ebb,int n){//最小堆新结点x=new int[n];for(int i=0;i<n;i++)x[i]=e.x[i];f=ef;sf2=e.sf2+f[2];bb=ebb;s=e.s+1;}@Overridepublic int compareTo(Object o) {int xbb=((Nodes) o).bb;if(bb<xbb) return -1;if(bb==xbb) return 0;return 1;}}/*运行结果:最优批处理作业调度顺序为:1 3 2 最优调度所需的最短时间为:18*/


0 0
原创粉丝点击