算法分析与设计(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])(j\geq t[i]) $

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

    $dp[j]=max(dp[j],dp[j-t[i]]+t[i])(j\geq 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\times V)\)。对于方案的输出同理,那么总体时间复杂度就是 \(O(n\times V)\)

5、源码

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

posted @ 2021-05-28 18:28  hachuochuo  阅读(268)  评论(0编辑  收藏  举报