最佳调度问题:假设有n个任务由k个可并行工作的机器完成。完成任务i需要的时间为ti,i=1~n。试设计一个优先队列式分支限界法,计算完成这n个任务的最佳调度,使得完成全部任务的时间最早。例如,7个任务的完成时间分别为2、14、4、16、6、5、3,交给3个机器完成,则最早完成时间为17。请给出c++代码
时间: 2024-03-20 12:38:47 浏览: 169
好的,以下是使用C++实现的最佳调度问题的优先队列式分支限界算法:
```cpp
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
struct Schedule {
vector<int> tasks; // 已经完成的任务列表
vector<int> machines; // 每个机器的完成时间
int finish_time; // 完成全部任务的时间
};
struct CompareSchedule {
bool operator()(const Schedule& s1, const Schedule& s2) const {
return s1.finish_time > s2.finish_time; // 按完成时间从小到大排序
}
};
int BestSchedule(vector<int>& tasks, int k) {
sort(tasks.begin(), tasks.end(), greater<int>()); // 将任务按完成时间从大到小排序
priority_queue<Schedule, vector<Schedule>, CompareSchedule> q;
Schedule initial;
initial.finish_time = 0;
initial.machines.resize(k, 0);
q.push(initial);
int best_finish_time = INT_MAX;
while (!q.empty()) {
Schedule cur = q.top();
q.pop();
if (cur.finish_time >= best_finish_time) {
break; // 剪枝
}
if (cur.tasks.size() == tasks.size()) {
best_finish_time = cur.finish_time;
continue;
}
int task = tasks[cur.tasks.size()];
for (int i = 0; i < k; i++) {
Schedule next = cur;
next.tasks.push_back(task);
next.machines[i] += task;
next.finish_time = *max_element(next.machines.begin(), next.machines.end());
if (next.finish_time < best_finish_time) {
q.push(next);
} else {
break; // 剪枝
}
}
}
return best_finish_time;
}
int main() {
vector<int> tasks = {2, 14, 4, 16, 6, 5, 3};
int k = 3;
int best_finish_time = BestSchedule(tasks, k);
cout << "Best finish time: " << best_finish_time << endl; // 输出最优解
return 0;
}
```
这段代码中,我们使用了一个结构体`Schedule`来表示一个调度方案,其中`tasks`保存已经完成的任务列表,`machines`保存每个机器的完成时间,`finish_time`保存完成全部任务的时间。我们还定义了一个比较器`CompareSchedule`,用于在优先队列中按完成时间从小到大排序。
在`BestSchedule`函数中,我们首先将任务按完成时间从大到小排序,然后初始化一个空的调度方案`initial`,将其加入优先队列中。我们使用变量`best_finish_time`来保存当前的最优解,初始值为无穷大。然后开始循环,每次从优先队列中取出一个调度方案进行扩展,如果扩展出的子节点的完成时间比当前最优解要大,就可以剪枝,不需要继续扩展这个子节点。如果扩展出的子节点完成了全部任务,就更新最优解。否则,枚举下一个任务分配给哪台机器完成,并计算出新的完成时间,然后将这个子节点加入优先队列中。
最后,输出最优解即可。
阅读全文