贪心算法之多机调度问题

问题描述:

设有 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;
}

运行结果

当只有三台机器时:
三机器作业调度情况
四机器作业调度情况

  • 8
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nepu_bin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值