算法设计与分析——独立任务最优调度问题

问题描述

独立任务最优调度问题

问题描述:
用2台处理机A和B处理n个作业。设第i个作业交给机器A处理时需要时间ai.若由机器B来处理,则需要时间bi。由于各作业的特点和机器的性能关系,很可能对于某些i,有ai≥bi,而对于某些j≠i,有aj< bj;。既不能将一个作业分开由2台机器处理,也没有一台机器能同时处理2个作业。设计个动态规划算法,使得这2台机器处理完这n个作业的时间最短(从任何一台机器开工到最后一台机器停工的总
时间)。
研究一个实例:(a1,a2 ,a3,a4,a5,a5) = (2,5,7,10,5,2);
(b1,b2,b3,b4,b5,b6)= (3,8,4,11,3,4)。

算法设计:
对于给定的2台处理机A和B处理n个作业,找出一个最优调度方案,使2台机器处理完这n个作业的时间最短。

数据输入:
由文件input. txt提供输入数据。文件的第1行是1个正整数n,表示要处理n个作业,在接下来的2行中,每行有n个正整数,分别表示处理机A和B处理第i个作业需要的处理时间。
结果输出:
将计算出的最短处理时间输出到文件output txt。

输入文件示例
input. txt
6
2 5 7 10 5 2
3 8 4 11 3 4

输出文件示例

output. txt
15

问题分析

算法设计——动态规划

最优子结构性质:

设f[i][j]表示完成i个作业且机器A花费j时间的条件下机器B所花费时间的最小值,一定要注意这是B花费的时间。

可以往前递推一下,f[i][j]怎么得到的,也就是说当第i-1件任务完成后,第i件任务需要确定谁来做,这是一个子问题。

(1)若第i件任务由A来做,那么机器B花费的时间就是A完成前i-1个任务的时间(此时A还没有做第i件任务,所以花费的时间会比完成第i件任务少a[i])
即f[i-1][j-a[i]],相当于B没有做第i件任务,所以B花费的最短时间和做完第i-1件任务一样。

(2)若第i件任务由B来做,那么机器B花费的时间就是f[i-1][j]+b[i],也就是A完成了i-1个任务花费j时间的条件下加上B自己做第i件任务的时间。

为什么不需要像(1)那样减掉a[i]呢?因为第i件任务不是A做的,所以可以直接用j来代表A做完i-1件任务花的时间。

但是有一种情况是不能让A来做的,我们的j可以从0到sumA,其中sumA为假如按照所有的任务都由A来完成,A需要的时间的累加,比如说进行到第i件任务,那么sumA就是a[0]+a[1]+…+a[i]。如果完成i个任务花费的时间比A做第i个任务的时间还要少的话,即j<a[i],那么为了使A这边在j时间内完成i个任务(注意,第i个任务不是由A来做的,只是说当进行到第i个任务时,A花费的时间不会超过j)第i个任务只能由B来完成。

相当于你为了在10min内走完1km,如果你一直走,那么用时就会超过10min,所以后面一定要骑车,或者用更快的方式完成。在这种情况下,机器B花费的最少时间是f[i-1][j]+b[i];

由于两机器可以同时工作,A的运行对B的运行没有影响,确定了第i件任务由谁来完成,B花的时间最短,然后再从A和B中取得最晚的停机时间,就可以确定A和B完成任务的最短时间。所以问题满足最优子结构性质

构造最优解

6个任务
A机器完成时间2 5 7 10 5 2
B机器完成时间3 8 4 11 3 4

以前两个任务为例

第一个任务,0<=x<2,f[1][x]=b[1]是当A一直开机直到x,此时第一件任务只能由B来完成,因为A完成第一件任务至少需要2时间。
当x=a[1]时,比较A完成第一个任务的时间和B完成第一个任务的时间,如果A需要的时间更短,那么B根本不需要花时间完成第一个任务,f[1][2]就是0,否则第一件任务就给B来完成,B花费的最短时间就是b[1]

第二个任务往后,先初始化所有B花费的时间都是正无穷,然后计算sumA=a[1]+a[2]=7,
X=0,f[2][0]=f[1][0]+b[2]=b[1]+b[2]=11,max(0,11)=11;
X=1,f[2][1]=f[1][1]+b[2]=b[1]+b[2]=11,max(1,11)=11;
X=2,f[2][2]=f[1][2]+b[2]=0+b[2]=8,max(2,8)=8;
X=3,f[2][3]=f[1][3]+b[2]=0+b[2]=8,max(3,8)=8;
X=4,f[2][4]=f[1][4]+b[2]=0+b[2]=8,max(4,8)=8;
X=5,f[2][5]=min(f[1][5]+b[2],f[1][5-a[2]])=min(8,3)=3,max(5,3)=5;
X=6,f[2][6]=min(f[1][6]+b[2],f[1][6-a[2]])=min(8,3)=3,max(6,3)=6;
X=7,f[2][7]=min(f[1][7]+b[2],f[1][7-a[2]])=min(8,0)=0,max(7,3)=7;
完成第二件任务需要的最少时间是当X=5的时候,此时B执行第一件任务,A执行第二件任务,同时进行

当完成最后一件任务时,A的停机时间是j(即花费时间),B的停机时间是f[n][j],(就是A完成n件任务花费j时间的时候B停机的时间),要取最后停机的那个时间才是最后的时间就是

  • 36
    点赞
  • 147
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Data Structures, Algorithms, and Applications in C++, Second Edition 出版者的话 译者序 前言 第一部分 预备知识 第1章 C++回顾 1.1 引言 1.2 函数与参数 1.2.1 传值参数 1.2.2 模板函数 1.2.3 引用参数 1.2.4 常量引用参数 1.2.5 返回值 1.2.6 重载函数 1.3 异常 1.3.1 抛出异常 1.3.2 处理异常 1.4 动态存储空间分配 1.4.1 操作符new 1.4.2 一维数组 1.4.3 异常处理 1.4.4 操作符delete 1.4.5 二维数组 1.5 自有数据类型 1.5.1 类currency 1.5.2 一种不同的描述方法 1.5.3 操作符重载 1.5.4 友元和保护性类成员 1.5.5 增加#ifndef、#define和#endif语句 1.6 异常类illegalParameterValue 1.7 递归函数 1.7.1 递归的数学函数 1.7.2 归纳 1.7.3 C++递归函数 1.8 标准模板库 1.9 测试与调试 1.9.1 什么是测试 1.9.2 测试数据的计 1.9.3 调试 1.10 参考及推荐读物 第2章 程序性能分析 2.1 什么是程序性能 2.2 空间复杂度 2.2.1 空间复杂度的组成 2.2.2 举例 2.3 时间复杂度 2.3.1 时间复杂度的组成 2.3.2 操作计数 2.3.3 最好、最坏和平均操作计数 2.3.4 步数 第3章 渐近记法 3.1 引言 3.2 渐近记法 3.2.1 大Ο记法 3.2.2 渐近记法Ω和Θ 3.3 渐近数学(可选) 3.3.1 大O记法 3.3.2 Ω记法 3.3.3 Θ记法 3.3.4 小ο记法 3.3.5 特性 3.4 复杂度分析举例 3.5 实际复杂度 3.6 参考及推荐读物 第4章 性能测量 4.1 引言 4.2 选择实例的大小 4.3 计测试数据 4.4 实验计 4.5 高速缓存 4.5.1 简单计算机模型 4.5.2 缓存未命中对运行时间的影响 4.5.3 矩阵乘法 4.6 参考及推荐读物 第二部分 数据结构 第5章 线性表——数组描述 5.1 数据对象和数据结构 5.2 线性表数据结构 5.2.1 抽象数据类型linearList 5.2.2 抽象类linearList 5.3 数组描述 5.3.1 描述 5.3.2 变长一维数组 5.3.3 类arrayList 5.3.4 C++迭代器 5.3.5 arrayList的一个迭代器 5.4 vector的描述 5.5 在一个数组中实现的多重表 5.6 性能测量 5.7 参考及推荐读物 第6章 线性表——链式描述 6.1 单向链表 6.1.1 描述 6.1.2 结构chainNode 6.1.3 类chain 6.1.4 抽象数据类型linearList的扩充 6.1.5 类extendedChain 6.1.6 性能测量 6.2 循环链表和头节点 6.3 双向链表 6.4 链表用到的词汇表 6.5 应用 6.5.1 箱子排序 6.5.2 基数排序 6.5.3 凸包 6.5.4 并查集 第7章 数组和矩阵 7.1 数组 7.1.1 抽象数据类型 7.1.2 C++数组的索引 7.1.3 行主映射和列主映射 7.1.4 用数组的数组来描述 7.1.5 行主描述和列主描述 7.1.6 不规则二维数组 7.2 矩阵 7.2.1 定义和操作 7.2.2 类matrix 7.3 特殊矩阵 7.3.1 定义和应用 7.3.2 对角矩阵 7.3.3 三对角矩阵 7.3.4 三角矩阵 7.3.5 对称矩阵 7.4 稀疏矩阵 7.4.1 基本概念 7.4.2 用单个线性表描述 7.4.3 用多个线性表描述 7.4.4 性能测量 第8章 栈 8.1 定义和应用 8.2 抽象数据类型 8.3 数组描述 8.3.1 作为一个派生类实现 8.3.2 类arrayStack 8.3.3 性能测量 8.4 链表描述 8.4.1 类derivedLinkedStack 8.4.2 类linkedStack 8.4.3 性能测量 8.5 应用 8.5.1 括号匹配 8.5.2 汉诺塔 8.5.3 列车车厢重排 8.5.4 开关盒布线 8.5.5 离线等价类问 8.5.6 迷宫老鼠 8.6 参考及推荐读物 第9章 队列 9.1 定义和应用 9.2 抽象数据类型 9.3 数组描述 9.3.1 描述 9.3.2 类arrayQueue 9.4 链表描述 9.5 应用 9.5.1 列车车厢重排 9.5.2 电路布线 9.5.3 图元识别 9.5.4 工厂仿真 9.6 参考及推荐读物 第10章
实验原理: 在独立任务调度问题中,每个任务都有一个执行时间和一个截止时间,任务之间没有任何依赖关系。任务调度的目标是在满足所有任务的截止时间的前提下,最大化已完成任务的数量。这是一个经典的NP完全问,因此需要采用高效的算法来解决。 动态规划是一种重要的解决最优化问算法,可以用于解决独立任务调度问题动态规划算法的基本思想是将问分解成一系列重叠的子问,并通过求解子问最优解来求解原问最优解。 解步骤: 1. 确定状态:在独立任务调度问题中,状态可以用一个二元组(i, t)来表示,其中i表示任务的编号,t表示当前时间。 2. 确定状态转移方程:根据目中的约束条件和目标函数,计状态转移方程,用于计算每个状态的最优解。 3. 初始化状态:将第一个任务的状态作为初始状态,即(i, 0),其中i为第一个任务的编号,时间为0。 4. 递推求解:利用状态转移方程,从初始状态开始逐步计算每个状态的最优解,直到达到最终状态,即(n, T),其中n为任务数量,T为所有任务的最大截止时间。 5. 回溯求解:根据递推计算所得的最优解,回溯求解出每个任务最优调度方案。 以上是解决独立任务调度问题动态规划算法的基本步骤。需要根据具体情况进行算法计和实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值