Prolog循环赛安排主客场

Prolog循环赛安排主客场,prolog,Prolog,我目前正试图在Prolog中编制一个循环赛时间表,并已设法让所有球队相互比赛一次,我现在希望对其进行编程,使所有球队在主场和客场都相互比赛两次,例如[1,2]和[2,1]。我目前掌握的守则如下: %table of allocated matches :- dynamic(match_table/2). %get all teams from 1 .. NumTeams forTeams(T, T, X) :- T =< X. forTeams(I, T, X) :- T

我目前正试图在Prolog中编制一个循环赛时间表,并已设法让所有球队相互比赛一次,我现在希望对其进行编程,使所有球队在主场和客场都相互比赛两次,例如[1,2]和[2,1]。我目前掌握的守则如下:

%table of allocated matches
:- dynamic(match_table/2).

%get all teams from 1 .. NumTeams
forTeams(T, T, X) :-
    T =< X.
forTeams(I, T, X) :-
    T < X,
    T1 is T + 1,
    forTeams(I, T1, X).

%teams represented by integers more than 1
check_num_input(T) :-
    integer(T),
    T > 1.

%resets the allocation table of matches
reset_allocations :-
    retractall(match_table(_, _)).

%check the match has not already been allocated
%empty list for once recursion is complete
check_not_allocated(_, []).
%recursively search through allocation list to see if team is allocated
check_not_allocated(T, [X | CurrentMatchesTail]) :-
    \+ match_table(T, X),
    \+ match_table(X, T),
    check_not_allocated(T, CurrentMatchesTail).

%recursively fetch match allocation
get_match_allocation(_, 0, CurrentMatches, CurrentMatches).
get_match_allocation(NumTeams, RemainingNumTeamsPerMatch, CurrentMatches, 
Matches) :-
    RemainingNumTeamsPerMatch > 0,
    forTeams(T, 1, NumTeams),
    \+ member(T, CurrentMatches),
    check_not_allocated(T, CurrentMatches),
    append(CurrentMatches, [T], NewMatches),
    Remaining1 is RemainingNumTeamsPerMatch - 1,
    get_match_allocation(NumTeams, Remaining1, NewMatches, Matches).

%recursively store/ add matches into allocation list
store_allocation_1(_, []).
store_allocation_1(T, [X | MatchesTail]) :-
    assertz(match_table(T, X)),
    store_allocation_1(T, MatchesTail).

%recursively store allocation from match list
store_allocation([_]).
store_allocation([T | MatchesTail]) :-
    store_allocation_1(T, MatchesTail),
    store_allocation(MatchesTail).

%recursively check all required matches are allocated
check_plays_all(_, []).
check_plays_all(T, [Team | TeamsTail]) :-
    %check head team from teams list plays next head team from remaining 
teams list
    (    match_table(T, Team)
    ;    match_table(Team, T)
    ),
    check_plays_all(T, TeamsTail).

check_all_play_all([_]).
%get head team of teams list
check_all_play_all([T | TeamsTail]) :-
    check_plays_all(T, TeamsTail),
    check_all_play_all(TeamsTail).

do_round_robin(NumTeams, _, T, []) :-
    T > NumTeams.
do_round_robin(NumTeams, NumTeamsPerMatch, T, [Matches | MatchesTail]) :-
    T =< NumTeams,
    get_match_allocation(NumTeams, NumTeamsPerMatch, [T], Matches),
    !,
    store_allocation(Matches),
    do_round_robin(NumTeams, NumTeamsPerMatch, T, MatchesTail).
do_round_robin(NumTeams, NumTeamsPerMatch, T, Matches) :-
    T =< NumTeams,
    T1 is T + 1,
    do_round_robin(NumTeams, NumTeamsPerMatch, T1, Matches).

round_robin(NumTeams, NumTeamsPerMatch, Matches) :-
    check_num_input(NumTeams),
    check_num_input(NumTeamsPerMatch),
    reset_allocations,
    NumTeamsPerMatch1 is NumTeamsPerMatch - 1, %1
    do_round_robin(NumTeams, NumTeamsPerMatch1, 1, Matches), %(NumTeams, 1, 
1, Matches_List)
    findall(T, forTeams(T, 1, NumTeams), Teams), %finds all teams from 1 .. 
NumTeams
    check_all_play_all(Teams),
    !,
    reset_allocations.
round_robin(_, _, _) :-
    reset_allocations,
    fail.
%已分配匹配项的表
:-动态(匹配表/2)。
%从1.中获取所有团队。。NumTeams
四组(T,T,X):-
T=1。
%重置匹配项的分配表
重置分配:-
收回所有(匹配表(u,u))。
%检查是否尚未分配匹配项
%一次递归完成后的空列表
选中未分配的(u,[])。
%递归搜索分配列表,查看团队是否已分配
检查未分配(T[X | CurrentMatchesTail]):-
\+匹配表(T,X),
\+匹配表(X,T),
选中未分配(T,CurrentMatchesTail)。
%递归获取匹配分配
获取\u匹配\u分配(\u,0,CurrentMatches,CurrentMatches)。
获取匹配分配(NumTeams、remainingnumteamsphermatch、CurrentMatches、,
匹配项):-
剩余numteamsphermatch>0,
四组(T,1,NumTeams),
\+成员(T,当前匹配),
检查未分配(T,CurrentMatches),
追加(CurrentMatches,[T],NewMatches),
Remaining1是RemainingNumTeamsPerMatch-1,
获取匹配分配(NumTeams、Remaining1、NewMatches、Matches)。
%递归地将匹配项存储/添加到分配列表中
存储\分配\ 1(\,[])。
存储分配1(T[X|MatchesTail]):-
assertz(匹配表(T,X)),
存储分配1(T,匹配标签)。
%从匹配列表递归存储分配
存储分配([[uu])。
存储单元分配([T| MatchesTail]):-
存储分配1(T,匹配状态),
存储单元分配(匹配目标)。
%递归检查是否分配了所有必需的匹配项
检查\u播放\u全部(\u,[])。
检查所有(T,[团队]团队成员]:-
%检查球队列表中的主队从剩余球队中选出下一个主队
球队名单
(比赛桌(T队)
;比赛表(T队)
),
检查播放所有(T,TeamsTail)。
检查所有内容,播放所有内容([\])。
%获取团队列表中的团队负责人
全部检查全部播放([T| TeamsTail]):-
检查播放所有(T,TeamsTail),
全场检查全场比赛(全队)。
进行循环(多个团队,T,[]):-
T>NumTeams。
do|u round_robin(NumTeams,NumTeamsPerMatch,T,[Matches | MatchesTail]):-
T=
要输出两支球队在一场比赛中比赛的时间表,查询为循环(6,2,时间表)。其中6是团队数量,2是每场比赛的团队数量

我对Prolog和逻辑编程非常陌生,因此非常感谢您的帮助:)

谢谢,

BD.

也许更好

home_away(N, A-B) :-
    between(1, N, A),
    between(1, N, B),
    A \== B.
这将按字典顺序排列所有可能性

?- findall(X, home_away(3, X), Xs).
Xs = [1-2, 1-3, 2-1, 2-3, 3-1, 3-2].
下面是旧的答案


在/3之间使用
更容易

home_away(N, X) :-
    succ(N0, N), between(1, N0, A),
    succ(A, A1), between(A1, N, B),
    (   X = A-B
    ;   X = B-A
    ).
现在连choicepoint都没有了:

?- home_away(3, X).
X = 1-2 ;
X = 2-1 ;
X = 1-3 ;
X = 3-1 ;
X = 2-3 ;
X = 3-2.
下面你会找到更古老的答案


你的代码真的很难。也许这不是一个有用的想法,但你可以试着给出球队的数量,并得到所有可能的比赛,每对数字都是主宾

home_away(N, X) :-
    numlist(1, N, Teams),
    append(_, [A|T], Teams),
    member(B, T),
    (   X = A-B
    ;   X = B-A
    ).
现在你可以给出球队的数量,你可以得到球队编号1,2,…,N作为主客场

?- home_away(3, X).
X = 1-2 ;
X = 2-1 ;
X = 1-3 ;
X = 3-1 ;
X = 2-3 ;
X = 3-2 ;
false.

?- bagof(X, home_away(4, X), Xs).
Xs = [1-2, 2-1, 1-3, 3-1, 1-4, 4-1, 2-3, 3-2, 2-4, 4-2, 3-4, 4-3].

你不应该删除你的代码。这是问题的重要部分!不管是好是坏,我可能不会回答没有代码的问题!请不要删除您在问题中输入的代码,并始终在每个问题中输入您的代码!