如果元素都是整数(即没有变量也没有浮点值),我相信这可以正常工作:
maximin(Elements, N, Maximin, LDistribution):-
sumlist(Elements, Sum),
TargetMaximin is -Sum//N,
once(
(
between(TargetMaximin, -1, NMaximin),
Maximin is -NMaximin,
distribute(Elements, [], n, Maximin, N, 0, [], LDistributionOnce)
)),
LDistribution=LDistributionOnce.
distribute([], [], _, _, 0, _, _, []).
distribute(Elements, Skipped, y, Maximin, N, Cur, Distribution, [Distribution|LDistribution]):-
N>0,
Cur >= Maximin,
succ(N1, N),
append(Elements, Skipped, NElements),
distribute(NElements, [], n, Maximin, N1, 0, [], LDistribution).
distribute([Element|Elements], Skipped, _, Maximin, N, Cur, Distribution, LDistribution):-
N>0,
NCur is Cur+Element,
distribute(Elements, Skipped, y, Maximin, N, NCur, [Element|Distribution], LDistribution).
distribute([Element|Elements], Skipped, _, Maximin, N, Cur, Distribution, LDistribution):-
N>0,
distribute(Elements, [Element|Skipped], n, Maximin, N, Cur, Distribution, LDistribution).
该算法的思想是从最大目标最小值(元素总和除以玩家数量的整数除法)开始,并尝试将元素放入 N 个槽中,其中每个槽的总和至少为目标最小值。
如果找到这样的分布,那么就完成了,否则将目标最小值递减 1 并重复。
这里的算法还给出了它找到的唯一一个分布。
样本运行:
?- maximin([11,17,19],3,Maximin, LDist).
Maximin = 11,
LDist = [[11], [17], [19]].
?- maximin([5,7,1,3,3,7,4,3,8,2,5,1],3,Maximin, LDist).
Maximin = 16,
LDist = [[3, 1, 7, 5], [3, 4, 7, 3], [1, 5, 2, 8]].