【发布时间】:2014-03-23 16:32:37
【问题描述】:
我正在尝试解决一个 CSP,我需要将鸡尾酒分发给调酒师,以便每个调酒师最多有一种鸡尾酒,并且所有鸡尾酒都有一个调酒师。我通过创建一个 clpfd 变量列表来解决它,首先给他们所有调酒师的完整域,然后删除所有不知道如何制作鸡尾酒的调酒师。
我的代码有效,但有一个问题:它太慢了。如果我查看分析器,remove_domain 会被调用 2000 次(对于我给程序的输入),而它的重做统计量是 >100 000。
我需要在这些功能之一(或两者)中进行哪些更改,以便 prolog 不需要回溯?
produce_domains(_,_,[],[]) :- !.
produce_domains(Bartenders,NBartenders,[Cocktail|Cocktails],[Var|Vars]) :-
Var in 1..NBartenders,
remove_domain(Bartenders,NBartenders,Cocktail,Var),!,
produce_domains(Bartenders,NBartenders,Cocktails,Vars),!.
remove_domain([],0,_,_) :- !.
remove_domain([Bartender|Bartenders],NBartenders,Cocktail,Var) :-
(\+ member(Cocktail,Bartender) -> Var #\= NBartenders;!),!,
NNBartenders is NBartenders - 1,
remove_domain(Bartenders,NNBartenders,Cocktail,Var),!.
我已经阅读了this related question,但我使用的是最新的 Windows 版本的 SWI-Prolog(5.10.5),所以这不应该是这里的问题。
【问题讨论】:
-
切割不能与 CLP(FD) 很好地混合。而是尝试重新表述您的问题没有成员、\+等...(也许 all_different 会有所帮助)