因此,这是一个程序,它计算这些硬币上的特定值携带的硬币数量最少。该程序有效,但速度太慢......当您将值的长度替换为7或更小时,它可以工作......但是8或更高,它真的非常慢。有没有办法加快这个计划?
% LIBRARIES NEEDED FOR FUNCTION TO WORK
:- lib(ic).
:- lib(ic_global).
:- lib(branch_and_bound).
questionSix(Values, Coins) :-
init_vars(Values, Coins),
coin_cons(Values, Coins, Pockets),
clever_cons(Values, Coins),
Min #= sum(Coins),
minimize((labeling(Values), labeling(Coins), check(Pockets)), Min).
init_vars(Values, Coins) :-
length(Values, 8),
occurrences(5, Values, 1),
Values :: 1..99,
increasing(Values),
length(Coins, 8),
Coins :: 0..99.
increasing(List) :-
( fromto(List, [This, Next | Rest], [Next | Rest], [_])
do
This #< Next
).
clever_cons(Values, Coins) :-
( fromto(Values, [V1 | NV], NV, []),
fromto(Coins, [N1 | NN], NN, [])
do
( NV = [V2 | _]
-> N1*V1 #< V2;
N1*V1 #< 100
)
).
coin_cons(Values, Coins, Pockets) :-
( for(Price, 1, 99),
foreach(CoinsforPrice, Pockets),
param(Coins, Values)
do
price_cons(Price, Coins, Values, CoinsforPrice)
).
price_cons(Price, Coins, Values, CoinsforPrice) :-
( foreach(V, Values), foreach(C, CoinsforPrice), foreach(Coin, Coins),
foreach(Prod, ProdList)
do
Prod = V*C,
0 #=< C,
C #=< Coin
),
Price #= sum(ProdList).
check(Pockets) :-
( foreach(CoinsforPrice, Pockets)
do
once(labeling(CoinsforPrice))
).
任何帮助表示赞赏!谢谢!
答案 0 :(得分:1)
首先观察:如果你将labeling(Coins)
放在labeling(Values)
之前,那么时间就会大大改善。粗略地说,这是因为在这个问题中,硬币的数量比硬币的价值要重要得多。
第二个观察结果:无论您允许多少值,您都不能获得少于7个硬币。这是因为如果您使用7个值运行程序,您可以看到每个硬币在最佳解决方案中使用过一次。因此,如果您有超过7个值,将只使用其中的7个,或者硬币数量将超过7个,并且解决方案将不是最佳的。
记住这些观察结果,你可以改变
minimize((labeling(Values), labeling(Coins), check(Pockets)), Min).
到
bb_min((labeling(Coins), labeling(Values), check(Pockets)), Min, bb_options{from:7}).