如何使用 clpfd 中的 tuple_in?
How to use tuple_in from 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]).
我不确定我是否以 'intended' 的方式完成了此操作,但它确实有效并且看起来还不错。我基本上创建了跨列车的变量列表,然后将约束应用于。我不确定我是否以 'intended' 方式完成此操作,因为我只在火车时间而不是火车时间使用 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).
我觉得应该很简单
ex2(EmployeeId) :-
employees(Es),
tuples_in([[EmployeeId, LastReviewScore, NumOfSafetyViolations, TimeInGrade, RequiredTimeForPromotion]], Es),
LastReviewScore #> 80, NumOfSafetyViolations #=< 1, TimeInGrade #> RequiredTimeForPromotion,
label([EmployeeId]).
优点是,在了解有关该问题的一些有趣信息之前,可以不指定用于识别候选人的 值 之间的关系。
这个简单的例子并没有显示出这样的优势...我发现 tuple_in 解决填字游戏很有用,它可以大大缩短解决时间。
很高兴终于可以在 Whosebug 上回答问题了。这是我对第一个问题的解决方案。我正在使用累加器模式,您可以在 chaper 6 of LearnPrologNow, they also have friendly slides here, just go for chapter 6: slides
上找到它
首先我调用了一个辅助谓词,它重载了相同的名称但有 4 个参数,第三个是我到达 From
的时间。对于初始化,此数字为 -1。
findpath(From, To, Path) :- findpath(From, To, -1, Path).
然后我对 findpath/4、
进行递归
% 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).
但你也一样,我不确定这样是否充分利用了clpfd。我为 Ps
的每个元素调用 tuples_in/2
,我怀疑这是否必要。
我在这里跟随 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]).
我不确定我是否以 'intended' 的方式完成了此操作,但它确实有效并且看起来还不错。我基本上创建了跨列车的变量列表,然后将约束应用于。我不确定我是否以 'intended' 方式完成此操作,因为我只在火车时间而不是火车时间使用 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).
我觉得应该很简单
ex2(EmployeeId) :-
employees(Es),
tuples_in([[EmployeeId, LastReviewScore, NumOfSafetyViolations, TimeInGrade, RequiredTimeForPromotion]], Es),
LastReviewScore #> 80, NumOfSafetyViolations #=< 1, TimeInGrade #> RequiredTimeForPromotion,
label([EmployeeId]).
优点是,在了解有关该问题的一些有趣信息之前,可以不指定用于识别候选人的 值 之间的关系。
这个简单的例子并没有显示出这样的优势...我发现 tuple_in 解决填字游戏很有用,它可以大大缩短解决时间。
很高兴终于可以在 Whosebug 上回答问题了。这是我对第一个问题的解决方案。我正在使用累加器模式,您可以在 chaper 6 of LearnPrologNow, they also have friendly slides here, just go for chapter 6: slides
上找到它首先我调用了一个辅助谓词,它重载了相同的名称但有 4 个参数,第三个是我到达 From
的时间。对于初始化,此数字为 -1。
findpath(From, To, Path) :- findpath(From, To, -1, Path).
然后我对 findpath/4、
进行递归% 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).
但你也一样,我不确定这样是否充分利用了clpfd。我为 Ps
的每个元素调用 tuples_in/2
,我怀疑这是否必要。