More user feedback on

David Eppstein eppstein at
Mon Nov 10 00:02:39 CET 2003

In article <1hSqb.1167$bQ3.696 at>,
 "Raymond Hettinger" <vze4rx4y at> wrote:

> For Py2.4, I'm working on a C implementation of with the possibility 
> of
> having a set() type as a builtin.  There is a question as whether the current
> design for set of sets has been useful.
> To support sets-of-sets, the current design includes an automatic conversion 
> to
> an immutable set class.  The original use case was for implementing graph
> algorithms.
> Has anyone used sets-of-sets to solve any non-toy problems?
> Has anyone successfully applied sets-of-sets to graph algorithms?
> If the need has arisen, is the current design sufficient?

Now that I have sets working, here's a response to the original question.

I think, now that we have sets, the natural update to Guido's graph 
representation essay <>
is to use the following representation of a graph:
Represent G as a dictionary, where the keys are vertices and the values 
are sets of the (outgoing) neighbors of each vertex.
This representation allows the following operations to be performed 

    - iterate through all vertices in G:
      for v in G: suite

    - iterate through all neighbors of a vertex v:
      for w in G[v]: suite

    - test whether a vertex belongs to G:
      if v in G: suite

    - test whether an edge belongs to G:
      if w in G[v]: suite

If one uses this representation, then any time one has sets as vertices, 
one will have sets of sets in the representation.  No automatic coercion 
from mutable to immutable seems to be necessary here, or in any graph 
algorithm using this representation -- if you are going to use sets as 
vertices, they have to already be immutable.

Here's a quick example involving sets of sets of sets:

from sets import ImmutableSet

def powerset(U):
    """Generates all subsets of a set or sequence U."""
    U = iter(U)
        x = ImmutableSet([])
        for S in powerset(U):
            yield S
            yield S | x
    except StopIteration:
        yield ImmutableSet()

def cube(n):
    """Graph of n-dimensional hypercube."""
    singletons = [ImmutableSet([x]) for x in range(n)]
    return dict([(x, ImmutableSet([x^s for s in singletons]))
                 for x in powerset(range(n))])

def linegraph(G):
    """Graph, the vertices of which are edges of G,
    with two vertices being adjacent iff the corresponding
    edges share a vertex."""
    L = {}
    for x in G:
        for y in G[x]:
            nx = [ImmutableSet([x,z]) for z in G[x] if z != y]
            ny = [ImmutableSet([y,z]) for z in G[y] if z != x]
            L[ImmutableSet([x,y])] = ImmutableSet(nx+ny)
    return L

cuboctahedron = linegraph(cube(3))

David Eppstein            
Univ. of California, Irvine, School of Information & Computer Science

More information about the Python-list mailing list