问题描述:给定n个作业的集合{J1,J2,…,Jn}。每个作业必须先由机器1处理,然后由机器2处理。作业Ji需要机器j的处理时间为tji。对于一个确定的作业调度,设Fji是作业i在机器j上完成处理的时间。所有作业在机器2上完成处理的时间和称为该作业调度的完成时间和。
批处理作业调度问题要求对于给定的n个作业,制定最佳作业调度方案,使其完成时间和达到最小。
这3个作业的6种可能的调度方案是1,2,3;1,3,2;2,1,3;2,3,1;3,1,2;3,2,1;它们所相应的完成时间和分别是19,18,20,21,19,19。易见,最佳调度方案是1,3,2,其完成时间和为18。
以1,2,3为例:
作业1在机器1上完成的时间为2,在机器2上完成的时间为3
作业2在机器1上完成的时间为5,在机器2上完成的时间为6
作业3在机器1上完成的时间为7,在机器2上完成的时间为10
3+6+10=19,所以时间和为19。
以1,3,2为例:
作业1在机器1上完成的时间为2,在机器2上完成的时间为3
作业3在机器1上完成的时间为4,在机器2上完成的时间为7
作业2在机器1上完成的时间为7,在机器2上完成的时间为8
3+7+8=18,所以时间和为18。
算法分析:
#include <stdio.h>
int x[100]; //x[100]记录当前调度序号
int bestx[100]; //bestx[100]记录最佳作业调度时的调度序号
int m[100][100]; //m[j][i]表示作业j在第i台机器上的处理时间
int f1=0; //f1记录作业1的时间和
int f2=0; //f2记录作业2的时间和
int cf=0; //cf记录当前在机器2上的完成时间和
int bestf=10000; //bestf记录当前最小完成时间和
int n; //作业数量
// 交换x[t]和x[j]的调度序号
void swap(int *x,int t,int j){
int temp = x[t];
x[t] = x[j];
x[j] = temp;
}
void Backtrack(int t)
{
int tempf,j,i;
if(t>n) //到达叶子结点,搜索到最底部
{
for(i=1; i<=n; i++)
bestx[i]=x[i];
if(cf<bestf){
bestf=cf;
}
return;
}
else //非叶子结点
{
for(j=t; j<=n; j++)
{
f1+=m[x[j]][1]; //记录作业在第一台机器上的完成处理时间
tempf=f2;//保存上一个作业在机器2的完成处理时间
f2=(f1>f2?f1:f2)+m[x[j]][2];//保存当前作业在机器2的完成时间
cf+=f2; //cf记录当前在机器2上的完成时间和
if(cf<bestf)
{
swap(x,t,j); //交换两个作业序号的位置
Backtrack(t+1);
swap(x,t,j);
}
f1-=m[x[j]][1];
cf-=f2;
f2=tempf;
}
}
}
int main()
{
int i,j;
printf("请输入作业数量\n");
scanf("%d",&n);
printf("请输入在各机器上的处理时间\n");
for(i=1; i<=2; i++)
for(j=1; j<=n; j++)
scanf("%d",&m[j][i]);
for(i=1; i<=n; i++)
x[i]=i; //记录当前调度
Backtrack(1);
printf("调度作业顺序\n");
for(i=1; i<=n; i++)
printf("%d\t",bestx[i]);
printf("\n");
printf("处理时间:\n");
printf("%d\n",bestf);
return 0;
}
算法的时间复杂度为O(n!)