Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
py3: caring for Schnyder woods
Browse files Browse the repository at this point in the history
  • Loading branch information
Frédéric Chapoton committed Dec 19, 2018
1 parent 9dde00f commit 87cdeb7
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 74 deletions.
60 changes: 30 additions & 30 deletions src/sage/combinat/interval_posets.py
Original file line number Diff line number Diff line change
Expand Up @@ -3289,10 +3289,10 @@ def from_minimal_schnyder_wood(graph):
a minimal Schnyder wood, given as a graph with colored and
oriented edges, without the three exterior unoriented edges
The three boundary vertices must be 'a', 'b' and 'c'.
The three boundary vertices must be -1, -2 and -3.
One assumes moreover that the embedding around 'a' is the
list of neighbors of 'a' and not just a cyclic permutation of that.
One assumes moreover that the embedding around -1 is the
list of neighbors of -1 and not just a cyclic permutation of that.
Beware that the embedding convention used here is the opposite of
the one used by the plot method.
Expand All @@ -3306,23 +3306,23 @@ def from_minimal_schnyder_wood(graph):
A small example::
sage: TIP = TamariIntervalPosets
sage: G = DiGraph([(0,'a',0),(0,'b',1),(0,'c',2)], format='list_of_edges')
sage: G.set_embedding({'a':[0],'b':[0],'c':[0],0:['a','b','c']})
sage: G = DiGraph([(0,-1,0),(0,-2,1),(0,-3,2)], format='list_of_edges')
sage: G.set_embedding({-1:[0],-2:[0],-3:[0],0:[-1,-2,-3]})
sage: TIP.from_minimal_schnyder_wood(G)
The Tamari interval of size 1 induced by relations []
An example from page 14 of [BeBo2009]_::
sage: c0 = [(0,'a'),(1,0),(2,0),(4,3),(3,'a'),(5,3)]
sage: c1 = [(5,'b'),(3,'b'),(4,5),(1,3),(2,3),(0,3)]
sage: c2 = [(0,'c'),(1,'c'),(3,'c'),(4,'c'),(5,'c'),(2,1)]
sage: c0 = [(0,-1),(1,0),(2,0),(4,3),(3,-1),(5,3)]
sage: c1 = [(5,-2),(3,-2),(4,5),(1,3),(2,3),(0,3)]
sage: c2 = [(0,-3),(1,-3),(3,-3),(4,-3),(5,-3),(2,1)]
sage: ed = [(u,v,0) for u,v in c0]
sage: ed += [(u,v,1) for u,v in c1]
sage: ed += [(u,v,2) for u,v in c2]
sage: G = DiGraph(ed, format='list_of_edges')
sage: embed = {'a':[3,0],'b':[5,3],'c':[0,1,3,4,5]}
sage: data_emb = [[3,2,1,'c','a'],[2,3,'c',0],[3,1,0]]
sage: data_emb += [['b',5,4,'c',1,2,0,'a'],[5,'c',3],['b','c',4,3]]
sage: embed = {-1:[3,0],-2:[5,3],-3:[0,1,3,4,5]}
sage: data_emb = [[3,2,1,-3,-1],[2,3,-3,0],[3,1,0]]
sage: data_emb += [[-2,5,4,-3,1,2,0,-1],[5,-3,3],[-2,-3,4,3]]
sage: for k in range(6):
....: embed[k] = data_emb[k]
sage: G.set_embedding(embed)
Expand All @@ -3331,16 +3331,16 @@ def from_minimal_schnyder_wood(graph):
An example from page 18 of [BeBo2009]_::
sage: c0 = [(0,'a'),(1,0),(2,'a'),(3,2),(4,2),(5,'a')]
sage: c1 = [(5,'b'),(2,'b'),(4,'b'),(3,4),(1,2),(0,2)]
sage: c2 = [(0,'c'),(1,'c'),(3,'c'),(4,'c'),(2,'c'),(5,2)]
sage: c0 = [(0,-1),(1,0),(2,-1),(3,2),(4,2),(5,-1)]
sage: c1 = [(5,-2),(2,-2),(4,-2),(3,4),(1,2),(0,2)]
sage: c2 = [(0,-3),(1,-3),(3,-3),(4,-3),(2,-3),(5,2)]
sage: ed = [(u,v,0) for u,v in c0]
sage: ed += [(u,v,1) for u,v in c1]
sage: ed += [(u,v,2) for u,v in c2]
sage: G = DiGraph(ed, format='list_of_edges')
sage: embed = {'a':[5,2,0],'b':[4,2,5],'c':[0,1,2,3,4]}
sage: data_emb = [[2,1,'c','a'],[2,'c',0],[3,'c',1,0,'a',5,'b',4]]
sage: data_emb += [[4,'c',2],['b','c',3,2],['b',2,'a']]
sage: embed = {-1:[5,2,0],-2:[4,2,5],-3:[0,1,2,3,4]}
sage: data_emb = [[2,1,-3,-1],[2,-3,0],[3,-3,1,0,-1,5,-2,4]]
sage: data_emb += [[4,-3,2],[-2,-3,3,2],[-2,2,-1]]
sage: for k in range(6):
....: embed[k] = data_emb[k]
sage: G.set_embedding(embed)
Expand All @@ -3349,15 +3349,15 @@ def from_minimal_schnyder_wood(graph):
Another small example::
sage: c0 = [(0,'a'),(2,'a'),(1,0)]
sage: c1 = [(2,'b'),(1,'b'),(0,2)]
sage: c2 = [(0,'c'),(1,'c'),(2,1)]
sage: c0 = [(0,-1),(2,-1),(1,0)]
sage: c1 = [(2,-2),(1,-2),(0,2)]
sage: c2 = [(0,-3),(1,-3),(2,1)]
sage: ed = [(u,v,0) for u,v in c0]
sage: ed += [(u,v,1) for u,v in c1]
sage: ed += [(u,v,2) for u,v in c2]
sage: G = DiGraph(ed, format='list_of_edges')
sage: embed = {'a':[2,0],'b':[1,2],'c':[0,1]}
sage: data_emb = [[2,1,'c','a'],['c',0,2,'b'],['b',1,0,'a']]
sage: embed = {-1:[2,0],-2:[1,2],-3:[0,1]}
sage: data_emb = [[2,1,-3,-1],[-3,0,2,-2],[-2,1,0,-1]]
sage: for k in range(3):
....: embed[k] = data_emb[k]
sage: G.set_embedding(embed)
Expand All @@ -3366,8 +3366,8 @@ def from_minimal_schnyder_wood(graph):
"""
from sage.graphs.digraph import DiGraph
from sage.combinat.dyck_word import DyckWord
color_a = graph.incoming_edges('a')[0][2]
color_b = graph.incoming_edges('b')[0][2]
color_a = graph.incoming_edges(-1)[0][2]
color_b = graph.incoming_edges(-2)[0][2]

embedding = graph.get_embedding()
graph0 = DiGraph([e for e in graph.edges(sort=False)
Expand All @@ -3380,7 +3380,7 @@ def from_minimal_schnyder_wood(graph):

voisins_in = {}
for u in graph0:
if u != 'a':
if u != -1:
bad_emb = restricted_embedding[u]
sortie = graph0.neighbors_out(u)[0]
idx = bad_emb.index(sortie)
Expand Down Expand Up @@ -3410,12 +3410,12 @@ def profil(gr, vertex):
lbl += [1] + profil(gr, w) + [0]
return lbl

dyckword_bottom = profil(graph0, 'a')
dyckword_bottom = profil(graph0, -1)
# this is the profile of the planar graph graph0

liste = clockwise_labelling(graph0, 'a')[1:]
liste = clockwise_labelling(graph0, -1)[1:]
relabelling = {l: i for i, l in enumerate(liste)}
for l in ['a', 'b', 'c']:
for l in [-1, -2, -3]:
relabelling[l] = l
new_graph = graph.relabel(relabelling, inplace=False)

Expand All @@ -3424,7 +3424,7 @@ def profil(gr, vertex):
indegree1 = len([u for u in new_graph.incoming_edges(i)
if u[2] == color_b])
dyckword_top += [1] + [0] * indegree1
indegree1 = len([u for u in new_graph.incoming_edges('b')
indegree1 = len([u for u in new_graph.incoming_edges(-2)
if u[2] == color_b])
dyckword_top += [1] + [0] * indegree1

Expand Down Expand Up @@ -3736,7 +3736,7 @@ def random_element(self):
n = self._size
tri = RandomTriangulation(n + 3)
TIP = TamariIntervalPosets
schnyder = minimal_schnyder_wood(tri, root_edge=('a', 'b'),
schnyder = minimal_schnyder_wood(tri, root_edge=(-1, -2),
check=False)
return TIP.from_minimal_schnyder_wood(schnyder)

Expand Down
24 changes: 13 additions & 11 deletions src/sage/graphs/generators/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -1794,37 +1794,39 @@ def rotate_word_to_next_occurrence(word):
graph.add_edges(edges)
# This is the end of partial closure.

# There remains to add two new vertices 'a' and 'b'.
graph.add_edge(('a', 'b'))
# There remains to add two new vertices a and b.
a = -1
b = -2
graph.add_edge((a, b))

# Every remaining 'lf' vertex is linked either to 'a' or to 'b'.
# Every remaining 'lf' vertex is linked either to a or to b.
# Switching a/b happens when one meets the sequence 'lf','in','lf'.
a_or_b = 'a'
embedding['a'] = []
embedding['b'] = []
a_or_b = a
embedding[a] = []
embedding[b] = []
last_lf_occurrence = -42
change = {}
for x in word:
last_lf_occurrence -= 1
if x[0] == 'lf':
if last_lf_occurrence == -2:
change[a_or_b] = x[1]
a_or_b = 'b' if a_or_b == 'a' else 'a'
a_or_b = b if a_or_b == a else a
graph.add_edge((a_or_b, x[1]))
embedding[a_or_b].insert(0, x[1])
last_lf_occurrence = 0

# conjugates the embeddings of a and b
# in a way that helps to complete the embedding
for a_or_b in ['a', 'b']:
for a_or_b in [a, b]:
emba = embedding[a_or_b]
idx = emba.index(change[a_or_b])
embedding[a_or_b] = emba[idx:] + emba[:idx]
embedding['a'].append('b')
embedding['b'].append('a')
embedding[a].append(b)
embedding[b].append(a)

# completes the embedding by inserting missing half-edges
for a_or_b in ['a', 'b']:
for a_or_b in [a, b]:
emb = embedding[a_or_b]
for i, v in enumerate(emb[:-1]):
if i == 0:
Expand Down
66 changes: 33 additions & 33 deletions src/sage/graphs/schnyder.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
REFERENCE:
.. [1] Schnyder, Walter. Embedding Planar Graphs on the Grid.
.. [1] Schnyder, Walter. *Embedding Planar Graphs on the Grid*.
Proc. 1st Annual ACM-SIAM Symposium on Discrete Algorithms,
San Francisco (1994), pp. 138-147.
"""
# ****************************************************************************
# Copyright (C) 2008 Jonathan Bober and Emily Kirkman
#
# Distributed under the terms of the GNU General Public License (GPL)
# http://www.gnu.org/licenses/
# https://www.gnu.org/licenses/
# ****************************************************************************
from __future__ import absolute_import

Expand Down Expand Up @@ -690,9 +690,9 @@ def minimal_schnyder_wood(graph, root_edge=None, minimal=True, check=True):
- graph -- a planar triangulation, given by a graph with an embedding.
- root_edge -- a pair of vertices (default is from ``'a'`` to ``'b'``)
- root_edge -- a pair of vertices (default is from ``-1`` to ``-2``)
The third boundary vertex is then determined using the orientation and
will be labelled ``'c'``.
will be labelled ``-3``.
- minimal -- boolean (default ``True``), whether to return a
minimal or a maximal Schnyder wood.
Expand All @@ -710,45 +710,45 @@ def minimal_schnyder_wood(graph, root_edge=None, minimal=True, check=True):
EXAMPLES::
sage: from sage.graphs.schnyder import minimal_schnyder_wood
sage: g = Graph([(0,'a'),(0,'b'),(0,'c'),('a','b'),('b','c'),
....: ('c','a')], format='list_of_edges')
sage: g.set_embedding({'a':['b',0,'c'],'b':['c',0,'a'],
....: 'c':['a',0,'b'],0:['a','b','c']})
sage: g = Graph([(0,-1),(0,-2),(0,-3),(-1,-2),(-2,-3),
....: (-3,-1)], format='list_of_edges')
sage: g.set_embedding({-1:[-2,0,-3],-2:[-3,0,-1],
....: -3:[-1,0,-2],0:[-1,-2,-3]})
sage: newg = minimal_schnyder_wood(g)
sage: newg.edges()
[(0, 'a', 'green'), (0, 'b', 'blue'), (0, 'c', 'red')]
[(0, -3, 'red'), (0, -2, 'blue'), (0, -1, 'green')]
sage: newg.plot(color_by_label={'red':'red','blue':'blue',
....: 'green':'green',None:'black'})
Graphics object consisting of 8 graphics primitives
A larger example::
sage: g = Graph([(0,'a'),(0,2),(0,1),(0,'c'),('a','c'),('a',2),
....: ('a','b'),(1,2),(1,'c'),(2,'b'),(1,'b'),('b','c')], format='list_of_edges')
sage: g.set_embedding({'a':['b',2,0,'c'],'b':['c',1,2,'a'],
....: 'c':['a',0,1,'b'],0:['a',2,1,'c'],1:['b','c',0,2],2:['a','b',1,0]})
sage: g = Graph([(0,-1),(0,2),(0,1),(0,-3),(-1,-3),(-1,2),
....: (-1,-2),(1,2),(1,-3),(2,-2),(1,-2),(-2,-3)], format='list_of_edges')
sage: g.set_embedding({-1:[-2,2,0,-3],-2:[-3,1,2,-1],
....: -3:[-1,0,1,-2],0:[-1,2,1,-3],1:[-2,-3,0,2],2:[-1,-2,1,0]})
sage: newg = minimal_schnyder_wood(g)
sage: sorted(newg.edges(), key=lambda e:(str(e[0]),str(e[1])))
[(0, 2, 'blue'),
(0, 'a', 'green'),
(0, 'c', 'red'),
[(0, -1, 'green'),
(0, -3, 'red'),
(0, 2, 'blue'),
(1, -2, 'blue'),
(1, -3, 'red'),
(1, 0, 'green'),
(1, 'b', 'blue'),
(1, 'c', 'red'),
(2, 1, 'red'),
(2, 'a', 'green'),
(2, 'b', 'blue')]
(2, -1, 'green'),
(2, -2, 'blue'),
(2, 1, 'red')]
sage: newg2 = minimal_schnyder_wood(g, minimal=False)
sage: sorted(newg2.edges(), key=lambda e:(str(e[0]),str(e[1])))
[(0, 1, 'blue'),
(0, 'a', 'green'),
(0, 'c', 'red'),
[(0, -1, 'green'),
(0, -3, 'red'),
(0, 1, 'blue'),
(1, -2, 'blue'),
(1, -3, 'red'),
(1, 2, 'green'),
(1, 'b', 'blue'),
(1, 'c', 'red'),
(2, 0, 'red'),
(2, 'a', 'green'),
(2, 'b', 'blue')]
(2, -1, 'green'),
(2, -2, 'blue'),
(2, 0, 'red')]
TESTS::
Expand All @@ -773,8 +773,8 @@ def minimal_schnyder_wood(graph, root_edge=None, minimal=True, check=True):
3-Tree-Decompositions*, 2000
"""
if root_edge is None:
a = 'a'
b = 'b'
a = -1
b = -2
else:
a, b = root_edge

Expand All @@ -797,7 +797,7 @@ def minimal_schnyder_wood(graph, root_edge=None, minimal=True, check=True):
# initialisation
for i in emb[c]:
if i != a and i != b:
new_g.add_edge((i, 'c', 'red'))
new_g.add_edge((i, -3, 'red'))

path = list(emb[c])
idxa = path.index(a)
Expand Down Expand Up @@ -836,7 +836,7 @@ def minimal_schnyder_wood(graph, root_edge=None, minimal=True, check=True):
u != a and u != b]

def relabel(w):
return 'c' if w == c else w
return -3 if w == c else w

emb = {relabel(v): [relabel(u) for u in emb[v] if not(u in [a, b, c] and
v in [a, b, c])]
Expand Down

0 comments on commit 87cdeb7

Please sign in to comment.