Ticket #8421: trac_8421-bipartite-partition-sets.patch

File trac_8421-bipartite-partition-sets.patch, 8.8 KB (added by rhinton, 12 years ago)

updated commit message

  • sage/graphs/bipartite_graph.py

    # 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  
    7777        sage: B == G
    7878        True
    7979        sage: B.left
    80         [0, 1, 2, 3]
     80        set([0, 1, 2, 3])
    8181        sage: B.right
    82         [4, 5, 6]
     82        set([4, 5, 6])
    8383        sage: B = BipartiteGraph({0:[5,6], 1:[4,5], 2:[4,6], 3:[4,5,6]})
    8484        sage: B == G
    8585        True
    8686        sage: B.left
    87         [0, 1, 2, 3]
     87        set([0, 1, 2, 3])
    8888        sage: B.right
    89         [4, 5, 6]
     89        set([4, 5, 6])
    9090
    9191    3. From a graph and a partition. Note that if the input graph is not
    9292    bipartite, then Sage will raise an error. However, if one specifies check =
     
    103103
    104104        sage: B = BipartiteGraph(P, partition, check=False)
    105105        sage: B.left
    106         [0, 1, 2, 3, 4]
     106        set([0, 1, 2, 3, 4])
    107107        sage: B.show()
    108108
    109109    ::
     
    219219        """
    220220        if len(args) == 0:
    221221            Graph.__init__(self)
    222             self.left = []; self.right = []
     222            self.left = set(); self.right = set()
    223223            return
    224224        arg1 = args[0]
    225225        args = args[1:]
    226226        from sage.structure.element import is_Matrix
    227227        if isinstance(arg1, BipartiteGraph):
    228228            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)
    230230        elif isinstance(arg1, str):
    231231            Graph.__init__(self, *args, **kwds)
    232232            self.load_afile(arg1)
     
    237237            Graph.__init__(self, *args, **kwds)
    238238            ncols = arg1.ncols()
    239239            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))
    241241            if kwds.get('multiedges',False):
    242242                for ii in range(ncols):
    243243                    for jj in range(nrows):
     
    285285                        a_nbrs = set( arg1.neighbors(a) ) & set(right)
    286286                        if len( a_nbrs ) != 0:
    287287                            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])
    289289        elif isinstance(arg1, Graph):
    290290            try:
    291291                Graph.__init__(self, arg1, *args, **kwds)
     
    299299            if isinstance(arg1, (networkx.XGraph, networkx.Graph)):
    300300                if hasattr(arg1, 'node_type'):
    301301                    # Assume the graph is bipartite
    302                     self.left = []
    303                     self.right = []
     302                    self.left = set()
     303                    self.right = set()
    304304                    for v in arg1.nodes_iter():
    305305                        if arg1.node_type[v] == 'Bottom':
    306                             self.left.append(v)
     306                            self.left.add(v)
    307307                        elif arg1.node_type[v] == 'Top':
    308                             self.right.append(v)
     308                            self.right.add(v)
    309309                        else:
    310310                            raise TypeError("NetworkX node_type defies bipartite assumption (is not 'Top' or 'Bottom')")
    311311            # make sure we found a bipartition
     
    338338        EXAMPLE:
    339339            sage: B = BipartiteGraph( graphs.CycleGraph(4) )
    340340            sage: B.bipartition()
    341             ([0, 2], [1, 3])
     341            (set([0, 2]), set([1, 3]))
    342342
    343343        """
    344344        return (self.left, self.right)
     
    395395            kwds['pos'] = None
    396396        if kwds['pos'] is None:
    397397            pos = {}
     398            left = list(self.left)
     399            right = list(self.right)
     400            left.sort()
     401            right.sort()
    398402            l_len = len(self.left)
    399403            r_len = len(self.right)
    400404            if l_len == 1:
    401                 pos[self.left[0]] = [-1, 0]
     405                pos[left[0]] = [-1, 0]
    402406            elif l_len > 1:
    403407                i = 0
    404408                d = 2./(l_len-1)
    405                 for v in self.left:
     409                for v in left:
    406410                    pos[v] = [-1, 1-i*d]
    407411                    i += 1
    408412            if r_len == 1:
    409                 pos[self.right[0]] = [1, 0]
     413                pos[right[0]] = [1, 0]
    410414            elif r_len > 1:
    411415                i = 0
    412416                d = 2./(r_len-1)
    413                 for v in self.right:
     417                for v in right:
    414418                    pos[v] = [1, 1-i*d]
    415419                    i += 1
    416420            kwds['pos'] = pos
     
    492496        #NOTE:: we could check the actual node degrees against the reported node degrees....
    493497
    494498        # 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))
    497501
    498502        # return self for chaining calls if desired
    499503        return self
     
    552556            return
    553557
    554558        # 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()
    557563        max_vdeg = max(self.degree(vnodes))
    558564        max_cdeg = max(self.degree(cnodes))
    559565        num_vnodes = len(vnodes)
     
    580586        # return self for chaining calls if desired
    581587        return
    582588
    583     def __edge2idx(self, v1, v2):
     589    def __edge2idx(self, v1, v2, left, right):
    584590        r"""
    585591        Translate an edge to its reduced adjacency matrix position.
    586592
     
    590596            sage: P = graphs.PetersenGraph()
    591597            sage: partition = [range(5), range(5,10)]
    592598            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))
    594600            (2, 2)
    595601
    596602        """
    597603        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))
    600606            else:
    601                 return (self.right.index(v1), self.left.index(v2))
     607                return (right.index(v1), left.index(v2))
    602608        except ValueError:
    603609            raise ValueError("Tried to map invalid edge (%d,%d) to vertex indices" \
    604610                                 % (v1, v2))
     
    670676        if self.is_directed():
    671677            raise NotImplementedError, "Reduced adjacency matrix does not exist for directed graphs."
    672678
     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
    673685        # create dictionary of edges, values are weights for weighted graph,
    674686        # otherwise the number of edges (always 1 for simple graphs)
    675687        D = {}
    676688        if self.weighted():
    677689            for (v1, v2, weight) in self.edge_iterator():
    678                 D[self.__edge2idx(v1,v2)] = weight
     690                D[self.__edge2idx(v1, v2, left, right)] = weight
    679691        else:
    680692            # if we're normal or multi-edge, just create the matrix over ZZ
    681693            for (v1, v2, name) in self.edge_iterator():
    682                 idx = self.__edge2idx(v1, v2)
     694                idx = self.__edge2idx(v1, v2, left, right)
    683695                if D.has_key(idx):
    684696                    D[idx] = 1 + D[idx]
    685697                else:
  • sage/graphs/graph.py

    diff -r 987aa9ced6d3 -r ee171a17915c sage/graphs/graph.py
    a b  
    16011601        EXAMPLES::
    16021602       
    16031603            sage: graphs.CycleGraph(4).bipartite_sets()
    1604             ([0, 2], [1, 3])
     1604            (set([0, 2]), set([1, 3]))
    16051605            sage: graphs.CycleGraph(5).bipartite_sets()
    16061606            Traceback (most recent call last):
    16071607            ...
    16081608            RuntimeError: Graph is not bipartite.
    16091609        """
    16101610        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])
    16131613        return (left, right)
    16141614
    16151615    def chromatic_polynomial(self):