From f20caa717a684bf3ad7f4c038c3ea975be138e0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Radek=20Hu=C5=A1ek?= <PitelVonSacek@gmail.com>
Date: Thu, 10 Dec 2015 14:51:07 +0100
Subject: [PATCH] Implement and enable double subdivision optimization
---
compileTimeOptions.h | 2 +-
group-connectivity.h | 16 ++++++++++++++++
groupConnectivity.pyx | 21 ++++++++++++++++-----
3 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/compileTimeOptions.h b/compileTimeOptions.h
index 526e6ec..ee4aee3 100644
--- a/compileTimeOptions.h
+++ b/compileTimeOptions.h
@@ -20,6 +20,6 @@ REQUIRES(EXPLICIT_NORMAL_EDGES, USE_NEXT_FORB)
BOOL_OPTION(USE_TWO_CUTS, 1)
REQUIRES(USE_TWO_CUTS, USE_NEXT_FORB && EXPLICIT_NORMAL_EDGES)
-BOOL_OPTION(USE_DOUBLE_SUBDIVISIONS, 0)
+BOOL_OPTION(USE_DOUBLE_SUBDIVISIONS, 1)
REQUIRES(USE_DOUBLE_SUBDIVISIONS, USE_NEXT_FORB && EXPLICIT_NORMAL_EDGES)
diff --git a/group-connectivity.h b/group-connectivity.h
index ec326fb..0199836 100644
--- a/group-connectivity.h
+++ b/group-connectivity.h
@@ -57,6 +57,9 @@ struct Tester : public AbstractTester {
# if USE_TWO_CUTS
std::vector< TwoCutInt > twoCuts;
# endif
+# if USE_DOUBLE_SUBDIVISIONS
+ std::vector< EdgeId > doubleSubdividedEdges;
+# endif
virtual void init(
int edges_,
@@ -87,6 +90,16 @@ struct Tester : public AbstractTester {
}
}
+# if USE_DOUBLE_SUBDIVISIONS
+ if (Ring::size == 4) {
+ for (const auto& i : dSub) {
+ for (auto e : i) edgeList[e - 1] = false;
+ classEdges.push_back(i[0] - 1);
+ doubleSubdividedEdges.push_back(i[0] - 1);
+ }
+ }
+# endif
+
# if USE_TWO_CUTS
for (auto cut : twoCuts_) {
if (cut.first < 0) {
@@ -227,6 +240,9 @@ struct Tester : public AbstractTester {
# if USE_TWO_CUTS
for (const auto& cut : twoCuts) cut.encode(forb, 0);
# endif
+# if USE_DOUBLE_SUBDIVISIONS
+ for (const auto& e : doubleSubdividedEdges) forb.assign(e, 0);
+# endif
do {
Mapping copy(forb);
diff --git a/groupConnectivity.pyx b/groupConnectivity.pyx
index b70b9ed..007c5de 100644
--- a/groupConnectivity.pyx
+++ b/groupConnectivity.pyx
@@ -39,7 +39,7 @@ def pathToEdges(G, path):
def testGroupConnectivity(G, group = "Z4", getClasses = False,
- useTwoCuts = True, useDoubleSubdivisions = False,
+ useTwoCuts = True, useDoubleSubdivisions = True,
debug = False):
cdef AbstractTester* tester = NULL
if group == "Z4":
@@ -59,19 +59,29 @@ def testGroupConnectivity(G, group = "Z4", getClasses = False,
G.set_edge_label(u, v, i)
i += 1
- spanningTree = Graph(G.min_spanning_tree())
+ spanningTree = Graph(G.min_spanning_tree(
+ weight_function = lambda e: min(G.degree([e[0], e[1]]))
+ ))
elemCycles = [
[ l ] + pathToEdges(G, spanningTree.shortest_path(u, v))
for (u, v, l) in set(G.edge_iterator()) - set(spanningTree.edge_iterator())
]
spanningTreeEdges = [ l for (_, _, l) in spanningTree.edge_iterator() ]
+ availableEdges = set(spanningTreeEdges)
-
+ doubleSubdivisions = []
+ if useDoubleSubdivisions:
+ for (u, v, l) in G.edges():
+ if G.degree([u, v]) != [2, 2]:
+ continue
+ edges = set([ l for (_, _, l) in G.edges_incident([u, v]) ])
+ if edges.issubset(availableEdges):
+ doubleSubdivisions.append(edges)
+ availableEdges -= edges
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]
@@ -98,8 +108,9 @@ def testGroupConnectivity(G, group = "Z4", getClasses = False,
print "Spanning Tree: ", spanningTreeEdges
print "Elementary cycles: ", elemCycles
print "Two cuts: ", twoCuts
+ print "Double subdivided edges: ", doubleSubdivisions
- tester.init(G.num_edges(), spanningTreeEdges, twoCuts, [], elemCycles)
+ tester.init(G.num_edges(), spanningTreeEdges, twoCuts, doubleSubdivisions, elemCycles)
ret = tester.run()
if getClasses:
--
GitLab