# HG changeset patch
# User Ryan Hinton on appserv <iobass@email.com>
# Date 1267046028 18000
# Node ID ee171a17915c57d25c2099a96bd36daa4dff7917
# Parent 987aa9ced6d3ea70d60aea56b734f8000d73c54f
switch .left and .right members from lists to sets
diff -r 987aa9ced6d3 -r ee171a17915c sage/graphs/bipartite_graph.py
a
|
b
|
|
77 | 77 | sage: B == G |
78 | 78 | True |
79 | 79 | sage: B.left |
80 | | [0, 1, 2, 3] |
| 80 | set([0, 1, 2, 3]) |
81 | 81 | sage: B.right |
82 | | [4, 5, 6] |
| 82 | set([4, 5, 6]) |
83 | 83 | sage: B = BipartiteGraph({0:[5,6], 1:[4,5], 2:[4,6], 3:[4,5,6]}) |
84 | 84 | sage: B == G |
85 | 85 | True |
86 | 86 | sage: B.left |
87 | | [0, 1, 2, 3] |
| 87 | set([0, 1, 2, 3]) |
88 | 88 | sage: B.right |
89 | | [4, 5, 6] |
| 89 | set([4, 5, 6]) |
90 | 90 | |
91 | 91 | 3. From a graph and a partition. Note that if the input graph is not |
92 | 92 | bipartite, then Sage will raise an error. However, if one specifies check = |
… |
… |
|
103 | 103 | |
104 | 104 | sage: B = BipartiteGraph(P, partition, check=False) |
105 | 105 | sage: B.left |
106 | | [0, 1, 2, 3, 4] |
| 106 | set([0, 1, 2, 3, 4]) |
107 | 107 | sage: B.show() |
108 | 108 | |
109 | 109 | :: |
… |
… |
|
219 | 219 | """ |
220 | 220 | if len(args) == 0: |
221 | 221 | Graph.__init__(self) |
222 | | self.left = []; self.right = [] |
| 222 | self.left = set(); self.right = set() |
223 | 223 | return |
224 | 224 | arg1 = args[0] |
225 | 225 | args = args[1:] |
226 | 226 | from sage.structure.element import is_Matrix |
227 | 227 | if isinstance(arg1, BipartiteGraph): |
228 | 228 | Graph.__init__(self, arg1, *args, **kwds) |
229 | | self.left, self.right = arg1.left, arg1.right |
| 229 | self.left, self.right = set(arg1.left), set(arg1.right) |
230 | 230 | elif isinstance(arg1, str): |
231 | 231 | Graph.__init__(self, *args, **kwds) |
232 | 232 | self.load_afile(arg1) |
… |
… |
|
237 | 237 | Graph.__init__(self, *args, **kwds) |
238 | 238 | ncols = arg1.ncols() |
239 | 239 | nrows = arg1.nrows() |
240 | | self.left, self.right = range(ncols), range(ncols, nrows+ncols) |
| 240 | self.left, self.right = set(xrange(ncols)), set(xrange(ncols, nrows+ncols)) |
241 | 241 | if kwds.get('multiedges',False): |
242 | 242 | for ii in range(ncols): |
243 | 243 | for jj in range(nrows): |
… |
… |
|
285 | 285 | a_nbrs = set( arg1.neighbors(a) ) & set(right) |
286 | 286 | if len( a_nbrs ) != 0: |
287 | 287 | self.delete_edges([(a, b) for b in a_nbrs]) |
288 | | self.left, self.right = copy(args[0][0]), copy(args[0][1]) |
| 288 | self.left, self.right = set(args[0][0]), set(args[0][1]) |
289 | 289 | elif isinstance(arg1, Graph): |
290 | 290 | try: |
291 | 291 | Graph.__init__(self, arg1, *args, **kwds) |
… |
… |
|
299 | 299 | if isinstance(arg1, (networkx.XGraph, networkx.Graph)): |
300 | 300 | if hasattr(arg1, 'node_type'): |
301 | 301 | # Assume the graph is bipartite |
302 | | self.left = [] |
303 | | self.right = [] |
| 302 | self.left = set() |
| 303 | self.right = set() |
304 | 304 | for v in arg1.nodes_iter(): |
305 | 305 | if arg1.node_type[v] == 'Bottom': |
306 | | self.left.append(v) |
| 306 | self.left.add(v) |
307 | 307 | elif arg1.node_type[v] == 'Top': |
308 | | self.right.append(v) |
| 308 | self.right.add(v) |
309 | 309 | else: |
310 | 310 | raise TypeError("NetworkX node_type defies bipartite assumption (is not 'Top' or 'Bottom')") |
311 | 311 | # make sure we found a bipartition |
… |
… |
|
338 | 338 | EXAMPLE: |
339 | 339 | sage: B = BipartiteGraph( graphs.CycleGraph(4) ) |
340 | 340 | sage: B.bipartition() |
341 | | ([0, 2], [1, 3]) |
| 341 | (set([0, 2]), set([1, 3])) |
342 | 342 | |
343 | 343 | """ |
344 | 344 | return (self.left, self.right) |
… |
… |
|
395 | 395 | kwds['pos'] = None |
396 | 396 | if kwds['pos'] is None: |
397 | 397 | pos = {} |
| 398 | left = list(self.left) |
| 399 | right = list(self.right) |
| 400 | left.sort() |
| 401 | right.sort() |
398 | 402 | l_len = len(self.left) |
399 | 403 | r_len = len(self.right) |
400 | 404 | if l_len == 1: |
401 | | pos[self.left[0]] = [-1, 0] |
| 405 | pos[left[0]] = [-1, 0] |
402 | 406 | elif l_len > 1: |
403 | 407 | i = 0 |
404 | 408 | d = 2./(l_len-1) |
405 | | for v in self.left: |
| 409 | for v in left: |
406 | 410 | pos[v] = [-1, 1-i*d] |
407 | 411 | i += 1 |
408 | 412 | if r_len == 1: |
409 | | pos[self.right[0]] = [1, 0] |
| 413 | pos[right[0]] = [1, 0] |
410 | 414 | elif r_len > 1: |
411 | 415 | i = 0 |
412 | 416 | d = 2./(r_len-1) |
413 | | for v in self.right: |
| 417 | for v in right: |
414 | 418 | pos[v] = [1, 1-i*d] |
415 | 419 | i += 1 |
416 | 420 | kwds['pos'] = pos |
… |
… |
|
492 | 496 | #NOTE:: we could check the actual node degrees against the reported node degrees.... |
493 | 497 | |
494 | 498 | # now we have all the edges in our graph, just fill in the bipartite partitioning |
495 | | self.left = list(range(num_cols)) |
496 | | self.right = list(range(num_cols, num_cols + num_rows)) |
| 499 | self.left = set(xrange(num_cols)) |
| 500 | self.right = set(xrange(num_cols, num_cols + num_rows)) |
497 | 501 | |
498 | 502 | # return self for chaining calls if desired |
499 | 503 | return self |
… |
… |
|
552 | 556 | return |
553 | 557 | |
554 | 558 | # prep: handy lists, functions for extracting adjacent nodes |
555 | | vnodes = self.left |
556 | | cnodes = self.right |
| 559 | vnodes = list(self.left) |
| 560 | cnodes = list(self.right) |
| 561 | vnodes.sort() |
| 562 | cnodes.sort() |
557 | 563 | max_vdeg = max(self.degree(vnodes)) |
558 | 564 | max_cdeg = max(self.degree(cnodes)) |
559 | 565 | num_vnodes = len(vnodes) |
… |
… |
|
580 | 586 | # return self for chaining calls if desired |
581 | 587 | return |
582 | 588 | |
583 | | def __edge2idx(self, v1, v2): |
| 589 | def __edge2idx(self, v1, v2, left, right): |
584 | 590 | r""" |
585 | 591 | Translate an edge to its reduced adjacency matrix position. |
586 | 592 | |
… |
… |
|
590 | 596 | sage: P = graphs.PetersenGraph() |
591 | 597 | sage: partition = [range(5), range(5,10)] |
592 | 598 | sage: B = BipartiteGraph(P, partition, check=False) |
593 | | sage: B._BipartiteGraph__edge2idx(2,7) |
| 599 | sage: B._BipartiteGraph__edge2idx(2,7,range(5),range(5,10)) |
594 | 600 | (2, 2) |
595 | 601 | |
596 | 602 | """ |
597 | 603 | try: |
598 | | if v1 in self.left: |
599 | | return (self.right.index(v2), self.left.index(v1)) |
| 604 | if v1 in self.left: # note uses attribute for faster lookup |
| 605 | return (right.index(v2), left.index(v1)) |
600 | 606 | else: |
601 | | return (self.right.index(v1), self.left.index(v2)) |
| 607 | return (right.index(v1), left.index(v2)) |
602 | 608 | except ValueError: |
603 | 609 | raise ValueError("Tried to map invalid edge (%d,%d) to vertex indices" \ |
604 | 610 | % (v1, v2)) |
… |
… |
|
670 | 676 | if self.is_directed(): |
671 | 677 | raise NotImplementedError, "Reduced adjacency matrix does not exist for directed graphs." |
672 | 678 | |
| 679 | # create sorted lists of left and right edges |
| 680 | left = list(self.left) |
| 681 | right = list(self.right) |
| 682 | left.sort() |
| 683 | right.sort() |
| 684 | |
673 | 685 | # create dictionary of edges, values are weights for weighted graph, |
674 | 686 | # otherwise the number of edges (always 1 for simple graphs) |
675 | 687 | D = {} |
676 | 688 | if self.weighted(): |
677 | 689 | for (v1, v2, weight) in self.edge_iterator(): |
678 | | D[self.__edge2idx(v1,v2)] = weight |
| 690 | D[self.__edge2idx(v1, v2, left, right)] = weight |
679 | 691 | else: |
680 | 692 | # if we're normal or multi-edge, just create the matrix over ZZ |
681 | 693 | for (v1, v2, name) in self.edge_iterator(): |
682 | | idx = self.__edge2idx(v1, v2) |
| 694 | idx = self.__edge2idx(v1, v2, left, right) |
683 | 695 | if D.has_key(idx): |
684 | 696 | D[idx] = 1 + D[idx] |
685 | 697 | else: |
diff -r 987aa9ced6d3 -r ee171a17915c sage/graphs/graph.py
a
|
b
|
|
1601 | 1601 | EXAMPLES:: |
1602 | 1602 | |
1603 | 1603 | sage: graphs.CycleGraph(4).bipartite_sets() |
1604 | | ([0, 2], [1, 3]) |
| 1604 | (set([0, 2]), set([1, 3])) |
1605 | 1605 | sage: graphs.CycleGraph(5).bipartite_sets() |
1606 | 1606 | Traceback (most recent call last): |
1607 | 1607 | ... |
1608 | 1608 | RuntimeError: Graph is not bipartite. |
1609 | 1609 | """ |
1610 | 1610 | color = self.bipartite_color() |
1611 | | left = [v for v in color if color[v] == 1] |
1612 | | right = [v for v in color if color[v] == 0] |
| 1611 | left = set([v for v in color if color[v] == 1]) |
| 1612 | right = set([v for v in color if color[v] == 0]) |
1613 | 1613 | return (left, right) |
1614 | 1614 | |
1615 | 1615 | def chromatic_polynomial(self): |