// // given a graph G = (V,E) and an integer h, remove as // few edges from E such that every component of G is // of size h or less. // import java.io.File; import java.io.IOException; import java.util.Scanner; import org.chocosolver.solver.*; import org.chocosolver.solver.variables.*; import org.chocosolver.solver.constraints.*; import org.chocosolver.solver.search.strategy.*; import org.chocosolver.solver.search.strategy.strategy.IntStrategy; import org.chocosolver.solver.search.strategy.selectors.values.*; import org.chocosolver.solver.search.loop.monitors.*; public class Cows3 { Solver solver; int n; // number of vertices int m; // number of edges int h; // size of largest component int components; // max number of components = (n+1)/h, using integer arithmetic int [][] adj; // adj[i][j] = 1 <-> there is an edge between vertices i and j, read in IntVar[] v; // v[i] = j <-> vertex v in component j, these are the decision variables IntVar[][] A; // A[i][j] = 1 <-> vertices i and j are adjacent IntVar[] flatEdges; // all edges in A, flattened. We want to maximise the count of these IntVar sumEdges; // total number of edges, to be maximised IntVar[][] location; //location[i][j] = 1 <-> v[j] = i, i.e. vertex j is in component i Cows3 (String fname,int h) throws IOException { Scanner sc = new Scanner(new File(fname)); n = sc.nextInt(); // number of vertices solver = new Solver("cows"); components = n; v = VF.enumeratedArray("v",n,0,components-1,solver); A = new IntVar [n][n]; adj = new int [n][n]; this.h = h; sumEdges = VF.enumerated("sumEdges",0,n*(n-1)/2,solver); location = VF.enumeratedMatrix("location",components,n,0,1,solver); while (sc.hasNext()){ int i = sc.nextInt(); int j = sc.nextInt(); adj[i][j] = adj[j][i] = 1; m++; } sc.close(); // // read in graph as undirected edges // for (int i=0;i v[i] = v[j] ... same component, i.e. select edge and take consequences LCF.ifThen(ICF.arithm(A[i][j],"=",1),ICF.arithm(v[i],"=",v[j])); } } // make sure every component has size no more than h, using global cardinality constraint int[] values = new int[components]; // the different values that can be taken for (int i=0;i