2017-04-05 6 views
0

私は現在、Prologでラウンドロビンスケジュールをプログラムしようとしており、すべてのチームが一度お互いにプレイできるように管理しています。他の2倍、家庭と離れた両方、例えば[1,2]および[2,1]。次のように私がこれまで持っているコードは次のとおりです。Prologラウンドロビンスケジュールホームとアウェイ

%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試合でクエリがROUND_ROBIN(6、2、スケジュール)でプレイする予定。ここで、6はチームの数であり、2は各ゲームをプレイするチームの数です。

私は助けをいただければ幸いです:)

プロローグと論理プログラミングに非常に新しいですが、

BDをいただき、ありがとうございます。

+0

家として離れ1,2、...、Nの番号が付けられ得ます。それは質問の重要な部分でした!良いか悪いかにかかわらず、私はおそらくコードなしで質問に答えることはできません!質問に入れたコードを削除してはならず、常にすべての質問にコードを入れてください! –

答えて

1

多分もっと良いですか?

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]. 

以下のより古い回答。


between/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 
    ). 

今でもチョイスポイントない:

?- 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 
    ). 

は今、これで、あなたはチームの数を与えることができますし、チームはあなたがあなたのコードを削除しないでください

?- 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].