昨天在试图入睡时,我开始考虑如何解决下面的问题并意识到我无法想出一个好的算法。这不是学校作业,即使它看起来像一个,我只是想找到答案。 :)
基本上让我们想象一下商店员工的工作安排。该计划应根据一系列要求生成计划建议。
要求是:
攻击此问题的最佳方法是什么?也许函数式编程更适合解决这个问题?
编辑:现在我知道这类问题被称为“资源约束调度”。由于“调度”通常指的是诸如计划任务或线程之类的事情,因此对此有点困难。对于那些仍然认为我要求提供家庭作业解决方案的人(尽管我明确地声称上面提到了其他问题),你可以查看我以前的问题,我认为他们清楚地表明我不是学生......
答案 0 :(得分:5)
前两点是问题的约束。 第三点表示对候选解决方案进行排序的方法,如果您将其正式化,则会出现优化问题。实际上,您正在尝试最小化工作分布的差异。
请注意,由于约束,问题可能没有可接受的解决方案。
这是一个组合优化问题,您可以使用整数线性规划方法或大致使用随机局部搜索方法(它们也称为元启发式或许多其他名称)来解决它,例如遗传算法,模拟退火,禁忌搜索,迭代局部搜索,蚁群优化等。
这类特殊问题被称为作业调度,有很多关于它的文献有很多变种。
如果这不是作业,我认为这应该足以满足你的好奇心,如果我认为我告诉你你可以看到什么。
答案 1 :(得分:2)
即使看起来好像这是家庭作业,我也更愿意相信你。
以下是我的想法:
let rec assignWork n upTo last workers =
if n <= upTo then
let checkNameIsEqualToLast =
match last with
| Some n -> ((=) n)
| _ -> fun _ -> false
let (name, _, _) as worker =
workers
|> List.filter (not << fun (name, _, v) -> checkNameIsEqualToLast name || List.exists ((=) n) v)
|> List.sortBy (fun (_, w, _) -> w)
|> List.head
workers
|> List.map (function
| n, w, v when n = name -> n, w + 1, v
| w -> w)
|> assignWork (n + 1) upTo (Some name)
|> fun t -> name::t
else []
例如:
let workers =
List.zip
[ 'A' .. 'E' ]
[
[]
[ 2 .. 4 ]
[ 3 .. 5 ]
[ 1 .. 10000 ]
[ 3 ]
]
|> List.map (fun (c, v) -> c, 0, v)
assignWork 1 16 None workers
输出(对我来说似乎合理):
val it : char list =
['A'; 'C'; 'A'; 'E'; 'B'; 'C'; 'B'; 'E'; 'A'; 'B'; 'C'; 'E'; 'A'; 'B'; 'C'; 'E']