回溯法实现最佳调度问题(Java)
回溯法实现最佳调度问题的网上解答有很多,但基本上都是C或C++实现的,而且基本上只是粘了个代码而没有详细解释,因此我写了这篇文章,如有不对的地方,欢迎指正。
####问题描述
最佳调度问题的回溯算法实现:有n个任务由k个可并行工作的机器完成。完成任务i需要的时间为Ti。找出完成这n个任务的最佳调度,使得完成全部任务的时间最少。用文件导入每个任务所需要的时间Ti。(至少10个任务)使用回溯算法的思想,设计一个解决该问题的算法。设计一个输出界面,输出调度方案。
####算法思想
回溯法是从初始状态出发,在隐式图中以深度优先的方式搜索问题的解。当发现不满足求解条件时就回溯,尝试其他路径,即“能进则进,进不了则换,换不了则退”的基本搜索方法。
####算法设计
①问题解的形式:最佳调度算法的解表示成n元组的形式(X1,X2,…,Xn),其中Xi(i=1,2…,n)表示第i个任务放在第Xi个机器上处理。
②显约束: 当前容器处理时间与新加入该容器任务比最少时间短。
③隐约束:当前时间比最少时间短。
④解空间:根据显约束第i个任务有k个机器可以选择,显然满足显约束的n元组共有kn种,他们构成了最佳调度问题的解空间。
####变量说明
a:默认3行50列的二维整型数组,用于存放调度任务的信息,第1行为任务编号,第2行为任务所需时间,第3行为调度结果;
s:默认长度为50的一维整型数组,表示当前机器需要工作的时间;
nbest:默认长度为50的一维整型数组,表示当前调度结果;
n:整数,表示任务数;
k:整数,表示机器数;
minn:整数,表示调度后的最少时间;
####核心代码
public void search(int x,int y){
//最佳调度算法
if(y>minn) //隐约束剪枝
return;
if(x>n){ //到达叶结点
if(y<minn){ //判断最优解,更新最优解和最优值
minn = y;
for(int i=1;i<=n;i++){
a[2][i] = nbest[i];
}
}
return;
}
for(int i=1;i<=k;i++){
if(s[i]+a[1][x]<minn){ //显约束剪枝
s[i] += a[1][x];
nbest[x]=i;
search(x+1,max(y,s[i])); //递归
s[i] -= a[1][x];
}
}
return;
}
####运行结果
我的完整项目是设计了界面的。
####时间复杂度
时间复杂度为O(nkn)
完整工程下载地址最佳调度问题回溯法实现-Java