~ubuntu-branches/ubuntu/raring/python-networkx/raring

« back to all changes in this revision

Viewing changes to networkx/utils.py

  • Committer: Bazaar Package Importer
  • Author(s): Cyril Brulebois
  • Date: 2009-11-23 15:44:34 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20091123154434-ellm2ut3a4edf9wh
Tags: 1.0~rc1~svn1492-1
* New upstream snapshot, past 1.0~rc1, as requested by Yaroslav
  Halchenko (Closes: #549996).
* Refresh patch accordingly:
   + debian/patches/10_doc_relocation.
* Get rid of extra LICENSE.txt file in /usr/share/doc.
* Use dh_compress -Xexamples/ to avoid compressing examples, thanks to
  Sandro Tosi (Closes: #539942).
* Bump Standards-Version from 3.8.0 to 3.8.3 (no changes needed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
"""
2
 
Utilities for networkx package
 
2
*********
 
3
Utilities
 
4
*********
 
5
 
 
6
Helpers for NetworkX.
 
7
 
 
8
These are not imported into the base networkx namespace but
 
9
can be accessed, for example, as
 
10
 
 
11
>>> import networkx
 
12
>>> networkx.utils.is_string_like('spam')
 
13
True
3
14
 
4
15
"""
5
16
__author__ = """Aric Hagberg (hagberg@lanl.gov)\nDan Schult(dschult@colgate.edu)"""
7
18
#    Aric Hagberg <hagberg@lanl.gov>
8
19
#    Dan Schult <dschult@colgate.edu>
9
20
#    Pieter Swart <swart@lanl.gov>
10
 
#    Distributed under the terms of the GNU Lesser General Public License
11
 
#    http://www.gnu.org/copyleft/lesser.html
 
21
#    All rights reserved.
 
22
#    BSD license.
12
23
import random
13
24
 
14
25
### some cookbook stuff
16
27
# used in deciding whether something is a bunch of nodes, edges, etc.
17
28
# see G.add_nodes and others in Graph Class in networkx/base.py
18
29
def is_singleton(obj):
19
 
    """ Is string_like or not iterable. """
 
30
    """Is string_like or not iterable."""
20
31
    return hasattr(obj,"capitalize") or not hasattr(obj,"__iter__")
21
32
 
22
33
def is_string_like(obj): # from John Hunter, types-free version
31
42
 
32
43
 
33
44
def iterable(obj):
34
 
    """ Return True if obj is iterable with a well-defined len()  """
 
45
    """ Return True if obj is iterable with a well-defined len()"""
35
46
    if hasattr(obj,"__iter__"): return True
36
47
    try:
37
48
        len(obj)
40
51
    return True
41
52
 
42
53
def flatten(obj, result=None):
43
 
    """ Return flattened version of (possibly nested) iterable obj. """
 
54
    """ Return flattened version of (possibly nested) iterable object. """
44
55
    if not iterable(obj) or is_string_like(obj):
45
56
        return obj
46
57
    if result is None:
52
63
            flatten(item, result)
53
64
    return obj.__class__(result)
54
65
 
55
 
def iterable_to_string(obj, sep=''):
56
 
    """
57
 
    Return string obtained by concatenating the string representation
58
 
    of each element of an iterable obj, with an optional internal string
59
 
    separator specified.
60
 
    """
61
 
    if not iterable(obj):
62
 
        return str(obj)
63
 
    return sep.join([str(i) for i in obj])
64
 
 
65
66
def is_list_of_ints( intlist ):
66
67
    """ Return True if list is a list of ints. """
67
68
    if not isinstance(intlist,list): return False
198
199
    return seq
199
200
 
200
201
 
201
 
# some helpers for choosing random sequences from distributions
202
 
# uses pygsl: pygsl.sourceforge.org, but not all its functionality.
203
 
# note: gsl's default number generator is the same as Python's
204
 
# (Mersenne Twister)
205
 
 
206
 
def gsl_pareto_sequence(n,exponent=1.0,scale=1.0,seed=None):
207
 
    """
208
 
    Return sample sequence of length n from a Pareto distribution.
209
 
 
210
 
    """
211
 
    try:
212
 
        import pygsl.rng
213
 
    except ImportError:
214
 
        print "Import error: not able to import pygsl"
215
 
        return
216
 
    rng=pygsl.rng.rng()
217
 
    random._inst = random.Random()
218
 
    if seed is None:
219
 
        seed=random.randint(1,2**32-1)
220
 
    rng.set(seed)
221
 
 
222
 
    return rng.pareto(exponent,scale,n)
223
 
 
224
 
def gsl_powerlaw_sequence(n,exponent=2.0,scale=1.0,seed=None):
225
 
    """
226
 
    Return sample sequence of length n from a power law distribution.
227
 
 
228
 
    """
229
 
    try:
230
 
        import pygsl.rng
231
 
    except ImportError:
232
 
        print "Import error: not able to import pygsl"
233
 
        return
234
 
    rng=pygsl.rng.rng()
235
 
    random._inst = random.Random()
236
 
    if seed is None:
237
 
        seed=random.randint(1,2**32-1)
238
 
    rng.set(seed)
239
 
 
240
 
    return rng.pareto(exponent-1,scale,n)
241
 
 
242
 
def gsl_poisson_sequence(n,mu=1.0,seed=None):
243
 
    """
244
 
    Return sample sequence of length n from a Poisson distribution.
245
 
 
246
 
    """
247
 
    try:
248
 
        import pygsl.rng
249
 
    except ImportError:
250
 
        print "Import error: not able to import pygsl"
251
 
        return
252
 
    rng=pygsl.rng.rng()
253
 
    random._inst = random.Random()
254
 
    if seed is None:
255
 
        seed=random.randint(1,2**32-1)
256
 
    rng.set(seed)
257
 
 
258
 
    return rng.poisson(mu,n)
259
 
 
260
 
def gsl_uniform_sequence(n,seed=None):
261
 
    """
262
 
    Return sample sequence of length n from a uniform distribution.
263
 
 
264
 
    """
265
 
    try:
266
 
        import pygsl.rng
267
 
    except ImportError:
268
 
        print "Import error: not able to import pygsl"
269
 
        return
270
 
    rng=pygsl.rng.rng()
271
 
    random._inst = random.Random()
272
 
    if seed is None:
273
 
        seed=random.randint(1,2**32-1)
274
 
    rng.set(seed)
275
 
 
276
 
    return rng.uniform(n)
277
 
 
278
 
 
279
202
# The same helpers for choosing random sequences from distributions
280
203
# uses Python's random module
281
204
# http://www.python.org/doc/current/lib/module-random.html
341
264
    # choose from CDF
342
265
    seq=[bisect.bisect_left(cdf,s)-1 for s in inputseq]
343
266
    return seq
 
267
 
 
268
class UnionFind:
 
269
    """Union-find data structure.
 
270
 
 
271
    Each unionFind instance X maintains a family of disjoint sets of
 
272
    hashable objects, supporting the following two methods:
 
273
 
 
274
    - X[item] returns a name for the set containing the given item.
 
275
      Each set is named by an arbitrarily-chosen one of its members; as
 
276
      long as the set remains unchanged it will keep the same name. If
 
277
      the item is not yet part of a set in X, a new singleton set is
 
278
      created for it.
 
279
 
 
280
    - X.union(item1, item2, ...) merges the sets containing each item
 
281
      into a single larger set.  If any item is not yet part of a set
 
282
      in X, it is added to X as one of the members of the merged set.
 
283
 
 
284
      Union-find data structure. Based on Josiah Carlson's code,
 
285
      http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/215912
 
286
      with significant additional changes by D. Eppstein.
 
287
      http://www.ics.uci.edu/~eppstein/PADS/UnionFind.py
 
288
 
 
289
    """
 
290
 
 
291
    def __init__(self):
 
292
        """Create a new empty union-find structure."""
 
293
        self.weights = {}
 
294
        self.parents = {}
 
295
 
 
296
    def __getitem__(self, object):
 
297
        """Find and return the name of the set containing the object."""
 
298
 
 
299
        # check for previously unknown object
 
300
        if object not in self.parents:
 
301
            self.parents[object] = object
 
302
            self.weights[object] = 1
 
303
            return object
 
304
 
 
305
        # find path of objects leading to the root
 
306
        path = [object]
 
307
        root = self.parents[object]
 
308
        while root != path[-1]:
 
309
            path.append(root)
 
310
            root = self.parents[root]
 
311
 
 
312
        # compress the path and return
 
313
        for ancestor in path:
 
314
            self.parents[ancestor] = root
 
315
        return root
 
316
        
 
317
    def __iter__(self):
 
318
        """Iterate through all items ever found or unioned by this structure."""
 
319
        return iter(self.parents)
 
320
 
 
321
    def union(self, *objects):
 
322
        """Find the sets containing the objects and merge them all."""
 
323
        roots = [self[x] for x in objects]
 
324
        heaviest = max([(self.weights[r],r) for r in roots])[1]
 
325
        for r in roots:
 
326
            if r != heaviest:
 
327
                self.weights[heaviest] += self.weights[r]
 
328
                self.parents[r] = heaviest