From 0efdd348f8380957c0020c7df66f43ef5477463e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Hu=C5=A1ek?= <PitelVonSacek@gmail.com> Date: Thu, 10 Dec 2015 10:41:27 +0100 Subject: [PATCH] Implement Python part of 2-cut optimization --- group-connectivity.h | 6 +++--- groupConnectivity.pyx | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/group-connectivity.h b/group-connectivity.h index 280b07d..354328d 100644 --- a/group-connectivity.h +++ b/group-connectivity.h @@ -158,7 +158,7 @@ struct Tester : public AbstractTester { #endif - Mapping& cannonize(Mapping& map) { + Mapping& canonize(Mapping& map) { for (const auto &i : nonClassEdges) { #if OPTIMIZE_COMBINE if (map[i.first] != Ring::zero) @@ -225,11 +225,11 @@ struct Tester : public AbstractTester { do { Mapping copy(forb); - INC(classes[pack(cannonize(copy))]); + INC(classes[pack(canonize(copy))]); } while (nextForb(forb)); # else for (size_t i = 0; i < numForb; i++) - INC(classes[pack(cannonize(unpack(i, forb)))]); + INC(classes[pack(canonize(unpack(i, forb)))]); # endif for (const auto &c : classes) if (!c) return (isConnected = false); diff --git a/groupConnectivity.pyx b/groupConnectivity.pyx index 84a66e1..083bd12 100644 --- a/groupConnectivity.pyx +++ b/groupConnectivity.pyx @@ -25,6 +25,7 @@ cdef extern from "group-connectivity.h": cdef cppclass Tester[T](AbstractTester): pass + def pathToEdges(G, path): ret = [] u = path[0] @@ -35,7 +36,9 @@ def pathToEdges(G, path): u = v return ret -def testGroupConnectivity(G, group = "Z4", getClasses = False, debug = False): + +def testGroupConnectivity(G, group = "Z4", getClasses = False, + useTwoCuts = False, debug = False): cdef AbstractTester* tester = NULL if group == "Z4": tester = new Tester[Z4[int]]() @@ -46,6 +49,9 @@ def testGroupConnectivity(G, group = "Z4", getClasses = False, debug = False): assert(tester != NULL) + if useTwoCuts: + G.relabel() + i = 1 for (u, v, _) in G.edge_iterator(): G.set_edge_label(u, v, i) @@ -59,11 +65,37 @@ def testGroupConnectivity(G, group = "Z4", getClasses = False, debug = False): spanningTreeEdges = [ l for (_, _, l) in spanningTree.edge_iterator() ] + twoCuts = [] + if useTwoCuts: + availableEdges = set(spanningTreeEdges) + for v in [ v for v in G.vertices() if G.degree(v) == 2 ]: + e, f = G.edges_incident(v) + el = e[2] + fl = f[2] + if el not in availableEdges or fl not in availableEdges: + continue + availableEdges.remove(el) + availableEdges.remove(fl) + + w1 = e[0] if e[0] != v else e[1] + w2 = f[0] if f[0] != v else f[1] + + if w1 > v: + el *= -1 + if w2 < v: + fl *= -1 + + if debug: + print "twoCut> ", v, w1, w2, el, fl, (w1 > v), (w2 < v) + + twoCuts.append((el, fl)) + if debug: print "Spanning Tree: ", spanningTreeEdges print "Elementary cycles: ", elemCycles + print "Two cuts: ", twoCuts - tester.init(G.num_edges(), spanningTreeEdges, [], elemCycles) + tester.init(G.num_edges(), spanningTreeEdges, twoCuts, elemCycles) ret = tester.run() if getClasses: @@ -74,6 +106,7 @@ def testGroupConnectivity(G, group = "Z4", getClasses = False, debug = False): del tester return ret + def subdivisionIterator(G, edges = None): if edges is None: edges = G.edges() -- GitLab