From 566e626f63267e9c0359df92558c35e1fe25f6e0 Mon Sep 17 00:00:00 2001 From: Matthew Henderson Date: Fri, 29 Nov 2024 10:02:25 +0000 Subject: [PATCH 1/3] Add implementation of total list-colouring. --- src/vizing/__init__.py | 44 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/vizing/__init__.py b/src/vizing/__init__.py index a6c696c..98cd113 100644 --- a/src/vizing/__init__.py +++ b/src/vizing/__init__.py @@ -1,4 +1,4 @@ -import constraint +import constraint as ct def node_list_colouring_problem(G): """ @@ -7,11 +7,11 @@ def node_list_colouring_problem(G): :param G: A graph with lists of permissible colours assigned to nodes. :return A node list-colouring constraint problem. """ - P = constraint.Problem() + P = ct.Problem() for node in G.nodes(): P.addVariable(node, G.nodes[node]['permissible']) for edge in G.edges(): - P.addConstraint(constraint.AllDifferentConstraint(), edge) + P.addConstraint(ct.AllDifferentConstraint(), edge) return(P) def node_list_colouring_solution(G): @@ -34,11 +34,11 @@ def edge_list_colouring_problem(G): :param G: A graph with lists of permissible colours assigned to edges. :return An edge list-colouring constraint problem. """ - P = constraint.Problem() + P = ct.Problem() for edge in G.edges(): P.addVariable(edge, G.edges[edge]['permissible']) for node in G.nodes(): - P.addConstraint(constraint.AllDifferentConstraint(), [tuple(sorted(x)) for x in G.edges(node)]) + P.addConstraint(ct.AllDifferentConstraint(), [tuple(sorted(x)) for x in G.edges(node)]) return(P) def edge_list_colouring_solution(G): @@ -53,3 +53,37 @@ def edge_list_colouring_solution(G): for edge in G.edges(): G.edges()[edge]['colour'] = S[edge] return(G) + +def total_list_colouring_problem(G): + """ + Return a constraint problem representing a total list-colouring instance. + + :param G: A graph with lists of permissible colours assigned to nodes and edges. + :return A total list-colouring constraint problem. + """ + P = ct.Problem() + for node in G.nodes(): + P.addVariable(node, G.nodes[node]['permissible']) + for edge in G.edges(): + P.addVariable(edge, G.edges[edge]['permissible']) + for edge in G.edges(): + P.addConstraint(ct.AllDifferentConstraint(), [edge[0], edge[1], edge]) + for node in G.nodes(): + P.addConstraint(ct.AllDifferentConstraint(), [node] + [tuple(sorted(x)) for x in G.edges(node)]) + return(P) + +def total_list_colouring_solution(G): + """ + Return a total list-coloured graph. + + :param G: A graph with lists of permissible colours assigned to nodes and edges. + :return A properly total list-coloured graph. + """ + P = total_list_colouring_problem(G) + S = P.getSolution() + for node in G.nodes: + G.nodes[node]['colour'] = S[node] + for edge in G.edges(): + G.edges()[edge]['colour'] = S[edge] + return(G) + From 671d398c0ab853867fbba528d1f8c34f45942af5 Mon Sep 17 00:00:00 2001 From: Matthew Henderson Date: Fri, 29 Nov 2024 10:02:38 +0000 Subject: [PATCH 2/3] Add tests of total list-colouring. --- tests/test_total-list-colouring.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tests/test_total-list-colouring.py diff --git a/tests/test_total-list-colouring.py b/tests/test_total-list-colouring.py new file mode 100644 index 0000000..ec6b058 --- /dev/null +++ b/tests/test_total-list-colouring.py @@ -0,0 +1,23 @@ +import listcolouring as lc +import networkx as nx +import vizing as vz + +def test_total_list_colouring_problem(): + G = nx.complete_graph(3) + permissible_dict_edge = {(0, 1): [0, 1], (0, 2): [1, 2], (1, 2): [2, 4]} + nx.set_edge_attributes(G, permissible_dict_edge, "permissible") + nx.set_edge_attributes(G, None, "colour") + permissible_dict_node = {0: [0, 1], 1: [1, 2], 2: [2, 4]} + nx.set_node_attributes(G, permissible_dict_node, "permissible") + nx.set_node_attributes(G, None, "colour") + P = vz.total_list_colouring_problem(G) + assert P._variables == {0: [0, 1], 1: [1, 2], 2: [2, 4], (0, 1): [0, 1], (0, 2): [1, 2], (1, 2): [2, 4]} + +def test_total_list_colouring_solution(): + G = nx.petersen_graph() + n_colours = 6 + G = lc.list_init_node(G, range(n_colours - 1), 3, 0) + G = lc.list_init(G, range(n_colours - 1), 3, 0) + G = vz.total_list_colouring_solution(G) + assert G.nodes()[0]['colour'] == 0 + From 074049bc60f4446dca70d78eb7190b990be835d1 Mon Sep 17 00:00:00 2001 From: Matthew Henderson Date: Fri, 29 Nov 2024 10:02:54 +0000 Subject: [PATCH 3/3] Bump dev version number: 9001 -> 9002. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3c9a59a..062c8de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "vizing" -version = "0.1.0.9001" +version = "0.1.0.9002" description = "Constraint-based list-colouring in Python." authors = ["Matthew Henderson "] readme = "README.md"