zoukankan      html  css  js  c++  java
  • 装配线调度

    问题:一个工厂有两条装配线a1, a2,每条装配线有n个装配站,每个编号对等的装配站功能相同。机器只要依次通过编号为1,2,...,n的装配站即可加工完成。已知两条装配线各个装配站装配所需的时间即a1,1,a1,2,...,a1,n,  a2,1,a2,2,...,a2,n, 进入装配线所需时间e1,e2,离开装配线所需时间x1,x2。有时候为了加快装配进度,可以将部分完成的机器从一条装配线移到另一条装配线,所需时间分别为t1,1,t1,2,...,t1,n-1,  t2,1,t2,2,...,t2,n-1. 求机器制造所需的最短时间。

    算法基本思路:

    1.计算最优解即最短时间;

    要求最短时间,可以看作求到达装配s1,n, s2,n的最短时间。要到达s1,n,有两种可能。

    (1)从s1,n-1直接到s1,n;

    (2)从s2,n-1经过t2,n-1到达s1,n

    对于s2,n,也是类似情况。

    不难看出,几乎对于所有站点都存在这个性质(起始站点除外)。满足最优子结构,和重叠子问题(对等编号的站点对前一站点的最优时间重复使用),可用动态规划法。

    设f[1][i]表示到达装配线1上 i 号站点所需的最短时间,f[2][i]表示到达装配线2上 i 号站点所需的最短时间。

    f[1][1]初始化为e[1] + a[1][1],f[2][1]初始化为e[2] + a[2][1]。则有,

    f[1][i] = min{f[1][i-1] + a[1][i], f[2][i-1] + t[2][i-1] + a[1][i]}, (2<= i <= n)

    f[2][i] = min{f[2][i-1] + a[2][i], f[1][i-1] + t[1][i-1] + a[2][i]}, (2<= i <= n)

    此时易得最小时间 t = min{f[1][n] + x[1], f[2][n] + x[2]}。

    2.构造获得最短时间的路线。

    在计算最短时间的基础上,多开一个记录表 l[1][i] 表示 到达装配线1上 i 号站点的前一个站点, l[2][i] 表示 到达装配线2上 i 号站点的前一个站点。

    从最后一个站点逆推可得整条路线。

    public class AssemblyLineScheduling{
    
        public static String fastestWay(int[][] a, int[][] t, int[] e, int[] x){
            /*
            a means the cost time of assembly station
            t means the transform time betweeen different line
            e means the time of enter assembly line
            x means the time of exit assembly line
            return the cost time of the fastest way
            */
            int n = a[0].length;
            int[][] f = new int[2][n];
            int[][] l = new int[2][n-1];
            //init
            f[0][0] = a[0][0] + e[0];
            f[1][0] = a[1][0] + e[1];
            //dynamic programming
            for(int i = 1; i < n; i ++){
                if(f[0][i-1] + a[0][i] < f[1][i-1] + t[1][i-1] + a[0][i]){
                    f[0][i] = f[0][i-1] + a[0][i];
                    l[0][i-1] = 0;
                }
                else{
                    f[0][i] = f[1][i-1] + t[1][i-1] + a[0][i];
                    l[0][i-1] = 1;
                }
                if(f[0][i-1] + t[0][i-1] + a[1][i] < f[1][i-1] + a[1][i]){
                    f[1][i] = f[0][i-1] + t[0][i-1] + a[1][i];
                    l[1][i-1] = 0;
                }
                else{
                    f[1][i] = f[1][i-1] + a[1][i];
                    l[1][i-1] = 1;
                }
            }
            int r;
            int p;
            //build the path
            if(f[0][n-1] + x[0] < f[1][n-1] + x[1]){
                r = f[0][n-1] + x[0];
                p = 0;
            }
            else{
                r = f[1][n-1] + x[1];
                p = 1;
            }
            String result = "line " + p + ", station " + (n-1) + "
    " + r;
            for(int i = n-2; i >= 0; i --){
                result = "line " + l[p][i] + ", station " + i + "
    " + result;
                p = l[p][i];
            }
            return result;
        }
    
        public static void main(String[] args) {
            //Unit Testing
            int[][] a = {{7, 9, 3, 4, 8, 4}, {8, 5, 6, 4, 5, 7}};
            int[][] t = {{2, 3, 1, 3, 4}, {2, 1, 2, 2, 1}};
            int[] e = {2, 4};
            int[] x = {3, 2};
            System.out.println(fastestWay(a, t, e, x));
        }
        
    }
    Java
  • 相关阅读:
    13.Query for Null or Missing Fields-官方文档摘录
    海南IT互联网招聘数据简单分析
    Mongo Spark Connector中的分区器(一)
    一、Golang中的反射基本使用
    Golang中的sync.Pool对象
    Golang中的内置函数
    golang单元测试简述
    Spark Streaming数据限流简述
    Golang中类面向对象特性
    在Docker中跑Hadoop与镜像制作
  • 原文地址:https://www.cnblogs.com/7hat/p/3458756.html
Copyright © 2011-2022 走看看