问题描述:
Student A took 5 courses this semester. Below table lists due time to submit his homework from now on. It also lists the time to finish those works.
As the time is limited, some homework cannot be finished on time. What he can do is arranging his time in a smart way so that he can finish more homework on time. Please do bellowing work:
1) Write C program to get the right arrangement
2) Write makefile for this program
3) Write detail description of this program (in Microsoft Word format).
问题分析:
该问题等价于最优化问题,即现在有N个任务,每个任务需要一个时间区间ti来处理。每个任务i可以灵活处理,只要在规定的截止时间di之间完成处理就行,即任务i在时间段0~di -ti的任意一个时刻,并且要求一个长度为ti连续的时间区间。虽然如此,但是因为只有一个资源来完成任务,所以不同的任务要求被分在完全不重叠的区间。 在这种情况下,根据想要优化的目标,应该存在许多的优化方法。简单而有效优化方法,考虑一个非常自然的通过贪心算法可以被优化的目标。有几种自然的贪心方法,在这些方法中我考虑任务的数据有(ti,di),并且按照某种简单的规则对他们排序。
1. 一种方法是把任务按长度ti增长的次序安排,使得较短的任务尽快结束。但是它完全忽略了任务的截止时间。例如,题目中提供的作业D,完成它所需的时间为1,最短,但是它的截止时间为7,而其他的作业虽然完成他们所需的时间较长,但是截止时间较短。如果要想尽可能多得完成任务,显然安排先完成作业D不巧当,而安排先完成其他的作业比较合适。因此该规则的最优化规则失效。
2. 根据1的分析我们应该可以考虑先完成(di-ti)非常小的任务,这种任务是那种需要用最小松弛时间开始的任务,即先安排完成可调整时间最短的作业。因此将按照di-ti增长的次序对任务排序。但是,这种贪心规则也不是最优的。考虑两个任务的实例,假设有3个任务,他们的截止时间和完成任务所需的时间分别为(1)8和7,(2)4和2,(3)5和3,那么按照2的规则,先选择任务(1),那么最终完成的任务只有任务(1),完成的任务数量也只有1;而选择任务(2)或者(3),那么可以在规定的时间内可以完成任务(2)和(3),完成的任务数量为2.因此该规则也失效。
3. 综合考虑di和ti。因为每个任务只要在它的截止时间之前完成即可,而不需要该什么时候开始,那么要想完成更多的任务,先完成截止时间较短的任务,并放弃已超过截止时间的任务。一般来说,截止时间小的作业暗示着完成该作业所需的时间也少,反之不一定成立。因此要想完成更多的作业,那么需要在作业的截止时间之前一个一个的完成它。总之,优化的思路为:a.在未完成的任务中,选择截止时间较早的任务,记为 i,若完成其所需的时间ti小于它的截止时间di,那么放弃完成该任务,继续a步骤,否则,就选择完成该任务,并且更新剩下未完成任务的截止时间,即将它们的截止时间减去完成前一个任务所需的时间,继续a步骤。根据该规则写出该算法:
i.初始化定义
i1. 定义一个2维数组 Task[3][NUMOFTASK]。其中第一行的元素表示任务i的截止时间,第二行的元素表示完成任务i所需时间,第三行表示任务i的代号(因为排序,所以需要记住其任务代号1.. NUMOFTASK)。这里NUMOFTASK表示任务数量。为了简单表示符号,用三个一维数组Task0 [NUMOFTASK] , Task1 [NUMOFTASK], Task2[NUMOFTASK]表示 Task[3][NUMOFTASK] 对应的第0、1、2行;
i2. 完成任务代号数组FinishedTask[NUMOFTASK],初始化全为0(如果FinishedTask[]数组元素值为任务代号i,表示完成了任务i)。
i3. 已完成任务数量SumOfFinishedTask=0.
a.将所有的任务按照截止时间从小到大排序。若存在截止时间相同的情况,那么进一步按照其对应的完成所需时间从小到大排序。根据第一行排好序为: Task1[0]<= Task1[1]...<= Task1[NUMOFTASK-1](对应的Task1[]、Task2[]对应的元素位置也更改好)。
b. 按照Task0[]的次序考虑任务i,i从1到NUMOFTASK(或者是0~NUMOFTASK-1) 将Task0[i]与Task1[i]进行比较,
b1.若小于,那么跳过,重复b;
b2.若大于等于,那么执行该任务,并且
b21.将Task2[i]录入以完成任务的数组,同时SumOfFinishedTask加1.
b22.j从i+1到NUMOFTASK(这里表示未完成的任务),
b221.更新截止时间,即用当前的截止时间减去完成任务i所需要的时间,Task1[j]=Task1[j]-Task2[i]
c.打印完成任务总数SumOfFinishedTask,并根据它打印出完成的任务的顺序即其代号,结束。
代码实现:
#include <stdio.h>
#define NUMOFTASK 5
void swap(int *a,int *b)
{
int temp=*a;
*a=*b;
*b=temp;
return;
}
int partition(int *r, int first, int end)
{
int i=first;
int j=end;
while (i<j)
{
while (i<j&&*(r+i)<=*(r+j))
{
if(*(r+i)==*(r+j))//如果两者的截止时间相等,那么需要接着比较完成他们所需要的时间
if(*(r+i+2*NUMOFTASK)>*(r+j+2*NUMOFTASK))
break;
j--;
}
if(i<j)
{
swap((r+i),(r+j));
swap((r+i)+NUMOFTASK,(r+j)+NUMOFTASK);
swap((r+i)+2*NUMOFTASK,(r+j)+2*NUMOFTASK);
i++;
}
while (i<j&&*(r+i)<=*(r+j))
{
if(*(r+i)==*(r+j))//如果两者的截止时间相等,那么需要接着比较完成他们所需要的时间
if(*(r+i+2*NUMOFTASK)>*(r+j+2*NUMOFTASK))
break;
i++;
}
if(i<j)
{
swap((r+i),(r+j));
swap((r+i)+NUMOFTASK,(r+j)+NUMOFTASK);
swap((r+i)+2*NUMOFTASK,(r+j)+2*NUMOFTASK);
j--;
}
}
return i;
}
void QuickSort(int *r,int first,int end)
{
if(first<end)
{
int pivot=partition(r, first, end);
QuickSort(r, first, pivot-1);
QuickSort(r, pivot+1, end);
}
}
int main (int argc, const char * argv[])
{
int DueTime[][NUMOFTASK]={{8,3,3,7,4},{1,2,3,4,5},{5,2,2,1,2}};//DueTime数组元素第一行代表一个任务的截止时间,第二行代表任务的代号,第三行代表完成任务所需的时间,仅供排序用
int TimeToFinish[NUMOFTASK]={5,2,2,1,2};//TimeToFinish数组元素代表任务所需的时间
int FinishedTask[NUMOFTASK]={0};//FinishedTask用来表示完成的任务代号,元素值为0表示没没完成任务
int SumOfFinishedTask=0;//记录完成任务的数量
//对DueTime数组元素的第一行元素进行快速排序,当DueTime中的截止时间有相同的情况时,按照对应的TimeToFinish元素从小到大排序,
//如果一个任务的截止时间与完成任务所需的时间一样,那么随机排序
QuickSort(*DueTime, 0, NUMOFTASK-1);
int i=0;//老的编译器不支持在for语句中定义变量
for(i=0;i<NUMOFTASK;i++)
{
if(DueTime[0][i]>=TimeToFinish[DueTime[1][i]-1])//截止时间大于等于任务所需时间,那么就可以顺利执行完该任务
{
FinishedTask[SumOfFinishedTask++]=DueTime[1][i];
int j=i+1;
for(;j<NUMOFTASK;j++)
{
DueTime[0][j]=DueTime[0][j]-TimeToFinish[DueTime[1][i]-1];//将剩下的任务的截止时间减下完成前一个任务所花的时间
}
}
}
//打印出完成的任务数量
printf("completed:%d tasks!\n",SumOfFinishedTask);
//打印出完成的任务的顺序即其代号
for (i=0; i<SumOfFinishedTask; i++) {
//if(FinishedTask[i]!=0)
printf("step %d:\tFinished No.%d Task。\n",i+1,FinishedTask[i]);
}
return 0;
}
更多详细信息请查看
java教程网 http://www.itchm.com/forum-59-1.html
分享到:
相关推荐
《数字信号处理——原理、实现及应用》是由高西全等专家编著的一部深入探讨数字信号处理领域的经典教材。这本书全面介绍了数字信号处理的基本概念、理论基础以及实际应用,对于学习和理解数字信号处理技术具有重要的...
【数学广角——优化沏茶问题】是针对数学中的优化理论和时间管理概念的一个教学案例。这个PPT学习教案旨在帮助学生理解如何通过合理安排任务来节省时间和提高效率,这在日常生活和工作中都非常实用。 首先,案例...
这种类型的优化问题具有全局最优解的特性,即找到的解是全局最小值,而非局部最小值。在图像处理中,凸优化常用于解决如图像去噪、图像恢复等非线性问题。 MATLAB是一个强大的数学计算软件,而CVX是MATLAB的一个...
**基于LSTM网络的垃圾邮件处理——自然语言处理(NLP)** 在现代通信中,垃圾邮件已经成为一个普遍的问题,不仅占用用户的时间,还可能带来潜在的安全风险。为了解决这个问题,我们可以利用机器学习和自然语言处理...
这种并行处理的思想是优化问题的基础,让学生意识到合理安排时间的重要性。 接下来,课程引入了一个更具体的问题——烧水泡茶。这里涉及到了流程分析和时间规划。学生需要理解,洗水壶和接水是烧水的前提,这两个...
在2020年的MathorCup高校数学建模挑战赛中,参赛者们面临了一个实际的仓储管理问题,即“仓内拣货优化问题”。该问题的核心是提高订单拣货效率,涉及到拣货员的任务分配、行走路径规划以及复核台的工作效率提升。 ...
通过阅读博客文章《tomcat engine,host,context的管道处理——pipeline》(链接:https://yjhexy.iteye.com/blog/670309),你可以获得更详细的信息,包括如何配置和使用Valves,以及Pipeline的高级用法。...
对于集合划分问题,可以定义一个二维数组dp,其中dp[i][mask]表示处理到第i个元素时,使用mask这个子集状态的最小子集数量。通过转移方程,可以从已知状态推导出未知状态。 3. 贪心算法:贪心策略是每次做出局部...
在分词中,它通过学习词语边界特征,对每个字预测其是否为词的起始或结束,从而得到最优化的分词结果。这种方法的优势在于能考虑上下文信息,提高分词的准确性。 另一篇文档“基于有效子串的字标注分词”则可能涉及...
负载均衡确保所有节点都能充分参与任务处理,避免某些节点过载或闲置;而减少IPC开销则旨在降低因数据传输导致的时间延迟和带宽消耗,从而提升整体系统的响应速度和吞吐量。 #### 遗传算法的应用 遗传算法是一种...
在IT领域,尤其是在图论和算法设计中,解决“最短路径问题”是一个经典而重要的任务。本案例中,我们关注的是美国硅谷城镇地图上的最短路径问题,它涉及到网络中的节点(城镇)和边(连接城镇的路径),以及边上的...
蚁群算法是一种模拟自然界蚂蚁寻找食物路径的优化算法,它在解决组合优化问题,如旅行商问题(TSP)上表现出色。旅行商问题是一个经典的图论问题,目标是找到访问每个城市一次并返回起点的最短路径。在这个问题中,蚁...
总的来说,这个PPT学习教案通过实例教学,帮助学生理解和应用数学中的优化概念,提升他们在日常生活和未来工作中解决问题的能力,强调了合理安排时间和任务顺序对于提高效率的重要性。通过这样的教学,学生不仅能...
在本文中,我们将深入探讨如何使用Matlab进行无人机药品配送路线的最优化规划。这个问题属于经典的运筹学问题,可以通过数学建模和特定算法来解决。我们主要关注两个关键概念:路径规划和拉格朗日中值定理的优化应用...
《工程与技术科学——工程控制论——基于粒子群算法的PERT网络优化问题研究》这篇文献主要探讨了在工程控制论的背景下,如何运用粒子群算法解决PERT(Program Evaluation and Review Technique)网络的优化问题。...
在机器学习领域,数据是驱动模型训练和性能优化的核心要素。"data.rar"这个压缩包文件显然包含了用于机器学习的数据集。...在实际操作中,具体的数据处理和模型选择会根据数据集的性质和任务需求而变化。
指派问题是一种优化问题,通常出现在资源分配、任务调度等领域,目标是找到一种方式将一组任务有效地分配给一组工人,使得总成本或时间最小化。在这个案例中,我们使用MATLAB的遗传算法(Genetic Algorithm,简称GA...
8. **优化**:在数值处理中,优化通常涉及找到使目标函数最小化的变量值,这在工程、经济和数据科学中广泛存在,例如最小二乘法、拉格朗日乘数法和约束优化问题。 9. **错误和异常处理**:在编程中,数值计算可能会...
标题中的“数字信号处理大作业——编写FFT程序”是指一项针对数字信号处理的学习任务,要求学生编程实现快速傅立叶变换(FFT),这是一种用于计算离散傅立叶变换(DFT)的高效算法。FFT在计算机科学和工程领域,尤其...