染色问题是离散优化中的经典问题,给定一个无向图,要求相邻节点的颜色不同,求颜色种类的最小值。
用OR-Tools求解这个问题,代码如下:
from ortools.sat.python import cp_model
def coloring(node_count, edges):
model = cp_model.CpModel()
c = [model.NewIntVar(1, node_count, f"Node {i}'s color") for i in range(node_count)]
for edge in edges:
model.Add(c[edge[0]] != c[edge[1]])
count = model.NewIntVar(1, node_count, "max count")
model.AddMaxEquality(count, c)
model.Minimize(count)
solver = cp_model.CpSolver()
solver.parameters.log_search_progress = True
solver.parameters.max_time_in_seconds = 300.0
status = solver.Solve(model)
这里没有做任何优化,能对小规模(050个节点,0500条边)的染色问题快速给出最优值,大规模问题(几百个节点,几千条边),能够快速给出可行解。
但我按照传统的优化方式,例如缩小变量空间、symmetry-breaking、First-fail principle等方法来优化上面的代码,发现效果并不好,甚至还不如优化前的性能。目前并不清楚原因,推测是OR-Tools求解器有更好的优化策略,如果我手动加以限制,反而不利于求解器的性能发挥。