import static choco.Choco.*; import choco.cp.model.CPModel; import choco.cp.solver.CPSolver; import choco.cp.solver.search.integer.varselector.StaticVarOrder; import choco.cp.solver.search.integer.varselector.MinDomain; import choco.kernel.model.Model; import choco.kernel.solver.Solver; import choco.kernel.model.variables.integer.IntegerVariable; import choco.kernel.solver.variables.integer.IntDomainVar; public class SteinerTriple04 { public static void main(String[] args) { CPModel model = new CPModel(); int v = Integer.parseInt(args[0]); // # points int b = v*(v-1)/6; // # blocks IntegerVariable[][] A = new IntegerVariable[v][v]; // // A[i][j] = k <-> the pair of points (i,j) is in block k // where there v points, b blocks, each block is of size 3 // NOTE: this forces each pair of points to occur once and once only! // for (int i=0;i<v-1;i++) for (int j=0;j<v;j++) A[i][j] = A[j][i] = makeIntVar("A",0,b-1); for (int i=0;i<v;i++) A[i][i] = constant(0); IntegerVariable[][] block = new IntegerVariable[b][v]; // // block[i][j] = 1 <-> block i contains point j // for (int i=0;i<b;i++) for (int j=0;j<v;j++) block[i][j] = makeIntVar("block",0,1); for (int i=0;i<v-1;i++) for (int j=i+1;j<v;j++) for (int k=0;k<b;k++) model.addConstraint(ifOnlyIf(eq(A[i][j],k),and(eq(block[k][i],1),eq(block[k][j],1)))); // // channel between A and block // A[i][j] = k <-> block[k][i] && block[k][j] // i.e. pair (i,j) \in block k iff block[k][i] is true and block[k][j] is true // for (int i=0;i<b;i++) model.addConstraint(eq(sum(block[i]),3)); // // every block contains 3 points // if (args.length == 2 && Boolean.parseBoolean(args[1])) for (int i=0;i<v-1;i++) model.addConstraint(lex(A[i],A[i+1])); // // symmetry breaker, a redundant constraint // CPSolver sol = new CPSolver(); sol.read(model); IntDomainVar[] decision = new IntDomainVar[v*(v-1)/2]; for (int i=0,k=0;i<v-1;i++) for (int j=i+1;j<v;j++,k++) decision[k] = sol.getVar(A[i][j]); sol.setVarIntSelector(new MinDomain(sol,decision)); // sol.setVarIntSelector(new StaticVarOrder(decision)); // // decision variables are the pairs to be assigned to a block // System.out.println(sol.solve()); sol.printRuntimeSatistics(); for (int i=0;i<b;i++){ for (int j=0;j<v;j++) if(sol.getVar(block[i][j]).getVal() == 1) System.out.print(j +" "); for (int j=0;j<v;j++) System.out.print(sol.getVar(block[i][j]).getVal()); System.out.println(); } System.out.println(); for (int i=0;i<v;i++){ for (int j=0;j<v;j++) if (i!=j) System.out.print(sol.getVar(A[i][j]).getVal() +" "); else System.out.print("- "); System.out.println(); } } }