回溯法-5.3批处理作业调度

来源:互联网 发布:java常见的接口 编辑:程序博客网 时间:2024/04/29 18:28

问题描述:给定n个作业的集合{J1,J2,…,Jn}。每个作业必须先由机器1处理,然后由机器2处理。作业Ji需要机器j的处理时间为tji。对于一个确定的作业调度,设Fji是作业i在机器j上完成处理的时间。所有作业在机器2上完成处理的时间和称为该作业调度的完成时间和。
批处理作业调度问题要求对于给定的n个作业,制定最佳作业调度方案,使其完成时间和达到最小
1
分析:这3个作业的6种可能的调度方案是1,2,3;1,3,2;2,1,3;2,3,1;3,1,2;3,2,1;它们所相应的完成时间和分别是19,18,20,21,19,19。易见,最佳调度方案是1,3,2,其完成时间和为18。
以3,1,2顺序为例
1

算法实现步骤

1.if(当前层大于总数) 遍历到排序树的叶节点
2.else 遍历到排序树的第k层节点
—①先向下一层子节点探索
—-if(若当前完成时间和小于当前最优值) 则递归到下一层节点
—②回溯到父节点

public class test5_3 {    static int n = 3,                        //作业数                               (需初始化)               f = 0,                        //完成时间和               f1 = 0,                       //机器1完成处理时间               bestf = Integer.MAX_VALUE;    //当前最优值                        (需初始化最大值)    static int[][] m = {{0,0,0}              //各作业所需的处理时间       (需初始化)                       ,{0,2,1}                       ,{0,3,1}                       ,{0,2,3}};    static int[] x = {0,1,2,3};              //当前作业调度                     (需初始化)    static int[] bestx = new int[n+1];       //当前最优作业调度    static int[] f2 = new int[n+1];          //机器2完成处理时间    /**     * 回溯法     * @param k 表示遍历的排序树的层数,初始k=1,表示从第一层根节点开始     */    private static void backtrack(int k){        //1.遍历到排序树的叶节点        if(k>n){            for(int i=1;i<=n;i++)                bestx[i] = x[i];            bestf = f;        }else        //2.遍历到排序树的第k层节点    k∈[1:n]            for(int i=k;i<=n;i++){   //排列树下此for循环抽象成广度优先搜索,即从k节点下的(n-k)个子分支依次遍历                //*****2.1先向下一层子节点探索****(值的探索)******************                f1 += m[x[i]][1];                f2[k] = ((f2[k-1]>f1)? f2[k-1]:f1) + m[x[i]][2];                f += f2[k];                //*****2.1先向下一层子节点探索*****(值的探索)*****************                //*****2.2若当前完成时间和小于当前最优值,则递归到下一层节点********                if(f<bestf){                     swap(x,k,i);//类别全排列算法(节点的真正探索)                    backtrack(k+1);  //抽象成深度优先搜索,即递归到下一层节点                    swap(x,k,i);//类别全排列算法(节点的真正回溯)                }                //*****2.2若当前完成时间和小于当前最优值,则递归到下一层节点********                //*****2.3回溯到父节点***********(值的回溯)*****************                f1 -= m[x[i]][1];                f -= f2[k];                //*****2.3回溯到父节点***********(值的回溯)****************            }    }    private static void swap(int[] x,int i,int j){        int temp;        temp = x[i];        x[i] = x[j];        x[j] = temp;    }    public static void main(String[] args) {        backtrack(1);        System.out.println("最优调度下完成时间和为:"+bestf);        System.out.print("最优作业调度顺序如下:");        for(int i=1;i<=n;i++)            System.out.print(bestx[i]+" ");    }}

运行结果如下:

最优调度下完成时间和为:18最优作业调度顺序如下:1 3 2 

总结:最坏情况下,整个算法的时间复杂度为O(n!)。