问题描述:
设有 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 个作业按照最长处理时间作业优先的贪心策略可以得到较为均匀的一个分配。
实现代码:
/**
* @author nepu_bin
* @date 2022/10/6 20:21
* @brief
* [bugfix] 修改机器数目大于作业数量时的处理逻辑
**/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define MACHINE_NUM 4//现有机器的数目
/*
* @brief 计算任务调度
*
* @param works 所有任务
* @param arrange 调度结果
* @param runTime 调度完成后每台机器的工作时长
*/
void MultiScheduling(vector<vector<int>>& works, vector<vector<pair<int, int>>>& arrange, vector<int>& runTime) {
if (MACHINE_NUM >= works.size()) {//机器数目大于等于作业个数时直接分配
for (int i = 0; i < works.size(); i++) {
auto work = make_pair(works[i][0], works[i][1]);
arrange[i].push_back(work);
runTime[i] = works[i][1];
}
return;
}
sort(works.begin(), works.end(),
[](vector<int>& a, vector<int>& b) ->bool {
return a[1] > b[1];
});//按照作业所需时间降序排序
int curMinTimeIndex = 0;//最小运行时间的机器编号
for (int i = 0; i < works.size(); ++i) {//分配作业程序
curMinTimeIndex = min_element(runTime.begin(), runTime.end()) - runTime.begin();
runTime[curMinTimeIndex] += works[i][1];//每天机器执行作业的时间
arrange[curMinTimeIndex].push_back({ make_pair(works[i][0],works[i][1]) });//第i个作业被分配的情况
}
}
/*
* @brief 打印每台机器被调度之后的结果
*/
void Print(vector<vector<pair<int, int>>>& arrange, vector<int>& 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] << endl << endl;
}
}
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(MACHINE_NUM);
//记录每台机器全部作业时间
vector<int> runTime(MACHINE_NUM, 0);
MultiScheduling(works, arrange, runTime);
Print(arrange, runTime);
return 0;
}
运行结果
当只有三台机器时: