Skip to content
Snippets Groups Projects
Commit 4470b2bd authored by Radek Hušek's avatar Radek Hušek
Browse files

implementation of naive algorithm for group connectivity testing

parent b2d95f55
No related branches found
No related tags found
No related merge requests found
default: groupConnectivity.so clean_obj
groupConnectivity.so: groupConnectivity.pyx group-connectivity.h setup.py compileTimeOptions.h generateCompileTimeOptions.sh rings.h fast-array.h twoCuts.h parmap.py
groupConnectivity.so: groupConnectivity.pyx group-connectivity.h setup.py compileTimeOptions.h generateCompileTimeOptions.sh rings.h fast-array.h twoCuts.h parmap.py groupConnectivityNaive.py
./generateCompileTimeOptions.sh > options.h
python setup.py build_ext
cp build/lib*/groupConnectivity.so .
......
from libcpp.vector cimport vector
from libcpp cimport bool
from libcpp.utility cimport pair
from sage.graphs.graph import Graph
from sage.graphs.graph import Graph, DiGraph
# include because we don't want it to became external dependecy
include "parmap.py"
include "groupConnectivityNaive.py"
cdef extern from "group-connectivity.h" namespace "Ring":
cdef cppclass Z4[T]:
......@@ -28,6 +31,7 @@ cdef extern from "group-connectivity.h":
def pathToEdges(G, path):
"""Transform list of vertices into list of edges."""
ret = []
u = path[0]
for v in path[1:]:
......@@ -39,10 +43,7 @@ def pathToEdges(G, path):
def theOtherNeighbour(G, v, w):
"""
Given vertex v of degree 2 returns neighbour
of v not equal to w.
"""
"""Return neighbour of v in G not equal to w given v has degree 2."""
N = G.neighbors(v)
if N[0] == w:
return N[1]
......
def flowEnumerator(G, group):
"""Enumerate all flows of given graph.
Graph G must be directed and it edges labeled with numbers 0 to |E(G)|.
"""
m = G.num_edges()
assert(G.is_directed())
assert(set(x for _, _, x in G.edges()) == set(range(m)))
def to_elem_vector(cycle):
vec = [ group.zero() ] * m
for (u, v, x) in cycle:
if u > v:
vec[x] = -group.one()
else:
vec[x] = group.one()
return vec
elemVecs = map(to_elem_vector, Graph(G).cycle_basis(output = "edge"))
def combine(vec, i):
if i >= len(elemVecs):
yield vec
return
for e in group:
for v in combine(map(lambda x: x[0] + e * x[1], zip(vec, elemVecs[i])), i + 1):
yield v
for v in combine([group.zero()] * m, 0):
yield v
def testGroupConnectivityNaive(G_, group, forb_spanning_tree = False, list_all = False):
E = [ (u, v, i) for i, (u, v, _) in enumerate(G_.edges()) ]
G = DiGraph([G_.vertices(), E], format='vertices_and_edges')
m = G.num_edges()
info = { 'graph': G, 'edges': E }
if forb_spanning_tree:
T = G.min_spanning_tree()
else:
T = G.edges()
info['span_tree'] = T
T = [ x for _, _, x in T ]
flows = list(flowEnumerator(G, group))
info['all_flows'] = flows
mask = [group.zero()] * m
for e in T:
mask[e] = None
def is_compatible(f, x):
for i in range(m):
if f[i] == x[i]:
return False
return True
flows = [ f for f in flows if is_compatible(f, mask) ]
info['compatible_flows'] = flows
Elems = [ x for x in group ]
forb = [ group.zero() ] * m
def forb_iter(e):
if e >= len(T):
yield True
return
for v in Elems:
forb[T[e]] = v
for r in forb_iter(e + 1):
yield r
def find_flow():
for f in flows:
if is_compatible(f, forb):
return True
return False
ret = []
for _ in forb_iter(0):
if not find_flow():
if not list_all:
return (False, info, [forb])
ret.append(list(forb))
return (len(ret) == 0, info, ret)
def labelsFromArray(G, E, labels):
for (u, v, i) in E:
G.set_edge_label(u, v, labels[i])
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment