создать подмножество и использовать каждый атом только один раз - PullRequest
0 голосов
/ 26 апреля 2018

Я совершенно новый в аспере. Мне нужно создать группу команд. Каждая группа должна состоять из 3 случайно выбранных команд. Команда может быть только в одной группе.

Заранее спасибо. Вот мой код

team(fener;galata;besik;van;adana;mardin).

neq(X,Y) :- X!=Y,team(X),team(Y).

count(C) :- C = #count{ T : team(T)}.

C/3 {group(X,Y,Z):team(X),team(Y),team(Z), neq(X,Y),neq(X,Z),neq(Z,Y) } C/3 :- count(C).

#show group/3.

возможный вывод может быть

group(fener;besik;van) group(galata;mardin;adana)

Ответы [ 2 ]

0 голосов
/ 29 апреля 2018

Вывод, который вы хотите, невозможен:

group(a;b;c).

означает:

group(a). group(b). group(c).

Возможный вывод будет:

group(a,b,c).

Но ASP не очень дружит с переменными аргументами атомов или списками элементов в качестве параметров. Более простым выходом для управления будет:

group(1,a). group(1,b). group(1,c).

И это очень легко сгенерировать, и позволяет нам избежать дорогостоящих #count:

% Data
#const nb_group=2.
group(1..nb_group).
team(fener;galata;besik;van;adana;mardin).

% Assign 3 teams to each group
3{ group(G,T): team(T) }3 :- group(G).

% Two (almost) equilavent constraints:
1{ group(G,T): group(G) }1:- team(T).  % a team is in only one group
OR
:- team(T) ; not group(_,T).  % a team has no group
0 голосов
/ 26 апреля 2018

Думаю, нашли решение.

team(fener;galata;besik;van;adana;mardin).

neq(X,Y) :- X!=Y,team(X),team(Y).

count(C) :- C = #count{ T : team(T)}.

C/3 {group(X,Y,Z):team(X),team(Y),team(Z), neq(X,Y),neq(X,Z),neq(Z,Y) } C/3 :- count(C).

exist_in_group(T) :- group(T,_,_).
exist_in_group(T) :- group(_,T,_).
exist_in_group(T) :- group(_,_,T).

:- team(T), not exist_in_group(T).

#show group/3.

Выход:

clingo version 5.0.0
Solving...
Answer: 1
group(besik,fener,adana) group(galata,mardin,van)
SATISFIABLE

Models       : 1+
Calls        : 1
Time         : 0.011s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
CPU Time     : 0.000s
...