这是我的模型......试图在N = 16个循环表的选项中将朋友放在另一个旁边。朋友有兴趣。一个接一个必须至少有一个共同的利益。
int :N;
set of int: FRIENDS = 1..N;
set of int: POSITIONS = 1..N;
array[FRIENDS] of set of int: interests;
array[POSITIONS] of var FRIENDS : friends_at;
include "alldifferent.mzn";
constraint alldifferent(friend_at);
constraint forall(i in 2..N-1)(
(interests[friend_at[i+1]]<=interests[friend_at[i]] \/ interests[friend_at[i+1]]>=interests[friend_at[i]])
/\
( interests[friend_at[i-1]]<=interests[friend_at[i]] \/ interests[friend_at[i-1]]>=interests[friend_at[i]])
/\
( interests[friend_at[N]]<=interests[friend_at[1]] \/ interests[friend_at[N]]>=interests[friend_at[1]])
);
solve satisfy;
N = 16 他们感兴趣的一系列:
interests=[{1},{2,3},{3,2},{2},{2,3},{2,1},{1,3},{3},{2,1},{3,1},{1,2},{2},{2,3},{2,3},{3},{2}];
答案 0 :(得分:0)
这是一个似乎有效的模型。主要方法是使用set操作intersect
来确保两个邻居至少有一个共同的兴趣。
int :N;
set of int: FRIENDS = 1..N;
set of int: POSITIONS = 1..N;
array[FRIENDS] of set of int: interests;
array[POSITIONS] of var FRIENDS : friend_at;
include "alldifferent.mzn";
constraint alldifferent(friend_at);
constraint
forall(i in 2..N-1) (
card(interests[friend_at[i+1]] intersect interests[friend_at[i]]) > 0
)
/\
card(interests[friend_at[N]] intersect interests[friend_at[1]]) > 0;
解决满足;
N = 16; 利益= [{1},{2,3},{3,2},{2},{2,3},{2,1},{1,3},{3},{2,1} ,{3,1},{1,2},{2},{2,3},{2,3},{3},{2}];
输出[&#34; friend_at:(friend_at)\ n&#34;] ++ [ &#34; p:(p)兴趣:(兴趣[friend_at [p]])\ n&#34; | p在位置 ];
有许多解决方案,这是第一个:
friend_at:[7, 15, 14, 16, 13, 12, 11, 9, 10, 8, 5, 4, 3, 2, 6, 1]
p:1 interests:{1,3}
p:2 interests:3..3
p:3 interests:2..3
p:4 interests:2..2
p:5 interests:2..3
p:6 interests:2..2
p:7 interests:1..2
p:8 interests:1..2
p:9 interests:{1,3}
p:10 interests:3..3
p:11 interests:2..3
p:12 interests:2..2
p:13 interests:2..3
p:14 interests:2..3
p:15 interests:1..2
p:16 interests:1..1
这里可以检查所有邻居(包括第一个和最后一个)是否至少有一个共同兴趣。