使用n个任务和m个机器进行作业调度

时间:2017-06-18 14:54:19

标签: java algorithm job-scheduling

问题描述:

我有n个优先约束作业和m个独立计算机。每个作业都分配了成本c(以1时间单位完成作业所需的计算机数量)。完成一项工作需要1时间单位,只有在c机器被分配给它的情况下才能完成工作(工作是原子的,不可能完成一半的工作)

简而言之,有n个工作及其优先约束,m个机器和截止日期d(一定数量的时间单位)。

我的目标:

我想检查是否可以将作业分配给计算机,以便所有作业在d时间单位内完成。如果可以,那么我想打印出一个时间表,为每个作业分配一个时间单位(处理作业的时间单位,见下面的例子)。

示例:

n = 5; // number of jobs
m = 6; // number of machines
d = 4; // deadline (number of time units in which the jobs need to be finished)

Precedences: (read "Job(x,y)<--Job(q,p)" as "job x with cost y needs to be
              finished before job q with cost p can be started")
Job(3,1)<--Job(2,3)<--Job(1,4)
Job(5,3)<--Job(4,3)
Job(6,1)

 The solution: in this case it's possible to assign jobs to machines such that each job
finishes in <=d time units. 
A possible schedule is 1 2 3 3 4 1.

(read schedule as "job 1 and job 6 are done in the first time unit, job 2
is done during the second time unit, jobs 3 and 4 during the third time unit, 
job 5 during the fourth time unit")

我目前的做法:(第二次尝试感谢@Ole V.V。反例)

我想做一个回溯方法(我能提出的最佳方法)。目前我在实施它时遇到了麻烦。

我想存储作业及其优先顺序。然后我确定一个集合A,其中包含可以在当前时间单位内解决的所有作业。然后我找到一个集合B(它包含我考虑在此时间单位内解决的所有作业集),其中包含A的所有子集,这些子集可用有限数量的机器m解决,这样就不能添加其他作业对于每个子集(通过向其中一个子集添加作业,该子集中所有作业的成本超过&#39; m&#39;)。然后我重复这个过程,但没有解决的作业(A \ B),我对B中的每个子集做一个递归调用。当传递的剩余作业集(A \ B)为空(所有作业都已完成)时,我停止如果递归深度为&lt; = d(如果符合截止日期),则返回找到的计划。

@Ole V.V提供的示例中此方法的示例。 :

The steps refer to the depth of recursion, the boxes refer to the jobs (first number is job ID, second is cost in time units. At step 0 I explicitly wrote out the subsets (sets of jobs which I consider solving during this step).

步骤是指递归的深度,方框是指作业(第一个数字是作业ID,第二个是时间单位的成本。在步骤0,我明确地写出了子集(我考虑解决的工作集)这一步)。

现在我的问题是存储作业及其优先级,找到可以在当前时间单位中解决的作业(设置A),找到我认为在当前时间单位中解决的作业子集(集B),并将它们放在一个递归函数中,最终输出找到的时间表或者没有找到时间表&#34;如果没有符合截止日期的时间表。

3 个答案:

答案 0 :(得分:1)

我相信你贪婪的算法并不总能给你正确的结果。

采取:

Job 1 costs 3
Job 2 costs 3
Job 3 costs 1
Job 4 costs 5
Job 5 costs 1

机器数量是7。

优先顺序是

#1 before #5
#2 before #5
#4 before #3 before #5

截止日期是3。

我相信你的算法会选择

Step 1 jobs 1, 2, total cost 6
Step 2 job 4 cost 5
Step 3 job 3 cost 1

现在作业5尚未运行且已达到截止日期。你的程序会说这是不可能的。

可以使用以下时间表

Step 1 job 4 cost 5
Step 2 jobs 1, 2, 3 total cost 7
Step 3 job 5 cost 1

答案 1 :(得分:1)

您正在考虑的问题显然是NP难度,我们可以从partition problem进行减少,如下所示: 想象一下你有整数s1,s2 ......,sn的分区问题。目的是找到这个集合的分区为两个集合S1和S2,使得S1上的和等于S2的总和。

我们可以通过为每个整数(其成本是整数的值)定义作业来将此问题转换为您的问题,并且我们添加一个额外的作业,必须在所有其他作业之后完成。我们设置d = 3

当且仅当问题有解决方案时,我们才能轻松地显示分区问题的解决方案,因此您的问题是NP难的。

答案 2 :(得分:0)

你的方法似乎很好,但我相信有一种更简单的方法。我建议你使用constraint saisfaction方法。有很多方法可以解决您的问题,例如: mixed-integer programmingMaxSAT。您的任务似乎相当简单,并且您确定不会有任何大数字,因此您可以尝试Minizinc。例如,考虑this调度示例。

如果我们讨论特定于Java的工具,请查看Choco solver