Hello everyone, I just developed a new function for coloring graph edges based on this article: https://www.sciencedirect.com/science/article/abs/pii/002001909290041S , and I'd like to know if you think it's a valuable contribution to sage and deserves a trac ticket. I compared the existing edge coloring function and the one I created, and it's a pretty good improvement in processing time for graphs with a lot of edges:
sage: g_list = [graphs RandomGNP(x, 0.7) for x in range(25)] sage: %time c = [vizing_edge_coloring(x) for x in g_list] CPU times: user 131 ms, sys: 9.94 ms, total: 141 ms Wall time: 140 ms sage: %time c = [edge_coloring(x, vizing=True) for x in g_list] CPU times: user 18.6 s, sys: 134 μs, total: 18.6 s Wall time: 18.6 s I still haven't decided if this function should be standalone or if it should be called when the flag vizing is set on the existing edge_coloring function. If you have an opinion on that, please share :) I'm pasting the code below for reference, since I haven't created a ticket and pushed my branch yet. Feedback is much appreciated! def vizing_edge_coloring(g, hex_colors=False): r""" Compute an edge coloring with at most `\Delta + 1` colors. INPUT: - ``g`` -- a graph. - ``hex_colors`` -- boolean (default: ``False``); when set to ``True``, the partition returned is a dictionary whose keys are colors and whose values are the color classes (ideal for plotting) OUTPUT: - Returns a partition of the edge set into at most `\Delta + 1` matchings. .. SEEALSO:: - :wikipedia:`Edge_coloring` for further details on edge coloring - :wikipedia:`Vizing's_theorem` for further details on Vizing's theorem ALGORITHM: This function's implementation is based on the algorithm described at [MG1992]_ EXAMPLES: Coloring the edges of the Petersen Graph:: sage: from sage.graphs.graph_coloring import vizing_edge_coloring sage: g = graphs.PetersenGraph() sage: vizing_edge_coloring(g) [[(0, 1), (2, 7), (3, 4), (6, 9)], [(0, 4), (2, 3), (5, 7), (6, 8)], [(0, 5), (1, 6), (3, 8), (7, 9)], [(1, 2), (4, 9), (5, 8)]] sage: vizing_edge_coloring(g, hex_colors=True) {'#00ffff': [(0, 5), (1, 6), (3, 8), (7, 9)], '#7f00ff': [(1, 2), (4, 9), (5, 8)], '#7fff00': [(0, 4), (2, 3), (5, 7), (6, 8)], '#ff0000': [(0, 1), (2, 7), (3, 4), (6, 9)]} TESTS: Graph without edge:: sage: g = Graph(2) sage: vizing_edge_coloring(g) [] sage: vizing_edge_coloring(g, hex_colors=True) {} """ # finds every color adjacent to vertex v def colors_of(v): return [x[2] for x in g.edges_incident(v) if x[2] is not None] # constructs a maximal fan <f..l> of X where X is edge[0] and f is edge[1] def maximal_fan(edge): fan_center, rear = edge rear_colors = colors_of(rear) cdef list neighbors = [n for n in g.neighbors(fan_center) if g.edge_label(fan_center, n) is not None] cdef list fan = [rear] can_extend_fan = True while can_extend_fan: can_extend_fan = False for n in neighbors: if g.edge_label(fan_center, n) not in rear_colors: fan.append(n) rear = n rear_colors = colors_of(rear) can_extend_fan = True neighbors.remove(n) return fan # gives each edge Xu in the fan <f..w> the color of Xu+ and uncolors Xw def rotate_fan(fan_center, fan): for i in range(1, len(fan)): g.set_edge_label(fan_center, fan[i - 1], g.edge_label(fan_center, fan[i])) g.set_edge_label(fan_center, fan[-1], None) # computes the maximal ab-path starting at v def find_path(v, a, b, path=[]): path_edge = [x for x in g.edges_incident(v) if x[2] == a] if path_edge and path_edge[0] not in path: path.append(path_edge[0][0] if path_edge[0][1] == v else path_edge[0][1]) find_path(path[-1], b, a, path) return path # exchanges the color of every edge on the ab-path starting at v def invert_path(v, a, b): path = [v] + find_path(v, a, b, []) for i in range(1, len(path)): g.set_edge_label(path[i-1], path[i], a if g.edge_label(path[i-1], path[i]) == b else b) # returns the ´smallest´ color free at v def find_free_color(v): colors = [x[2] for x in g.edges_incident(v) if x[2] is not None] for c in range(g.degree(v) + 1): if c not in colors: return c g._scream_if_not_simple() # as to not overwrite the original graph's labels g = copy(g) for e in g.edge_iterator(labels=False): fan = maximal_fan(e) fan_center = e[0] rear = fan[-1] c = find_free_color(fan_center) d = find_free_color(rear) invert_path(fan_center, d, c) for i in range(len(fan)): if d not in colors_of(fan[i]): fan = fan[:i + 1] break rotate_fan(fan_center, fan) g.set_edge_label(fan_center, fan[-1], d) matchings = dict() for e in g.edge_iterator(): matchings[e[2]] = matchings.get(e[2], []) + [(e[0], e[1])] classes = list(matchings.values()) if hex_colors: from sage.plot.colors import rainbow return dict(zip(rainbow(len(classes)), classes)) else: return classes -- You received this message because you are subscribed to the Google Groups "sage-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/sage-devel/a77f6852-f1f1-4b41-aa6c-893711d559b5n%40googlegroups.com.