Search code examples
setcompareminizinc

minizinc sitting friends at a table, sharing common interests


this is my model... trying to put friends one next to other at N=16 POTITIONS of a cyclic table. friends have interests. one next to each other MUST HAVE AT LEAST ONE COMMON INTEREST.

 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 The array of their interests:

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}];

Solution

  • Here is a model that seems to work. The main approach is to use the set operation intersect to ensure that two neighbours have at least one common interest.

    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;
    

    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}];

    output [ "friend_at:(friend_at)\n"] ++ [ "p:(p) interests:(interests[friend_at[p]])\n" | p in POSITIONS ];

    There are many solutions, here's the first one:

     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
    

    Here one can check that all neighbours (including the first and last) has at least one common interest.