达到最高效益的调度

http://blog.csdn.net/wenlei_zhouwl/article/details/5993185

问题: 假设有一台机器,以及在此机器上处理的n个作业a1,a2,...an的集合。每隔作业aj有一个处理时间tj,效益pj,以及最后期限dj。机器在一个时刻只能处理一个作业,而且作业aj必须在tj连续时间单位内不间断地运行。如果作业aj在最后期限dj之前完成,则获得效益pj,但如果在最后期限之后才完成,则没有效益。请给出一个动态规划算法,来寻找能获得最大量效益的调度,假设所有的处理时间都是1到n之间的整数。


分析:  
其实这个问题类似于01背包问题。
1.    将a1,a2,…,an按照dj值排序,从小到大。假设接下来的分析中,已经保证当i<j时,di<dj。添加d0=0。
2.    构建数组s[n][d[n]],s[i][j]代表在j时间内,调度i个作业,所得最高效益值。初始时,令s[i][0] = 0(i = 0->n),s[0][j] = 0(j = 0->d[n])。

3.    求s[i][j]的值,select[i][j]用于记录是否选择i。这里递归包含了一种思想:如果第i个作业被调度,那么最好使其在期限时正好结束,这样能够保证i之前的作业能够在更充裕的时间内被调度。


for i = 1->n
for j = 1->d[i]
    //不调度i
    s[i][j] = s[i-1][min(j, d[i-1])]
    select[i][j] = false
    //调度i
    if j>t[i]
        if s[i][j] < s[i-1][min(j-t[i], d[i-1])]+p[i]
            s[i][j] = s[i-1][min(j-t[i], d[i-1])]+p[i]
            select[i][j] = true

我之前任务这就是一个单纯的背包问题,不理解上面为什么要排序,为什么要求min

下面的段错误的代码:

int maxV = 0x80000000;
	int f[N] = {0};
	for (int i = 0; i < n; ++i ) {
		for (int v = work[i].deadline; v >= work[i].time; --v) {
			f[v] = max(f[v],f[v - work[i].time] + work[i].productivity);
			if (maxV < f[v])
				maxV = f[v];
		}
	}
	cout<<maxV<<endl;

#define N 10
//每个作业作为一个结点
struct node
{
	int time;//处理时间
	int productivity;//效益
	int deadline;//最后期限
}work[N];


这是因为任务有截止期限的,所以必须按照di从小到大排序

下面的代码比较好理解

sort();
    int end = deadline[0] - time[0];
    for (int i = 0; i < end; ++i)
        f[0][i] = 0;
    for (int i = end; i<= deadline[0]; ++i)
        f[0][i] = value[i];
    
    for (int i = 1; i < n; ++i) {
        for (int j = 0; j <= deadline[i]; ++j) {
            if (j< time[i])//如果结束时间比运行时间还少, 则不能选择这个作业
            {
                f[i][j] = f[i-1][min(j,deadline[i-1])];
            }
            else {
                int end = j - time[i];
                f[i][j] =max( f[i-1][min(end, deadline[i-1])] + value[i], f[i-1][deadline[i-1]]);//如果和前一个冲突,选与不选的问题
            }
        }
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值