I have created a model for solving the graph coloring problem in MiniZinc:
include "globals.mzn";
int: n_nodes; % Number of nodes
int: n_edges; % Number of edges
int: domain_ub; % Number of colors
array[int] of int: edges; % All edges of graph as a 1D array
array[1..n_edges, 1..2] of int: edges2d = array2d(1..n_edges, 1..2, edges);
array[1..n_nodes] of var 1..domain_ub: colors;
constraint forall (i in 1..n_edges) (colors[edges2d[i,1]] != colors[edges2d[i,2]]);
solve :: int_search(colors, dom_w_deg, indomain_random)
satisfy;
In order to tackle big problems (around 400-500 nodes), I start with an upper bound of the number of colors and solve successive satisfaction problems decrementing the number by one till it becomes unsatisfiable or times out. This method gives me decent results.
In order to improve my results, I added symmetry breaking constraints to the above model:
constraint colors[1] = 1;
constraint forall (i in 2..n_nodes) ( colors[i] in 1..max(colors[1..i-1])+1 );
This, however, brings down my results both speed-wise and quality-wise.
Why is my model performing badly after adding the additional constraints? How should I go about adding the symmetry breaking constraints?