// Graph coloring backtrack, // search heuristics are set based on heuristc flag func colorMapBacktrack(g graph.Graph, height int, h *nh.Heap) bool { // Have all nodes been colored? if height == len(g) { return true } // Assign current node by MRV heap or sequentally var currNode *graph.Node if Heuristic.MRV { // Top from the heap has the Minimum Remaining Values currNode = heap.Pop(h).(nh.NodeItem).Node } else { currNode = g[height] } colors := ColorsCache.Colors[height] for _, color := range colors { // Is this color avaliable for use? if currNode.TakenColors[color] == 0 { // Update currNode color and warn adjacents impossible := updateColorAndAdj(currNode, color, h) // Forward Checking if Heuristic.FC { if impossible { resetColorAndAdj(currNode) continue } } // Proceed with recursion if colorMapBacktrack(g, height+1, h) { return true } resetColorAndAdj(currNode) } } // Need to backtrack if Heuristic.MRV { heap.Push(h, nh.NewNodeItem(currNode)) } return false }
// Setup for graph coloring backtracking algorithm, // search heuristics are set based on heuristc flag func colorMap(g graph.Graph) bool { // For MRV, we'll use a heap var h nh.Heap if Heuristic.MRV { h = nh.NewNodeHeap(len(g), Heuristic.Degree) for _, n := range g { h.Items = append(h.Items, nh.NewNodeItem(n)) } heap.Init(&h) } // Init colors cache ColorsCache.Colors = make([][]graph.NodeColor, len(g)) for i := range g { ColorsCache.Colors[i] = make([]graph.NodeColor, 0, graph.NumColors-1) for color := graph.Blank + 1; color < graph.NumColors; color++ { ColorsCache.Colors[i] = append(ColorsCache.Colors[i], graph.NodeColor(color)) } } return colorMapBacktrack(g, 0, &h) }