如何从clpfd使用tuple_in?

时间:2015-09-18 12:36:06

标签: prolog swi-prolog clpfd

我正在关注clpfd练习: http://www.pathwayslms.com/swipltuts/clpfd/clpfd.html

我有以下解决方案,例如5号1

trains([[1,2,0,1], % from station, to station, departs at, arrives at
       [2,3,4,5],
       [2,3,0,1],
       [3,4,5,6],
       [3,4,2,3],
       [3,4,8,9]]).

threepath(A, D, Ps) :-
    Ps = [[A,B,_T0,T1],[B,C,T2,T3],[C,D,T4,_T5]],
    T2 #> T1,
    T4 #> T3,
    trains(Ts),
    tuples_in(Ps, Ts).


allpaths(From,To,Route):-
  trains(Ts),
  length(Ts,Max_Trains),
  between(2,Max_Trains,Length_Of_Route),
  Route=[_,_|_],length(Route,Length_Of_Route),
  maplist(same_length([_,_,_,_]),Route),
  create_chain(Route,TimeChain,1),
  train_chain(Route),
  chain(TimeChain, #<),
  tuples_in(Route,Ts),
  nth1(1,Route,[From|_]),
  nth1(Length_Of_Route,Route,[_,To|_]).

create_chain([],[],_).
create_chain(List_of_Lists,[First,Second|Chain],1):-
  List_of_Lists =[Item|T],
  Item =[_T1,_T2,First,Second],
  create_chain(T,Chain,2).
create_chain(List_of_Lists,[First,Second|Chain],2):-
  List_of_Lists =[Item|T],
  Item =[_T1,_T2,First,Second],
  create_chain(T,Chain,1).

train_chain([_]).
train_chain(List_Of_Lists):-
  List_Of_Lists =[First,Second|T],
  First = [_One,Two,_,_],
  Second =[Two,_Three,_,_],
  train_chain([Second|T]).

我不确定我是否已经在&#39;打算&#39;方式,但它的工作,似乎没关系。我基本上创建了跨列车的变量列表,然后应用约束。我不确定我是否已经在&#39;打算&#39;因为我只使用clpfd作为火车的时间而不是火车。

现在,与员工进行下一次练习时,与火车练习不同,制约因素是个别员工,而不是员工 在这种情况下,我不明白如何使用tuples_in,用findall完成练习似乎很简单。如何使用约束和tuples_in实现它有什么优势?

employees([
 [1, 75, 0, 30, 25],
 [2, 83, 0, 45, 25],
 [3, 90, 1, 45, 50],
 [4, 45, 3, 75, 25],
 [5, 89, 0, 52, 50]
 ]).

promotions(Es,Promotions):-
  employees(Es),
  findall([Id,Score,V,T,RT],
    (member([Id,Score,V,T,RT],Es),Score>80,V=<1,T>RT),
  Promotions).

2 个答案:

答案 0 :(得分:1)

我认为应该像

一样简单
ex2(EmployeeId) :-
 employees(Es),
 tuples_in([[EmployeeId, LastReviewScore, NumOfSafetyViolations, TimeInGrade, RequiredTimeForPromotion]], Es),
 LastReviewScore #> 80, NumOfSafetyViolations #=< 1, TimeInGrade #> RequiredTimeForPromotion,
 label([EmployeeId]).

优点是,用于识别候选人的之间的关系可以在未知的情况下保留,直到知道该问题。

这个简单的例子并没有显示出这样的优势......我发现tuple_in有用的解决填字游戏,它可以大大缩短解决时间。

答案 1 :(得分:1)

很高兴我终于可以在StackOverflow上回答一些问题。这是我对第一个问题的解决方案。我使用的是Accumulator模式,您可以在chaper 6 of LearnPrologNow上找到它们,这里也有友好的幻灯片,请直接转到第6章:slides

首先,我调用一个辅助谓词,该谓词重载了相同的名称,但带有4个参数,第三个是我到达../Libio/obj/lib%.a ../Libprotocol/obj/lib%.a ../Libutil/obj/lib%.a``` I've read the GNU Make reference manual, and I don't see any mention or examples of using % twice in one statement. I don't even know if it is possible. Any help would be greatly appreciated. 的时间。对于初始化,该数字为-1。

From

然后我对findpath / 4进行递归,

findpath(From, To, Path) :- findpath(From, To, -1, Path).

但是与您一样,我不确定这是否能最好地利用clpfd。我为% base case: from X1 to Xn there is direct train findpath(X1, Xn, Time, [[X1, Xn, T0, T1]]) :- trains(Ts), T0 #> Time, tuples_in([[X1, Xn, T0, T1]], Ts). % go to a midpoint X2, leave X2 -> Xn to recursion findpath(X1, Xn, Time, [P|Ps]) :- trains(Ts), P = [X1, X2, T0, T1], T0 #> Time, tuples_in([P], Ts), findpath(X2, Xn, T1, Ps). 的每个元素调用tuples_in/2,但我怀疑这是否超出了必要。