回溯法--批处理作业调度
问题描述
给定n个作业的集合{J1,J2,…,Jn}。每个作业必须先由机器1处理,然后由机器2处理。
作业Ji需要机器j的处理时间为tji(i=1,2,...,n; j=1,2)。
对于一个确定的作业调度,设Fji是作业i在机器j上完成处理的时间。
所有作业在机器2上完成处理的时间和称为该作业调度的完成时间和。
批处理作业调度问题要求对于给定的n个作业,制定最佳作业调度方案,使其完成时间和达到最小。
解决思路
- 请直接看代码,每次循环i到n的作业
代码实现
/*
3
2 1
3 1
2 3
18
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 55, INF = 0x3f3f3f3f;
int m[N][3]; // 各作业所需的处理时间
int x[N]; // 当前作业调度
int bestx[N]; // 当前最优作业调度
int f2[N]; // 机器2完成处理时间
int f1; // 机器1完成处理时间
int f; // 完成时间和
int bestf = INF; // 当前最优值
int n; // 作业数
void Backtrack(int i)
{
if(i > n) // 找到最优解
{
for(int j = 1; j <= n; j ++ )
bestx[j] = x[j];
bestf = f;
return;
}
for(int j = i; j <= n; j ++ )
{
f1 += m[x[j]][1];
//int tempf = f2[i];
f2[i] = ((f2[i - 1] > f1) ? f2[i - 1] : f1) + m[x[j]][2];
f += f2[i];
if(f < bestf) //剪枝,剪去当前使用时间大于besf的枝
{
swap(x[i], x[j]);
Backtrack(i + 1);
swap(x[i], x[j]);
}
f1 -= m[x[j]][1];
f -= f2[i];
//f2[i]=tempf;
}
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i ++ )
for(int j = 1; j <= 2; j ++ )
cin >> m[i][j];
for(int i = 1; i <= n; i ++ )
{
x[i] = i; //记录当前调度
}
Backtrack(1);
cout << "调度作业顺序:" << endl;
for(int i = 1; i <= n; i ++ )
cout << bestx[i] << " ";
cout << endl;
cout << "处理时间:" << endl;
cout << bestf << endl;
return 0;
}