一、问题描述
设有n个任务由k个可并行工作的机器来完成,完成任务i需要时间为 。试设计一个算法找出完成这n个任务的最佳调度,使完成全部任务的时间最早。(要求给出调度方案)
二、算法设计与分析
1、算法核心思想
排列树回溯法+剪枝
2、解空间的表示
一个深度为N的K叉排列树。
3、基本思路
① 搜索从开始结点(根结点)出发,以DFS搜索整个解空间。每搜索完一条路径则记录下bestTime 和best_N_to_K []序列(用于构造最优解)。
② 开始结点就成为一个活结点,同时也成为当前的扩展结点。在当前的扩展结点处向纵深方向移至一个新结点,并成为一个新的活结点,也成为当前扩展结点。如果在当前的扩展结点处不能再向纵深方向扩展,则当前扩展结点就成为死结点。
③ 此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点;直至找到一个解或全部解。
三、结果与分析
(一)本实验的测试用例可通过系统调用随机函数随机生成。
输入:
N:任务数
K:机器数
输出:
1、原始任务时间对应表;
2、针对每个任务的最佳调度序列;
3、每台机器对应完成的任务。
(二)实验结果截图如下图-3:
A、情况一:任务数大于等于机器数,即N>=K,结果如下图-1,每个机器都分配有任务
图-5 N>=K,每个机器都分配有任务
图-6 N< K,有未分配任务的机器
四、实验结论
1、 实验结果验证本算法可得到最优解:当任务数大于等于机器数,即N>=K,每个机器都分配有任务,也可能有未分配任务的机器,但不影响最终最优解值,因为最优解值可能有多个,而本实验只取其中一个;但当任务数小于机器数,即N< K,一定有未分配任务的机器。
2、 通过排列树回溯法的计算,可得到最优分配方案,但此问题的叶节点个数接近n!,遍历时间为Ω(n!),呈阶乘级增长,效率不是很高。例如在任务数N=20时,就需等待很长时间才能出结果。
3、 以DFS搜索解空间时,搜索过程中裁剪掉死结点的子树有利于提高搜索效率。本算法的剪枝约束条件为:ScheduleTime()< bestTime。
五、源代码(C++)
#include <iostream>
#include <ctime>