一、问题描述
假设有n个任务由k个可并行工作的机器完成。完成任务i需要的时间为ti。试设计一个算法找出完成这n个任务的最佳调度,使得完成全部任务的时间最早。
数据输入: 由文件input.txt给出输入数据。第1行有2个正整数n和k。第2行的n个正整数是完成n个任务需要的时间。
结果输出: 将计算的完成全部任务的最早时间输出到文件output.txt。
二、分析
先假设3个time值,分别代表三个机器的工作时间。然后我们知道所有的事件都必须完成,所以一个事件只有3种状态,要么在机器1中,要么在机器2中,要么在机器3中。因此我们分别对这三种情况进行判断,判断是否入列。
在input.txt文本第一行输入总任务个数和工作的机器数。
三、运行结果
运行程序,打开output.txt文本可知完成全部任务的最早时间。
四、代码
#include <iostream>
#include <queue>
#include<fstream>
#include <algorithm>
using namespace std;
const int M = 100;
const int INF = 0x3f3f3f3f;
int x[M], n, k;
int best = INF; //最佳值
struct node //定义一个node
{
int time[M]; //当前的time
int num; //当前的位置
int tt; //当前的最大值
bool operator<(const node& a)const {//重载运算符,实现优先队列从小到大排列
return tt > a.tt;
}
}point; //当前点
int p_queue() {
priority_queue<node> q;
for (int i = 1; i <= k; i++) { //初始化
point.time[i] = 0;
}
point.num = 0;
point.tt = 0;
while (point.tt < best) { //不符合退出循环
if (point.num == n) {
best = point.tt; //达到最后一点给best赋值
}
else {
for (int i = 1; i <= k; i++) {
node next; //定义中间变量并赋值
next.num = point.num + 1;
for (int m = 1; m <= k; m++) {
next.time[m] = point.time[m];
}
next.time[i] += x[next.num];
next.tt = max(next.time[i], point.tt);
if (next.tt < best) { //剪枝
q.push(next);
}
}
}
if (q.empty()) { //队列无值退出循环
return best;
}
else { //取队列中第一个值进入下一步循环
point = q.top();
q.pop();
}
}
return best;
}
int main() {
ifstream fcin;
fcin.open("input.txt");
fcin >> n >> k; //输入
for (int i = 1; i <= n; i++) {
fcin >> x[i];
}
fcin.close();
ofstream fcout;
fcout.open("output.txt");
fcout << p_queue(); //输出
fcout.close();
}