diff --git a/tests/test_euler_tour.py b/tests/test_euler_tour.py index fe347a3..ae485c7 100644 --- a/tests/test_euler_tour.py +++ b/tests/test_euler_tour.py @@ -3,6 +3,7 @@ import itertools import unittest + class TestEuler(unittest.TestCase): def test_reroot(self): @@ -67,57 +68,6 @@ def test_link(self): edge = tuple([4,'c','d',5]) self.assertTrue(edge in x1._spares) - def test_cut(self): - # building tour 1,2,1,3,1 - x1 = EulerTour('x1',blist([1])) - x2 = EulerTour('x2',blist([2])) - edge = tuple([1,'a','b',2]) - x1.link(x2,edge) - edge = tuple([1,'c','d',2]) - x1.add_spare(edge) - x3 = EulerTour('x3',blist([3])) - edge = tuple([1,'a','b',3]) - x1.link(x3,edge) - - # cutting a tour edge when spare exists - edge = tuple([1,'a','b',2]) - cuts = x1.cut(edge) - self.assertTrue(len(cuts)==1) - x1 = cuts.pop() - self.assertEqual(x1._tour,[1,3,1,2,1]) - - # cutting a tour edge when no spare exists - edge = tuple([1,'a','b',3]) - cuts = x1.cut(edge) - self.assertTrue(len(cuts)==2) - x1,x2 = sorted(cuts,key=len,reverse=True) - self.assertEqual(x1._tour,[1,2,1]) - self.assertEqual(x2._tour,[3]) - - def test_eulertourindex(self): - ind = EulerTourIndex() - - x = EulerTour('x',blist([1,2,3,4,5,4,3,2,1])) - ind.add_tour(x,remap=True) - self.assertEqual(sorted(ind._tourmap.keys()),[1,2,3,4,5]) - for key in [1,2,3,4,5]: - self.assertEqual(ind.get_mapped_tour(key),x) - - x._tour = blist([1,2,3,2,1,6,7,6,1]) - ind.remap_nodes([6,7],x) - ind.remap_nodes([4,5]) - - self.assertEqual(sorted(ind._tourmap.keys()),[1,2,3,6,7]) - for key in [1,2,3,6,7]: - self.assertEqual(ind.get_mapped_tour(key),x) - - for i,j in itertools.combinations([1,2,3,6,7],2): - self.assertTrue(ind.is_connected([i,j])) - - ind.remove_tour(x,remap=True) - for key in range(10): - self.assertEqual(ind.get_mapped_tour(key),None) - def test_insert_delete(self): # sequentially build a tree 1,2,3,2,1 # with two spare edges 1,2 and 2,3 @@ -170,18 +120,3 @@ def test_insert_delete(self): self.assertEqual(len(values),1) x = list(values)[0] self.assertTrue(edge in x._spares) - - # deletion sequence - # delete 1,2 main edge - # should rework the tree using spare edge - # delete 2,3 spare edge - # should not change the tree - # delete 1,2 formerly spare edge - # 1 is now a singleton - # delete 1 - # delete 2,3 main edge - # should rework the tree using spare edge - # delete 2,3 formerly spare edge - # 2,3 are now singletons - # delete 2 - # delete 3 diff --git a/wc_rules/euler_tour.py b/wc_rules/euler_tour.py index 92b8a3e..f875738 100644 --- a/wc_rules/euler_tour.py +++ b/wc_rules/euler_tour.py @@ -61,7 +61,6 @@ def add_edge(self,edge): return self def remove_spare(self,spare): - print(self._spares,spare) self._spares.remove(spare) return self @@ -105,6 +104,7 @@ def link(self,other,edge): node1,_,_,node2 = edge if node1 not in self: node1,node2 = node2,node1 + print(node1,self._tour,node2,other._tour) self.reroot(node1) other.reroot(node2) self.extend_right(other._tour + [node1]) @@ -113,55 +113,6 @@ def link(self,other,edge): self._edges |= other._edges return self - def cut(self,edge): - node1,_,_,node2 = edge - self.reroot(node1) - x1 = self.first_occurrence(node2) - x2 = self.last_occurrence(node2)+1 - inner_tour = self._tour[x1:x2] - outer_tour = self._tour[:x1] + self._tour[x2+1:] - print(self._tour,inner_tour,outer_tour) - big_tour,small_tour = sorted([inner_tour,outer_tour],key=len,reverse=True) - print(self._tour,big_tour,small_tour) - big_nodes = set(big_tour) - small_nodes = set(small_tour) - print(self._tour,big_nodes,small_nodes) - - # is there a spare edge that can fuse them again? - mergeable = False - merge_edge = None - for e in self._spares: - n = set([e[0],e[3]]) - print(n<=big_nodes and n<=small_nodes) - if not (n<=big_nodes and n<=small_nodes): - mergeable=True - merge_edge = e - break - - print(mergeable) - print(merge_edge) - - if not mergeable: - # make two tour objects and return them - self.remove_edge(edge) - small_edges = set([x for x in self._edges if x[0] in small_nodes]) - big_edges = self._edges - small_edges - small_spares = set([x for x in self._spares if x[0] in small_nodes]) - big_spares = self._spares - small_spares - t1 = EulerTour(id=self.id,iterable=big_tour,edges=big_edges,spares=big_spares) - t2 = EulerTour(id=None,iterable=small_tour,edges=small_edges,spares=small_spares) - return [t1,t2] - - # make two tour objects, merge them and return them - self.remove_edge(edge) - self.remove_spare(merge_edge) - t1 = EulerTour(id=None,iterable=big_tour) - t2 = EulerTour(id=None,iterable=small_tour) - t1.link(t2,merge_edge) - self._tour = t1._tour - return [self] - - class EulerTourIndex(SetLike): def __init__(self): super().__init__() @@ -234,3 +185,5 @@ def insert_edge(self,edge): self.remove_tour(t2) self.remap_nodes(t2.get_nodes(),t1) return self + +