#include "iostream" #include "ctime" using namespace std; typedef struct { int tasksign; //任务标志 int timestart; //任务开始时间 int timeend; //任务结束时间 int wage; //暂时用不到,可以不考虑,下面讨论动态规划时用到 }task; void IntervalScheduler(task tasks[], int total); //区间内任务调度实现 void QuickSort_End(task tasks[], int startindex, int endindex); //快速排序以结束时间从小到大 int Privot_End(task tasks[], int startindex, int endindex); //快排中的子函数,用于找到中轴 void IntervalScheduler_Greedy(task tasks[], int total); //贪心算法实现 void IntervalScheduler_DynamicProgramming(task tasks[], int total); //动态规划实现 int main() { const int TIMESTART = 0; //任务的开始时间 const int TIMEEND = 100; //任务的结束时间 const int TOTALTASKS = 20; //任务的总数 task tasks[TOTALTASKS]; int i = int(); srand((unsigned int)time(NULL)); //以时间做为随机数种子 for (; i<TOTALTASKS; i++){ //在TIMESTART 和 TIMEEND之间随机产生任务的开始时间和结束时间 tasks[i].tasksign = i; tasks[i].timestart = TIMESTART + (rand() % (TIMESTART - TIMEEND + 1)); tasks[i].timeend = tasks[i].timestart + (rand() % (TIMEEND - tasks[i].timestart + 1)); tasks[i].wage = i % (TOTALTASKS/2); } IntervalScheduler(tasks, TOTALTASKS); //区间调度问题贪心实现 return 0; } void IntervalScheduler(task tasks[], int total) { int i = int(); cout << "未排序前各任务状态" << endl; for (i=0; i<total; i++){ //输出随机产生的各任务状态 cout <<"任务标志:" << tasks[i].tasksign <<" 任务开始时间:" << tasks[i].timestart << " 任务结束时间:" << tasks[i].timeend << " 报酬: " << tasks[i].wage << endl; } IntervalScheduler_Greedy(tasks, total); //用贪心算法实现 IntervalScheduler_DynamicProgramming(tasks, total); //动态规划实现 } void IntervalScheduler_Greedy(task tasks[], int total) //贪心算法实现 { int i = int(); int maxtasks =int(); int currenttime = int(); QuickSort_End(tasks, 0, total-1); //以任务的结束时间从小到大排序 cout << endl << "排序后各任务的状态" << endl; for (i=0; i<total; i++){ //输出排序后各任务的状态 cout <<"任务标志:" << tasks[i].tasksign <<" 任务开始时间:" << tasks[i].timestart << " 任务结束时间:" << tasks[i].timeend << " 报酬: " << tasks[i].wage << endl; } cout <<endl; currenttime = tasks[0].timestart; for (i=0; i<total; i++){ //根据贪心算法找对在这一区间内最多可共存的任务数 if (tasks[i].timestart >= currenttime){ cout <<"任务标志:" << tasks[i].tasksign <<" 任务开始时间:" << tasks[i].timestart << " 任务结束时间:" << tasks[i].timeend << " 报酬: " << tasks[i].wage << endl; currenttime = tasks[i].timeend; maxtasks++; } } cout << "最大共存任务数 " << maxtasks << endl; // 贪心算法实现部分结束 } void QuickSort_End(task tasks[], int startindex, int endindex) //快速排序以结束时间从小到大 { if (startindex < endindex){ int privotpostion; privotpostion = Privot_End(tasks, startindex, endindex); QuickSort_End(tasks, startindex, privotpostion-1); QuickSort_End(tasks, privotpostion+1, endindex); } } int Privot_End(task tasks[], int startindex, int endindex) //找中轴以任务结束时间的从小到大 { task temp; int i; i = startindex + rand() % (endindex - startindex + 1); //加入随机找中轴,平衡快排的时间,不至于对某些 temp = tasks[i]; //实例算法的最坏到O(n2),从而稳定在O(n㏒n),实质是代价分摊 tasks[i] = tasks[startindex]; while (startindex < endindex){ while ( (startindex < endindex) && (tasks[endindex].timeend > temp.timeend) ) endindex--; tasks[startindex] = tasks[endindex]; while ( (startindex < endindex) && (tasks[startindex].timeend <= temp.timeend) ) startindex++; tasks[endindex] = tasks[startindex]; } tasks[startindex] = temp; return startindex; }
转自: http://blog.sina.com.cn/pc178

区间调度问题 ,最大利润作业调度问题
// 首先介绍什么是贪心算法(贪婪算法)
//
// 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,
// 他所做出的仅是在某种意义上的局部最优解。
//   贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最
// 优解或者是整体最优解的近似解。
//   贪心算法的基本思路如下:
//   1.建立数学模型来描述问题。
//   2.把求解的问题分成若干个子问题。
//   3.对每一子问题求解,得到子问题的局部最优解。
//   4.把子问题的解局部最优解合成原来解问题的一个解。
//   实现该算法的过程:
//    从问题的某一初始解出发;
//    while 能朝给定总目标前进一步 do
//    求出可行解的一个解元素;
//    由所有解元素组合成问题的一个可行解;
//
//
// 例题:
// 现有1,2,3......n个任务,各个任务的开始时间和结束时间都是在时间段[ timestart, timeend]内随机生成的,
// 要求在ts-te时间段内能够完成最多的任务,并求出这些任务。

//上述实现对于这类各任务的重要性相同的情况是适用的,但实际上可能有些任务比较急迫(或更为重要)。例如:任务1做了
//可以获利10,需要时间为 5;任务2做了可以获利20,需要时间为 15。如果做任务1、任务2是互斥,那么我们我们做哪个呢?
//答案是:需要从整体考虑,显然就单个任务的性价比看,做任务1更划算,但我们不能保证任务1过后的 10的时间里能获利10。
//那么对于这样的问题贪心算法就不再适用了,因为贪心算法要求整个问题的最优解一定由在贪心算法中存在的子问题的最优解
//得来的,通俗的讲,是种追求现利益最大的人,通常被认为目光短浅!
//对于这类问题,常采用另一种类似算法:动态规划。动态规划是一种将问题实例分解为更小的、相似的子问题,并存储子问
//题的解而避免计算重复的子问题,以解决最优化问题的算法策略。将问题分解为相似的子问题的做法和贪心算法是类似的,
//但采用动态规划的全局最优解是:全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解。
//详细内容请参考资料。
//在此,我们假设对上述问题的每个任务都有一个报酬(wage),并简单的假设任务i的wage值为:i % (TOTALTASKS/2)。
//找出在时间段[ timestart, timeend]内使总报酬(wage)最大的任务集,其实上面的贪心算法可以看做是各任务报酬都
//相同的情况。
#define max(a, b) (((a) > (b)) ? (a) : (b))
void IntervalScheduler_DynamicProgramming(task tasks[], int total) //动态规划实现
{
int *optimization = new int[total+1];
int *above = new int[total+1]; //above[i]表示在以按任务结束时间从小到大排序的任务中,在任务i-1开始之前
//就已经结束的离任务i-1最近的任务,而above[0]为0,表示前面的以无任务,这样
//表示是为了,实现使算法更容易实现,所以可能有些难以理解
int i, j;
QuickSort_End(tasks, 0, total-1); //以任务的结束时间从小到大排序
above[0] = 0; //计算各个任务的above值
for (i=1; i<=total; i++){
for (j = i-1; j>=1 && tasks[i-1].timestart < tasks[j-1].timeend; j--);
if (j < 1)
above[i] = 0;
else
above[i] = j;
}
//动态规划的主要思路,这里的解法是:OPT(i) = MAX{ OPT(i-1), OPT(above[i])+tasks[i].wage };
//但这个任务属于最优解里时就有,OPT(i) = OPT(above[i])+tasks[i].wage;不属于最优解里是:
//OPT(i) = OPT(i-1)。这就是这要思路,很浅显,如果用递归的话很容易实现,主要是效率问题,
//动态规划就是避免递归的重复求值!
//和上面的above[i]一样,为了更简单的实现,optimization[i]为任务0...i-1的最优解,optimization[0]=0
//用来表示结束,这里的下标0 不表示任务0,而表示任务-1,没有任务-1,所以没意义!
optimization[0] = 0;
for (i=1; i<=total; i++)
optimization[i] = max(optimization[i-1], optimization[above[i]] + tasks[i-1].wage);
// 运用“反向追踪法”追踪动态规划生成的中间过程,以反向的序列输出,由动态规划生成的结果,一般都可以
//采用这种方式追踪中间的过程!~!~
cout << endl << "反向追踪法探查生成结果" << endl;
for (i = total; i>0; )
if (optimization[i] == optimization[i-1]){
i--;
}else{
cout <<"任务标志:" << tasks[i-1].tasksign <<" 任务开始时间:" << tasks[i-1].timestart
<< " 任务结束时间:" << tasks[i-1].timeend << " 报酬: " << tasks[i-1].wage << endl;
i = above[i];
}
}
//关于这个问题就讨论到这里了,也许你对动态规划带权区间调度还是不甚了解,那你还等什么,看书去吧!了解下可以
//用动态规划解决的问题,如典型的背包问题,Bellman-Ford最短路径算法,序列比对等!

转载于:https://www.cnblogs.com/demote/archive/2011/12/01/2509104.html

区间调度问题(最大利润作业调度问题)相关推荐

  1. 批处理作业调度问题 ——回溯法详解

    1.问题描述 每一个作业Ji都有两项任务分别在2台机器上完成.每个作业必须先有机器1处理,然后再由机器2处理.作业Ji需要机器j的处理时间为tji.对于一个确定的作业调度,设Fji是作业i在机器j上完 ...

  2. 【老生谈算法】MATLAB实现车间作业调度问题(JSP)遗传算法通用源码——JSP

    MATLAB实现车间作业调度问题(JSP)遗传算法通用源代码 1.原文下载: 本算法原文如下,有需要的朋友可以点击进行下载 序号 原文(点击下载) 本项目原文 [老生谈算法]车间作业调度问题(JSP) ...

  3. 回溯法解决批处理作业调度问题

    唉,这是作为一个失败的开端.但是,我不害怕失败的!今天稍微晚点睡觉,因为中午多睡啦~最近被王晓东老师的<计算机算法设计与分析>(第4版)折磨得够呛.不会说些文雅的话,这的确是事实.基础差, ...

  4. 回溯算法批处理作业调度问题

    1.问题描述 给定n个作业的集合J={j1,j2,j3,-jn},每一个作业都有两项任务分别在两台机器上完成.每个作业必须先由机器1处理,再由机器2处理.作业Ji需要机器j的处理时间为tij,设Fij ...

  5. 泊位调度问题 matlab,流水线车间调度问题matlab源程序.doc

    流水线车间调度问题matlab源程序 流水线车间调度问题matlab源程序 流水线型车间作业调度问题遗传算法Matlab源码 流水线型车间作业调度问题可以描述如下:n个任务在流水线上进行m个阶段的加工 ...

  6. 基础算法 —— 调度问题 —— 多机并行调度问题

    [概述] 多机调度问题可表达为:n 个工件由 k 个可并行工作的机器加工,完成任务 i 需要的时间为 ti,调度目标是确定这 n 个工件完成的最佳加工顺序,使得完成全部任务的时间最早,其可利用 回溯法 ...

  7. 作业调度问题java代码_Tabu Search求解作业车间调度问题(Job Shop Scheduling)-附Java代码...

    本文来源于公众号[程序猿声],作者舟寒丶 作业车间调度问题 问题模型 举个栗子 有关禁忌搜索算法的内容,公众号内有详细教程: 大家可以点击超链接回顾相关知识,这里就不再细说了. 一般而言,用禁忌搜索算 ...

  8. 分枝限界法求解流水线作业调度问题

    问题描述 有n个作业(编号为1-n)要在由两台机器M1和M2组成的流水线上完成加工.每个作业加工的顺序都是先在M1上加工,然后在M2上加工.M1和M2加工作业i所需的时间分别为ai和bi(1≤i≤n) ...

  9. 【调度】经典作业车间调度问题VS柔性作业车间调度问题

    经典作业车间调度问题 在传统车间调度模型中,假设工序加工所需要的资源是不具备柔性的资源,工件的所有工序的加工机器是唯一的,且机器顺序是已知的,则可通过确定工序在每台机器上的加工顺序来优化完工时间等系统 ...

  10. 实验4 贪心法(作业调度问题)

    1.问题的已知 设有n个独立的作业{1, 2, -, n},由m台相同的机器{M1, M2, -, Mm}进行加工处理,作业i所需的处理时间为ti(1≤i≤n),每个作业均可在任何一台机器上加工处理, ...

最新文章

  1. VC/MFC Tips
  2. 输出可爱的”杨辉三角”
  3. net项目总结一(1)
  4. 怎么自学python自动化测试-学习自动化测试,如何学习Python语言?
  5. IntelliJ IDEA 配置文件位置
  6. JVM虚拟机-Class文件之字段表集合
  7. Python程序:输出斐波那契数列
  8. jmeter 控制偏离_Jmeter(二十) - 从入门到精通 - JMeter监听器 -下篇(详解教程)
  9. Java多线程——同步容器类
  10. Matlab安装minGW
  11. python填充三角形颜色怎么输入_用Python填充三角形(海龟)
  12. 阿里云用域名、ip访问不了网站
  13. 大数据培训就业班毕业后通常可以从事哪些领域做哪些方面工作
  14. ListView的增删改查(实战)
  15. Ubuntu 设置合上笔记本盖子休眠的方法
  16. 快速解决Ubuntu缺少各种驱动的方法: 解决ThinkPad T14s没有无线网卡驱动以及WIFI无法连接等驱动问题
  17. 干货!手把手教你穿透内网
  18. mm7 彩信发送方法
  19. ELK浅入浅出之环境搭建
  20. 【JavaScript详解】JavaScript语言的特性以及DOM操作和表单操作

热门文章

  1. day05匿名函数,内置函数,二分法,递归,模块
  2. CS5213 HDMI转VGA带音频DAC输出|HDMI to VGA withDAC转换
  3. selenium和requests实现12306登录及余票查询
  4. [Delphi] Search path vs Library Path vs Browsing Path
  5. android 多个按键精灵,Android 一种通用的按键精灵的实现思路
  6. Cannot connenct to relay host smtp.163.com (php邮件发送失败)
  7. 【Lintcode】1132. Valid Triangle Number
  8. client中周期性边界_周期性边界条件
  9. Java程序员月薪30K和月薪3K差别在哪?
  10. 联想android怎么解密,联想G886手机如何解密