贪心选择--最长处理时间作业优先(n个作业,m台相同机器)
当n<=m时,只要将机器i的[0, ti]时间区间分配给作业i即可,算法只需要O(1)时间。
当n>m时,首先将n个作业依其所需的处理时间从大到小排序。然后依此顺序将作业分配给空闲的处理机。算法所需的计算时间为O(nlogn)。
问题描述
多机调度问题要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。约定,每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理。作业不能拆分成更小的子作业。
贪心策略
这个问题是NP完全问题,到目前为止还没有有效的解法。对于这一类问题,用贪心选择策略有时可以设计出较好的近似算法。采用最长处理时间作业优先的贪心选择策略可以设计出解多机调度问题的较好的近似算法。
当n<=m时,只要将机器i的[0, ti]时间区间分配给作业i即可,算法只需要O(1)时间。
当n>m时,首先将n个作业依其所需的处理时间从大到小排序。然后依此顺序将作业分配给空闲的处理机。算法所需的计算时间为O(nlogn)。
也就是说从剩下的作业中,选择需要处理时间最长的,然后依次选择处理时间次长的,直到所有的作业全部处理完毕,或者机器不能再处理其他作业为止。如果我们每次是将需要处理时间最短的作业分配给空闲的机器,那么可能就会出现其它所有作业都处理完了只剩所需时间最长的作业在处理的情况,这样势必效率较低。
举例
代码:
先按照处理时间长短由大到小排序
最长的m个作业分配给m台机器
寻找最先空闲的机器j
把机器j分配第m+1长时间的作业任务,更新结束时间...依次循环分配
//多机调度问题
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
int speed[10010]; //作业时间
int mintime[101]; //存放添加作业后完成的时间
bool cmp(const int &x, const int &y)
{
return x > y; //比较函数,求较大值
}
int main()
{
int t;
cin >> t;
while (t--)
{
int m, n;
memset(speed, 0, sizeof(speed)); //将函数清空
memset(mintime, 0, sizeof(mintime));
cin >> n >> m;
for (int i = 0; i < n; i++)
{
cin >> speed[i];
}
sort(speed, speed + n, cmp); //对speed数组进行降序排序
for (int i = 0; i < n; ++i)
{
*min_element(mintime, mintime + m) += speed[i]; // m是机器数,依次对m台机器添中最小的加speed
}
cout << *max_element(mintime, mintime + m) << endl; //求mintime数组中的最大值(所有作业都已完成的时间)
}
return 0;
}
/*
input
1
7 3
2 14 4 16 6 5 3
output:
17
*/