第五章 回溯法-批处理作业调度

http://blog.csdn.net/wzq153308/article/details/46365177

问题描述

给定 n 个作业的集合 j = {j1, j2, …, jn}。每一个作业 j[i] 
都有两项任务分别在两台机器上完成。每一个作业必须先由机器1 
处理,然后由机器2处理。作业 j[i] 需要机器 j 的处理时间为 
t[j][i] ,其中i = 1, 2, …, n, j = 1, 2。对于一个确定的作业
调度,设F[j][i]是作业 i 在机器 j 上的完成处理的时间。所有作
业在机器2上完成处理的时间之和 f = sigma F[2][i] 称为该作业
调度的完成时间之和。

批处理作业调度问题要求对于给定的 n 个作业,制定最佳作业调度方案,使其完成时间和达到最小。

[java] 
view plain
copy

  1. /*该代码采用了回溯法解决最优调度问题。 
  2.  * 算法思想:对于有n个不同的任务,搜索出其最佳排列,属于一棵排列树搜索问题。 
  3.  * 采用回溯法,搜索到第t层时,当已经是叶子节点时,说明该路径就是当前情况下的最优解。 
  4.  * 当t不是叶子节点时,依次按照一定的顺序执行当前剩下的任务,将剩下的任务全部遍历一遍。 
  5.  * 在遍历过程中,按照schedule[t:n]完成剩下的搜索。计算执行当前任务后,各个时间点 
  6.  * 的变化。如果该层某个节点的任务执行之后,依然符合剪枝函数,则将当前的策略顺序做出 
  7.  * 调整,将刚刚执行的那个节点的任务序号放置到当前,然后继续向下进行搜索。 
  8.  *  
  9.  * 剪枝函数:当当前节点的总时间已经大于已找到的最优时间,则该节点后面的节点都不用进行搜索。直接回溯。 
  10.  *  
  11.  * */  
  12. package BackTrack;  
  13.   
  14.   
  15. public class BestSchedule2 {  
  16.     int n=3;//作业数  
  17.     int[][] mission={{2,1},{3,1},{2,3}};  
  18.     int bestFinishtime = Integer.MAX_VALUE;//最短时间  
  19.     int[] schedule = {0,1,2};//默认的策略顺序。  
  20.     int[] bestSchedule = new int[n];//最佳顺序  
  21.     int[] f2 = new int[n];//第二台机器的每个任务的结束时间  
  22.     int f1,totaltime;//f1当前任务的结束时间,f2的总时间  
  23.     public void swap(int[] str,int m,int n){  
  24.         int temp = str[m];  
  25.         str[m] = str[n];  
  26.         str[n] = temp;  
  27.     }  
  28.       
  29.     public void BackTrack(int t){  
  30.         //当搜索到叶子节点后,将这次遍历的策略赋值到最佳策略。  
  31.         if(t>n-1){  
  32.             bestFinishtime = totaltime;  
  33.             for(int i=0;i<n;i++)  
  34.                 bestSchedule[i] = schedule[i];  
  35.             return;  
  36.         }  
  37.   
  38.         for(int i=t;i<n;i++){        //下面执行的是第t次的任务,全部遍历剩下的可能性。  
  39.             f1+=mission[schedule[i]][0];  
  40.             if(t==0)   
  41.                 f2[t]=f1+mission[schedule[i]][1];  
  42.             else  
  43.                 f2[t] = ((f2[t-1]>f1)?f2[t-1]:f1)+mission[schedule[i]][1];  
  44.             totaltime += f2[t];  
  45.             //如果该作业处理完之后,总时间已经超过最优时间,就直接回溯。  
  46.             if(totaltime<bestFinishtime){  
  47.                 swap(schedule,t,i); //把选择出的原来在i位置上的任务序号调到当前执行的位置t  
  48.                 BackTrack(t+1);  
  49.                 swap(schedule,t,i);//进行回溯,还原,执行该层的下一个任务。  
  50.             }  
  51.             f1 -= mission[schedule[i]][0];  
  52.             totaltime -= f2[t];  
  53.         }  
  54.     }         
  55.     public static void main(String[] args){  
  56.         BestSchedule2 bs = new BestSchedule2();  
  57.         bs.BackTrack(0);  
  58.         System.out.println(“最佳调度方案为:”);  
  59.         for(int i=0;i<bs.n;i++)  
  60.             System.out.print(bs.bestSchedule[i]+”  “);  
  61.         System.out.println();  
  62.         System.out.println(“其完成时间为”+bs.bestFinishtime);  
  63.     }  
  64. }  
    原文作者:分支限界法
    原文地址: https://blog.csdn.net/weinierbian/article/details/50243187
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞