gmmoliveira / graph_coloring

Solving (undirected) graph coloring as a Mixed Integer Programming problem

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

graph_coloring

Solving (undirected) graph coloring as a Mixed Integer Programming problem


Documentation of the source-code

Implements a class GraphColoringMIP, with the following methods:

  • GraphColoringMIP.__init__(self, graph=None, n=None):
    • graph: an adjacency matrix representing the graph as a 2D numpy array of dimensions |V| by |V| where the value at row i and column j set to 0 indicates the absence of an edge and 1 indicates the presence of an edge, between the vertices indexed by i and j. Note that only the upper diagonal of this matrix will be considered for the representation of the graph, also, the MIP algorithm has non-polynomial nature, therefore, using adjacency list of lists doesn't accomplish meaningful results;
  • GraphColoringMIP._lpsolution2coloring(self): decodes the linear programming optimal solution vector X* into a human friendly format consisting of an array of |V| elements each representing a vertex of G with a color (integer number) assigned to it;
  • GraphColoringMIP._update_heuristic_min_chrom(self): updates an internal representation of the minimum chromatic number and it's certificate using a heuristic (algorithm which doesn't offer any guarantees of finding the optimum solution) consisting of a greedy algorithm. Returns the chromatic number found by the heuristic;
  • GraphColoringMIP.model(self, ascopy=True, dtype=np.float64): instantiates internal arrays to be used for the linear programming and fill them up. The heuristic from the method GraphColoringMIP._update_heuristic_min_chrom(self) is used to find an upper limit on the amount of colors that may be used, this simple technique reduces a the number of required variables in the final MIP model, therefore, a solution may be found faster. Returns the LP data arrays;
    • ascopy: return copies of the LP data structures which may be safely modified outside the scope of this object;
    • dtype: sets the data type for the LP data arrays;
  • GraphColoringMIP.solve(self): solves the LP built by GraphColoringMIP.model(self, ascopy=True, dtype=np.float64). Returns a 2-tuple containing the (guaranteed) minimum chromatic number and the optimum solution vector X* in a decoded (human-friendly) format;

Running an example

The input graph is:
[[0 1 0 0 0 1 0 1 1 0 0 1 1 0 1 0 1 0 1 1]
 [1 0 0 1 1 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0]
 [0 0 0 1 1 1 1 1 1 1 1 0 0 1 1 0 0 1 1 0]
 [0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1]
 [0 1 1 0 0 1 0 1 0 1 1 1 0 0 0 0 1 0 1 0]
 [1 0 1 0 1 0 0 0 0 0 1 0 0 1 1 0 1 1 1 1]
 [0 0 1 0 0 0 0 1 0 1 0 0 0 1 0 0 1 1 0 1]
 [1 1 1 0 1 0 1 0 1 0 0 0 0 1 0 0 1 1 0 1]
 [1 1 1 0 0 0 0 1 0 1 1 1 1 1 0 0 0 1 1 0]
 [0 1 1 0 1 0 1 0 1 0 0 0 1 1 0 1 0 1 0 0]
 [0 0 1 0 1 1 0 0 1 0 0 1 1 0 0 1 1 0 0 0]
 [1 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0]
 [1 0 0 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 1 1]
 [0 0 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1]
 [1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0]
 [0 1 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0]
 [1 1 0 0 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0]
 [0 0 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0]
 [1 0 1 0 1 1 0 0 1 0 0 0 1 1 0 0 0 1 0 1]
 [1 0 0 1 0 1 1 1 0 0 0 0 1 1 0 0 0 0 1 0]]
It contains 20 vertices and 81 edges.

HEURISTIC MIN CHROM = 6
MIP optimization time (milliseconds): 82 The minimum chromatic number for the given input is: 5 The color to assign to vertex k matches the k-th one in the following array: [0 1 0 2 3 1 1 2 4 2 2 1 1 3 4 0 4 3 2 4]

Further reference on the problem formulation and solution may be found here: https://gmmoliveira.github.io/blog/graph_coloring.html.

About

Solving (undirected) graph coloring as a Mixed Integer Programming problem

License:Apache License 2.0


Languages

Language:Python 100.0%