zoukankan      html  css  js  c++  java
  • 流水作业调度

    2018-03-18 20:37:06

    问题描述:

    n个作业 N={1,2,…,n}要在2台机器M1和M2组成的流水线上完成加工。每个作业须先在M1上加工,然后在M2上加工。M1和M2加工作业 i 所需的时间分别为 ai 和bi,每台机器同一时间最多只能执行一个作业。

    流水作业调度问题要求确定这n个作业的最优加工顺序,使得所有作业在两台机器上都加工完成所需最少时间。

    问题求解:

    流水作业调度问题的每个作业都会被分成若干部分,例如本例中的2部分,然后这两部分会有先后的在两台不同的机器上进行执行,最后求解的是在最终所有任务完成的时间。

    流水作业问题是个NPC问题,在m > 2的时候目前没有找到很好的解决方法。在n = 2的前提下,可以使用Johnson法则在O(nlogn)完成求解。

    Johnson法则:

    对作业i,j,若满足min{bi, aj} >= min{bj, ai},则称,作业i,作业j满足Johnson法则。

    已经被证明所有满足John法则的调度都是最优调度,Johnson法则的证明过程是比较繁琐的,可以进行定性的证明:

    直观上,一个最优调度应该使机器M1没有空闲时间,且机器M2的空闲时间最少。

    bi和aj是产生重叠的部分,如果该部分越大,则说明机器M2的空闲时间越少,因此我们所有的调度都应该满足这个法则。

    因此本题就规约为了如何构造出一个满足Johnson法则的调度。

    可以采取以下的策略进行构造:

    public class MultiDispatch {
        class Pair{
            int index;
            int val;
            boolean flag;
    
            Pair(int index, int val, boolean flag) {
                this.index = index;
                this.val = val;
                this.flag = flag;
            }
        }
    
        int multiDispatch(int[] a, int[] b) {
            int[] res = new int[a.length];
            boolean[] visited = new boolean[a.length];
            Arrays.fill(visited, false);
            Pair[] queue = new Pair[a.length + b.length];
            int j = 0;
            for (int i = 0; i < a.length; i++) {
                queue[j++] = new Pair(i, a[i], true);
                queue[j++] = new Pair(i, b[i], false);
            }
            Arrays.sort(queue, new Comparator<Pair>() {
                @Override
                public int compare(Pair o1, Pair o2) {
                    return o1.val - o2.val;
                }
            });
            int s = 0;
            int e = res.length - 1;
            for (int i = 0; i < queue.length; i++) {
                if (visited[queue[i].index]) continue;
                if (queue[i].flag) {
                    res[s++] = queue[i].index;
                    visited[queue[i].index] = true;
                }
                else {
                    res[e--] = queue[i].index;
                    visited[queue[i].index] = true;
                }
            }
    
            int m1 = 0;
            int m2 = 0;
            for (int i = 0; i < res.length; i++) {
                m1 += a[res[i]];
                m2 = Math.max(m1, m2) + b[res[i]];
            }
            return m2;
        }
    
        public static void main(String[] args) {
            MultiDispatch md = new MultiDispatch();
            System.out.println(md.multiDispatch(new int[]{5,12,4,8}, new int[]{6,2,14,7}));
        }
    }
    
  • 相关阅读:
    phalcon—— PHP基础知识(一)
    仿淘宝商品浏览界面, 向上拉查看详情
    linux执行run文件显示cannot execute binary file
    atitit.client连接oracle数据库的方式总结
    LeetCode203:Remove Linked List Elements
    DotNetBar.Bar图标列表的使用
    3509.com 纵横天下虚拟主机,垃圾中的战斗机
    RT-Thread内核之线程调度(三)
    CSDN-Code平台公钥设置
    2014年工作中遇到的20个问题:81-100
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/8597548.html
Copyright © 2011-2022 走看看