问题描述:
每一个作业Ji都有两项任务分别在2台机器上完成。每个作业必须先有机器1处理,然后再由机器2处理。作业Ji需要机器j的处理时间为tji。对于一个确定的作业调度,设Fji是作业i在机器j上完成处理时间。则所有作业在机器2上完成处理时间和f=F2i,称为该作业调度的完成时间和。对于给定的n个作业,指定最佳作业调度方案,使其完成时间和达到最小。
约束条件: 当前时间和小于当前最优解才有可能产生新的最优解,否则直接剪枝,不用再遍历这棵子树。
作业流程: 画个简图加强一下对作业工作流程的理解
排列树
代码
#include <iostream>
#define MAXS 10000;
using namespace std;
int M[100][3]; //各作业所需的处理时间
int x[100]; //当前作业调度
int bestx[100]; //当前最优作业调度
int f2[100]; //机器2完成处理的时间
int f1=0; //机器1完成处理的时间
int f=0; //完成时间和
int bestf=MAXS; //最优值
int n=0; //作业数
void Backtrack(int t)
{
if(t>n)
{
for (int i = 1; i <= n;i++)
bestx[i] = x[i];
bestf = f;
}
else
{
for (int i = t; i <= n;i++)
{
f1 += M[x[i]][1];
f2[t] = (f2[t - 1] > f1 ? f2[t - 1] : f1) + M[x[i]][2];
f += f2[t];
if(f<bestf) //当当前时间和小于当前最优解才有可能产生新的最优解
{
swap(x[t], x[i]);
Backtrack(t + 1);
swap(x[t], x[i]);
}
f -= f2[t];
f1 -= M[x[i]][1];
}
}
}
int main()
{
cout << "请输入作业数目:" << endl;
cin >> n;
cout << "请输入各个作业的工作时间" << endl;
for (int i = 1; i <= n;i++)
{
f2[i] = 0;
x[i] = i;
cin >> M[x[i]][1] >> M[x[i]][2];
}
Backtrack(1);
cout << "最优值为:" << bestf;
cout << "最优解为:";
for (int i = 1; i <= n;i++)
cout << bestx[i]<<" ";
return 0;
}