/* Swedish election 2018 - select majority subsets in Picat. Mandates from https://sv.wikipedia.org/wiki/Riksdagsvalet_i_Sverige_2018 Party 2014 2018 Diff ---------------------------------------- Vänsterpartiet 21 28 -7 Socialdemokraterna 113 100 -13 Miljöpartiet 25 16 -9 Centern 22 31 +9 Liberalerna 19 20 +1 Moderaterna 84 70 -14 Kristdemokraterna 16 22 +6 Sverigedemokraterna 49 62 +13 Objective: Select a subset of parties such that the total is >= 175. We also include the constraints that some parties don't want to accept a coalition including certain parties, i.e. v and sd. Note: in the original setting (in 2018) L stated that they don't support a SD coalition. But much have changed in 2021: now L accept SD (and would not vote no to SD). Here are the 23 possible coalitions with >= 175 votes, with the no accept constraints for v and sd (in go/0): num_coalitions = 23 Votes: 182: [s (100),l (20),sd (62)] Votes: 184: [s (100),kd (22),sd (62)] Votes: 186: [s (100),mp (16),m (70)] Votes: 189: [s (100),mp (16),c (31),l (20),kd (22)] Votes: 190: [s (100),l (20),m (70)] Votes: 192: [s (100),m (70),kd (22)] Votes: 201: [s (100),c (31),m (70)] Votes: 204: [s (100),l (20),kd (22),sd (62)] Votes: 206: [s (100),mp (16),l (20),m (70)] Votes: 208: [s (100),mp (16),m (70),kd (22)] Votes: 212: [s (100),l (20),m (70),kd (22)] Votes: 217: [s (100),mp (16),c (31),m (70)] Votes: 221: [s (100),c (31),l (20),m (70)] Votes: 223: [s (100),c (31),m (70),kd (22)] Votes: 228: [s (100),mp (16),l (20),m (70),kd (22)] Votes: 232: [s (100),m (70),sd (62)] Votes: 237: [s (100),mp (16),c (31),l (20),m (70)] Votes: 239: [s (100),mp (16),c (31),m (70),kd (22)] Votes: 243: [s (100),c (31),l (20),m (70),kd (22)] Votes: 252: [s (100),l (20),m (70),sd (62)] Votes: 254: [s (100),m (70),kd (22),sd (62)] Votes: 259: [s (100),mp (16),c (31),l (20),m (70),kd (22)] Votes: 274: [s (100),l (20),m (70),kd (22),sd (62)] The second scenario is the it's more realistic that S would vote against a coalition with SD so then we have these 16 coalitions: num_coalitions = 16 With v/sd no vote constraints: Adding S is against SD. Votes: 186: [s (100),mp (16),m (70)] Votes: 189: [s (100),mp (16),c (31),l (20),kd (22)] Votes: 190: [s (100),l (20),m (70)] Votes: 192: [s (100),m (70),kd (22)] Votes: 201: [s (100),c (31),m (70)] Votes: 206: [s (100),mp (16),l (20),m (70)] Votes: 208: [s (100),mp (16),m (70),kd (22)] Votes: 212: [s (100),l (20),m (70),kd (22)] Votes: 217: [s (100),mp (16),c (31),m (70)] Votes: 221: [s (100),c (31),l (20),m (70)] Votes: 223: [s (100),c (31),m (70),kd (22)] Votes: 228: [s (100),mp (16),l (20),m (70),kd (22)] Votes: 237: [s (100),mp (16),c (31),l (20),m (70)] Votes: 239: [s (100),mp (16),c (31),m (70),kd (22)] Votes: 243: [s (100),c (31),l (20),m (70),kd (22)] Votes: 259: [s (100),mp (16),c (31),l (20),m (70),kd (22)] One can note that in all both these scenarious, s must not vote against the coalition. The third scenariou is with no constraints at all, with give 128 possible (and probably some impossible) coalitions (go3/0). Without v/sd no vote constraints num_coalitions = 128 Votes: 175: [v (28),s (100),mp (16),c (31)] Votes: 176: [v (28),mp (16),m (70),sd (62)] Votes: 178: [s (100),mp (16),sd (62)] Votes: 179: [mp (16),c (31),m (70),sd (62)] [v (28),mp (16),c (31),l (20),kd (22),sd (62)] [v (28),s (100),c (31),l (20)] Votes: 180: [v (28),l (20),m (70),sd (62)] Votes: 181: [v (28),s (100),c (31),kd (22)] Votes: 182: [s (100),l (20),sd (62)] [v (28),m (70),kd (22),sd (62)] Votes: 183: [c (31),l (20),m (70),sd (62)] Votes: 184: [s (100),kd (22),sd (62)] Votes: 185: [c (31),m (70),kd (22),sd (62)] Votes: 186: [s (100),mp (16),m (70)] [v (28),s (100),mp (16),l (20),kd (22)] Votes: 187: [v (28),mp (16),c (31),l (20),m (70),kd (22)] Votes: 189: [s (100),mp (16),c (31),l (20),kd (22)] Votes: 190: [mp (16),l (20),m (70),kd (22),sd (62)] [s (100),l (20),m (70)] [v (28),s (100),sd (62)] Votes: 191: [v (28),c (31),m (70),sd (62)] Votes: 192: [s (100),m (70),kd (22)] Votes: 193: [s (100),c (31),sd (62)] Votes: 195: [v (28),s (100),mp (16),c (31),l (20)] Votes: 196: [v (28),mp (16),l (20),m (70),sd (62)] Votes: 197: [v (28),s (100),mp (16),c (31),kd (22)] Votes: 198: [s (100),mp (16),l (20),sd (62)] [v (28),mp (16),m (70),kd (22),sd (62)] [v (28),s (100),m (70)] Votes: 199: [mp (16),c (31),l (20),m (70),sd (62)] Votes: 200: [s (100),mp (16),kd (22),sd (62)] Votes: 201: [mp (16),c (31),m (70),kd (22),sd (62)] [s (100),c (31),m (70)] [v (28),s (100),c (31),l (20),kd (22)] Votes: 202: [v (28),l (20),m (70),kd (22),sd (62)] Votes: 204: [s (100),l (20),kd (22),sd (62)] Votes: 205: [c (31),l (20),m (70),kd (22),sd (62)] Votes: 206: [s (100),mp (16),l (20),m (70)] [v (28),s (100),mp (16),sd (62)] Votes: 207: [v (28),mp (16),c (31),m (70),sd (62)] Votes: 208: [s (100),mp (16),m (70),kd (22)] Votes: 209: [s (100),mp (16),c (31),sd (62)] Votes: 210: [v (28),s (100),l (20),sd (62)] Votes: 211: [v (28),c (31),l (20),m (70),sd (62)] Votes: 212: [s (100),l (20),m (70),kd (22)] [v (28),s (100),kd (22),sd (62)] Votes: 213: [s (100),c (31),l (20),sd (62)] [v (28),c (31),m (70),kd (22),sd (62)] Votes: 214: [v (28),s (100),mp (16),m (70)] Votes: 215: [s (100),c (31),kd (22),sd (62)] Votes: 217: [s (100),mp (16),c (31),m (70)] [v (28),s (100),mp (16),c (31),l (20),kd (22)] Votes: 218: [v (28),mp (16),l (20),m (70),kd (22),sd (62)] [v (28),s (100),l (20),m (70)] Votes: 220: [s (100),mp (16),l (20),kd (22),sd (62)] [v (28),s (100),m (70),kd (22)] Votes: 221: [mp (16),c (31),l (20),m (70),kd (22),sd (62)] [s (100),c (31),l (20),m (70)] [v (28),s (100),c (31),sd (62)] Votes: 223: [s (100),c (31),m (70),kd (22)] Votes: 226: [v (28),s (100),mp (16),l (20),sd (62)] Votes: 227: [v (28),mp (16),c (31),l (20),m (70),sd (62)] Votes: 228: [s (100),mp (16),l (20),m (70),kd (22)] [v (28),s (100),mp (16),kd (22),sd (62)] Votes: 229: [s (100),mp (16),c (31),l (20),sd (62)] [v (28),mp (16),c (31),m (70),kd (22),sd (62)] [v (28),s (100),c (31),m (70)] Votes: 231: [s (100),mp (16),c (31),kd (22),sd (62)] Votes: 232: [s (100),m (70),sd (62)] [v (28),s (100),l (20),kd (22),sd (62)] Votes: 233: [v (28),c (31),l (20),m (70),kd (22),sd (62)] Votes: 234: [v (28),s (100),mp (16),l (20),m (70)] Votes: 235: [s (100),c (31),l (20),kd (22),sd (62)] Votes: 236: [v (28),s (100),mp (16),m (70),kd (22)] Votes: 237: [s (100),mp (16),c (31),l (20),m (70)] [v (28),s (100),mp (16),c (31),sd (62)] Votes: 239: [s (100),mp (16),c (31),m (70),kd (22)] Votes: 240: [v (28),s (100),l (20),m (70),kd (22)] Votes: 241: [v (28),s (100),c (31),l (20),sd (62)] Votes: 243: [s (100),c (31),l (20),m (70),kd (22)] [v (28),s (100),c (31),kd (22),sd (62)] Votes: 245: [v (28),s (100),mp (16),c (31),m (70)] Votes: 248: [s (100),mp (16),m (70),sd (62)] [v (28),s (100),mp (16),l (20),kd (22),sd (62)] Votes: 249: [v (28),mp (16),c (31),l (20),m (70),kd (22),sd (62)] [v (28),s (100),c (31),l (20),m (70)] Votes: 251: [s (100),mp (16),c (31),l (20),kd (22),sd (62)] [v (28),s (100),c (31),m (70),kd (22)] Votes: 252: [s (100),l (20),m (70),sd (62)] Votes: 254: [s (100),m (70),kd (22),sd (62)] Votes: 256: [v (28),s (100),mp (16),l (20),m (70),kd (22)] Votes: 257: [v (28),s (100),mp (16),c (31),l (20),sd (62)] Votes: 259: [s (100),mp (16),c (31),l (20),m (70),kd (22)] [v (28),s (100),mp (16),c (31),kd (22),sd (62)] Votes: 260: [v (28),s (100),m (70),sd (62)] Votes: 263: [s (100),c (31),m (70),sd (62)] [v (28),s (100),c (31),l (20),kd (22),sd (62)] Votes: 265: [v (28),s (100),mp (16),c (31),l (20),m (70)] Votes: 267: [v (28),s (100),mp (16),c (31),m (70),kd (22)] Votes: 268: [s (100),mp (16),l (20),m (70),sd (62)] Votes: 270: [s (100),mp (16),m (70),kd (22),sd (62)] Votes: 271: [v (28),s (100),c (31),l (20),m (70),kd (22)] Votes: 274: [s (100),l (20),m (70),kd (22),sd (62)] Votes: 276: [v (28),s (100),mp (16),m (70),sd (62)] Votes: 279: [s (100),mp (16),c (31),m (70),sd (62)] [v (28),s (100),mp (16),c (31),l (20),kd (22),sd (62)] Votes: 280: [v (28),s (100),l (20),m (70),sd (62)] Votes: 282: [v (28),s (100),m (70),kd (22),sd (62)] Votes: 283: [s (100),c (31),l (20),m (70),sd (62)] Votes: 285: [s (100),c (31),m (70),kd (22),sd (62)] Votes: 287: [v (28),s (100),mp (16),c (31),l (20),m (70),kd (22)] Votes: 290: [s (100),mp (16),l (20),m (70),kd (22),sd (62)] Votes: 291: [v (28),s (100),c (31),m (70),sd (62)] Votes: 296: [v (28),s (100),mp (16),l (20),m (70),sd (62)] Votes: 298: [v (28),s (100),mp (16),m (70),kd (22),sd (62)] Votes: 299: [s (100),mp (16),c (31),l (20),m (70),sd (62)] Votes: 301: [s (100),mp (16),c (31),m (70),kd (22),sd (62)] Votes: 302: [v (28),s (100),l (20),m (70),kd (22),sd (62)] Votes: 305: [s (100),c (31),l (20),m (70),kd (22),sd (62)] Votes: 307: [v (28),s (100),mp (16),c (31),m (70),sd (62)] Votes: 311: [v (28),s (100),c (31),l (20),m (70),sd (62)] Votes: 313: [v (28),s (100),c (31),m (70),kd (22),sd (62)] Votes: 318: [v (28),s (100),mp (16),l (20),m (70),kd (22),sd (62)] Votes: 321: [s (100),mp (16),c (31),l (20),m (70),kd (22),sd (62)] Votes: 327: [v (28),s (100),mp (16),c (31),l (20),m (70),sd (62)] Votes: 329: [v (28),s (100),mp (16),c (31),m (70),kd (22),sd (62)] Votes: 333: [v (28),s (100),c (31),l (20),m (70),kd (22),sd (62)] Votes: 349: [v (28),s (100),mp (16),c (31),l (20),m (70),kd (22),sd (62)] This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. % % With the v/sd no-vote constraints % go ?=> coalitions(v_sd_1), print_map(get_global_map()), nl. go => true. go2 ?=> coalitions(v_sd_2), print_map(get_global_map()), nl. go2 => true. % % Without any v/sd no-vote constraints % go3 ?=> coalitions(false), print_map(get_global_map()), nl. go3 => true. % % Print the coalition map % print_map(Map) => println(num_coalitions=sum([Len : M in Map, Len = second(M.to_list()).len])), foreach(Votes=Coalitions in Map.to_list.sort) printf("Votes: %d: ",Votes), Count = 0, foreach(C in Coalitions) Count := Count + 1, if Count > 1 then print("\t ") end, println(C) end end, nl. % % Get all possible coalitions. % if V_SD_Constraints == true then include % the no vote constraints regarding v and sd. % coalitions(V_SD_Constraints) ?=> Map = get_global_map(), election(2018,Mandat), println(total=sum(Mandat)), N = Mandat.len, [V,S,MP,C,L,M,KD,SD] = [I : I in 1..N], Parties = [v,s,mp,c,l,m,kd,sd], % decision variables X = new_list(N), X :: 0..1, Z #= sum([Mandat[I]*X[I] : I in 1..N]), Z #>= 175, if V_SD_Constraints != false then println("With v/sd no vote constraints part 1"), % what happens if v is in the coalition? % L vote no % C vote no % M vote no % KD vote no % SD vote no (X[V] #= 1 #=> (X[L] #= 0 #/\ X[C] #= 0 #/\ X[M] #= 0 #/\ X[KD] #= 0 #/\ X[SD] #= 0)), % what happens if sd is in the coalition? % C vote no % V note no % MP vote no % (X[SD] #= 1 #=> (X[C] #= 0 #/\ X[V] #= 0 #/\ X[MP] #= 0)), if V_SD_Constraints == v_sd_2 then % Second scenario: S would also vote no to SD println("With v/sd no vote constraints: Adding S is against SD."), (X[SD] #= 1 #=> X[S] #= 0) end else println("Without v/sd no vote constraints") end, solve($[],X ++ [Z]), Res = [Parties[I].to_string() ++ " (" ++ Mandat[I].to_string() ++ ")" : I in 1..N, X[I] == 1], Map.put(Z,Map.get(Z,[]) ++ [Res]), fail, nl. coalitions(_) => true. election(2018, Mandat) => Mandat = [ 28,100, 16, 31, 20, 70, 22, 62]. election(2014, Mandat) => Mandat = [21,113,25,22,19,84,16,49].