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

问题描述:给定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!)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SL_World

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值