From 5ff3ddca6f507cc81b1da3c886c8b1001ce3ad5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Radek=20Hu=C5=A1ek?= <husek@iuuk.mff.cuni.cz>
Date: Thu, 25 Mar 2021 17:42:25 +0100
Subject: [PATCH] graph_to_gadget: add experimental decomposition

---
 graph_tools/misc.py | 38 +++++++++++++++++++++++++++++++++++---
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/graph_tools/misc.py b/graph_tools/misc.py
index 44c7daa..f6f39a5 100644
--- a/graph_tools/misc.py
+++ b/graph_tools/misc.py
@@ -52,6 +52,40 @@ def _init_():
     return b
 
 
+  def guess_decomposition(G):
+    from sage.all import flatten
+
+    cycles = []
+    H = G.copy()
+    while not H.is_forest():
+      _, c = H.girth(certificate=True)
+
+      stack = H.vertex_boundary(c)
+      H.delete_vertices(c)
+
+      while stack:
+        v = stack.pop()
+        if v not in H or H.degree(v) > 1: continue
+        c = [ c, v ]
+        stack.extend(H.vertex_boundary([ v ]))
+        H.delete_vertex(v)
+      
+      cycles.append(c)
+
+    score = lambda x: len(G.edge_boundary(flatten([cycles[x[0]], cycles[x[1]]])))
+
+    while len(cycles) > 2:
+      i1, i2 = min([ (i, j) for i in range(len(cycles)) for j in range(i) ], key=score)
+      c1 = cycles[i1]
+      c2 = cycles[i2]
+      del cycles[i1]
+      del cycles[i2]
+      cycles.append([ c1, c2 ])
+
+    assert(sorted(flatten(cycles)) == sorted(G.vertices()))
+    return cycles
+
+
   def graph_to_gadget(G, decomposition = None, allow_non_graph = False):
     """Transform graph into a Gadget.
 
@@ -76,9 +110,7 @@ def _init_():
     edges = [ (verts[u], verts[v]) for u, v, _ in G.edges() ]
 
     if decomposition is None:
-      decomposition = G.vertices()[0]
-      for v in G.vertices()[1:]:
-        decomposition = [ v, decomposition ]
+      decomposition = guess_decomposition(G)
 
     vert_map = { v: [0, 1, 2] for v in range(len(verts)) }
 
-- 
GitLab