贪心算法之多机调度问题
问题描述:
设有 n 个独立的作业{1, 2, 3, … , n}, 由 m 台相同的机器进行加工处理。作业 i 所需时间为 ti。
约定:任何作业可以在任何一台机器上加工处理,但未完工前不允许中断处理,任何作业不能拆分成更小的子作业。要求给出一种作业调度方案,使所给的 n
个作业尽可能短的时间内由 m 台机器加工处理完成。
多机调度问题到目前为止还没有完全有效的解法,对于这类问题,用贪心选择策略有时可以设计出一个比较好的近似算法。
现有7个独立作业 {1, 2, 3, 4, 5, 6, 7}由M1,M2 和 M3机器来加工处理,各作业所需时间分别为 {2, 14, 4, 16, 6, 5, 3}
解题思路
采用最长处理时间作业优先的贪心策略
设 n 为待处理的作业数量,m 为现有机器的数量。
- 当 n <= m 时,机器的数量大于需要处理的作业数目,每台机器最多处理一个作业即可完成任务,完成全部作业所需的时间为 耗时最长的子作业。
- 当 n > m 时,将 n 个作业按照最长处理时间作业优先的贪心策略可以得到较为均匀的一个分配。

实现代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define MACHINENUMS 3//现有机器的数目
void MultiScheduling(vector<vector<int>>& works, vector<vector<pair<int, int>>>& arrange, vector<int>& runTime) {
if (MACHINENUMS >= works.size()) {//机器数目大于等于作业个数时直接分配
for (int i = 0; i < works.size(); i++) {
arrange.push_back({ make_pair(works[i][0],works[i][1]) });
}
return;
}
sort(works.begin(), works.end(),
[](vector<int>& a, vector<int>& b) ->bool {
return a[1] > b[1];
});//按照作业所需时间降序排序
int curMinTime = 0;//当前机器运行时间最小值
int curMinTimeIndex = 0;//最小运行时间的机器编号
for (int i = 0; i < works.size(); ++i) {//分配作业程序
curMinTime = *min_element(runTime.begin(), runTime.end());//获取当前运行时长最短的处理机
for (int j = 0; j < MACHINENUMS; ++j) {
if (runTime[j] == curMinTime) {
curMinTimeIndex = j;
break;
}
}
runTime[curMinTimeIndex] += works[i][1];//每天机器执行作业的时间
arrange[curMinTimeIndex].push_back({ make_pair(works[i][0],works[i][1]) });//第i个作业被分配的情况
}
}
int main() {
vector<vector<int>> works{
{1,2},{2,14},{3,4},{4,16},{5,6},{6,5},{7,3}
};//works数组
vector<vector<pair<int, int>>> arrange(MACHINENUMS);
//记录每台机器全部作业时间
vector<int> runTime(MACHINENUMS, 0);
MultiScheduling(works, arrange, runTime);
for (int i = 0; i < arrange.size(); i++) {
cout << "第" << i + 1 << "台机器安排的作业: " << endl;
for (int j = 0; j < arrange[i].size(); j++) {
cout << arrange[i][j].first << "号作业,时长为 " << arrange[i][j].second << "h" << endl;
}cout << "第" << i + 1 << "台机器总运行时长: " << runTime[i] << "\n" << endl;
}
return 0;
}
运行结果
当只有三台机器时:



浙公网安备 33010602011771号