• 算法分析与设计(final)


    1、问题

    设有 (n) 项任务,加工时间分别表示为正整数(t_{1},t_{2},...,t_{n}).现有2台同样的机器,从 (0) 时刻开始安排对这些任务的加工。规定只要有待加工的任务,任何机器就不得闲置。如果直到时刻 (T) 所有任务都完成了,总加工时间就等于 (T) 。设计一个算法找到使得总加工时间T达到最小的调度方案。

    2、解析

    • 观察所给问题,发现只要有代加工的任务,任何机器都不得空闲,那么即从 (0) 时刻开始,机器不停在运转,设两台机器的加工时间为 (T_{1},T_{2}),有一下两个约束条件:1、 (T=max(T_{1},T_{2})) , 2、(T_{1}+T_{2}=sum^{n}_{i=1} t_{i})

    • 那么显然问题就可以转化为把 (t_{1},t_{2},...,t_{n})划分成两部分,一部分之和为(T_{1}),另一部分之和为(T_{2}),使得 (max(T_{1},T_{2}))最小。

    • 因为 (sum^{n}_{i=1} t_{i}) 是固定的,所以条件 (max(T_{1},T_{2}))最小等同于 (abs(T_{1}-T_{2}))最小。也就是说让 (T_{1},T_{2})都尽可能的接近背包的一半。

    • 也就是对于数组 (t) 中的元素,我们有两种选择,第一种就是放到第一台机器上,第二种就是放到第二台机器上,很显然这就相当与选和不选两种选择,也就可以转化为 01背包 问题。

    • 最终问题可以这样描述:从 (n) 个数中选择一些数,让这些数之和尽量接近这 (n) 个数的总和 (sum) 的一半,并输出选择方案。

    • 暴力方法的时间复杂度高达 (O(2^n)),显然不可行。

    • 考虑动态规划去求解,可以直接用 01背包 求解,背包容量为 (sum/2),目标就是尽量填满背包。每个物品的体积就是数的大小。

    • 原因:我们选择了一些数,那么另外一些数就可以确定,那么总和小的一部分数必定是小于等于 (sum/2),那么为了目标最优,也就是让这一部分数尽量填满 (sum/2) 的容量。

    • (dp[i][j]) 表示当背包容量为 (j) 时,从前 (i) 项任务中可选出的最大体积。转移方程为:
      .

      $dp[i][j]=max(dp[i-1][j],dp[i][j-t[i]]+t[i])(jgeq t[i]) $

    • 我们可以对空间进行进一步优化,即使用滚动数组把二维优化到一维。 (dp[j]) 表示对于体积为 (j)的背包,从所有任务中可选出的最大体积。转移方程为:
      .

      $dp[j]=max(dp[j],dp[j-t[i]]+t[i])(jgeq t[i]) $


    • 接下来考虑怎么输出方案,我们考虑在 (dp) 过程中遇到答案更新就标记在这个位置进行了更新,即标记 (path[i][j]=1),表示第 (i) 件任务在当背包容量为 (j) 时被选取了。然后就可以对包的容量 (V) 从大到小遍历,从此同时对物品 (i) 也从大到小遍历,对于某一对 (i,j),如果 (path[i][j]=1),此时就说明第 (i) 件任务被选取,然后为了继续向下回溯,此时 (j=j-t[i]),直到 (j=0)

    3、设计

    • 01背包部分
    int V=sum/2;
    for(int i=1;i<=n;i++){
        for(int j=V;j>=t[i];j--){
            if(dp[j-t[i]]+t[i]>dp[j]){
                dp[j]=dp[j-t[i]]+t[i];
                path[i][j]=1;
            }
        }
    }
    

    (max(dp[V],sum-dp[V]))即最少总加工时间

    • 输出方案部分
    for(int i=n,j=V;i>=1&&j>0;i--){
        if(path[i][j]){
            ans[i]=1;
            j-=t[i];
        }
    }
    

    (ans[i])就是任务的分组

    4、分析

    考虑01背包的时间复杂度,两层循环嵌套,外层是任务总数 (O(n)),内层就是背包的容量 (O(V)),总体时间复杂度(O(n imes V))。对于方案的输出同理,那么总体时间复杂度就是 (O(n imes V))

    5、源码

    https://github.com/HaHe-a/Algorithm-analysis-and-design-code/blob/master/final.cpp

    越自律,越自由
  • 相关阅读:
    PHP-FPM 不完全指南
    【权限设计】如何以“权限”为单位的进行权限设计(二)
    【权限设计】如何以“用户”为单位的进行权限设计(一)
    【权限设计】一个案例,三个角色,简单说下B端产品的权限设计
    gdb调试报错:Missing separate debuginfos, use: debuginfo-install glibc-XXX
    java之 ------ 文件拷贝
    高速排序C++实现
    error: internal error: unable to execute QEMU command &#39;migrate&#39;: this feature or command is not cur
    MySQL查询报错 ERROR: No query specified
    广告倒计时欢迎界面的实现
  • 原文地址:https://www.cnblogs.com/ha-chuochuo/p/14823479.html
Copyright © 2020-2023  润新知