combalg-py

combalg-py is a collection of combinatorial algorithms in python. The algorithms are primarily involve enumeration and random selection of combinatorial objects like sets, subsets, permutations, partitions and compositions. Random selection is always (unless noted otherwise) uniformly at random. The majority of the initial implementation was adapted from the mathematics presented in [NW1978].

API Documentation:

combalg.subset subset.py
combalg.combalg combalg.py
combalg.rooted_tree rooted_tree.py
combalg.utility utility.py

subset.py

Enumeration and random selection of arbitrary and k-element restricted subsets.

Members

combalg.subset.all_k_element(elements, k)[source]

A generator that produces all k-element subsets of the input elements in lexicographic order.

Parameters:
  • elements (list) – the input set
  • k (int) – size of the output set
Returns:

one of the k-element subsets of the input set

Return type:

list

combalg.subset.powerset(elements)[source]

A generator that produces all subsets of the input ‘set’ of elements. The input doesn’t need to be a set, any iterable will do (I think). The point is that the elements need not be unique, but will be treated as unique with respect to the subset generation. For example: powerset([‘a’,’a’]) will give the sequence [‘a’,’a’], [‘a’], [‘a’], []

Parameters:elements (list) – input set
Returns:one of the subsets of the input set
Return type:list
combalg.subset.random(elements)[source]

Returns a random subset of a set of elements. Equivalent to randomly selecting an element of powerset(elements). For each element of the universal set, select it to be in the subset with p=0.5

Parameters:elements (list) – the input set
Returns:a random subset of the input set
Return type:list
combalg.subset.random_k_element(elements, k)[source]

Returns a random k-element subset of a set of elements. This is a clever algorithm, explained in [NW1978] but not actually implemented. Essentially starting with the first element of the universal set, include it in the subset with p=k/n. If the first was selected, select the next with p=(k-1)/(n-1), if not p = k/(n-1), etc.

Parameters:
  • elements (list) – the input set
  • k (int) – the size of the output set
Returns:

a random k-element subset of the input set

Return type:

list

combalg.py

Algorithms I didn’t categorize.

Todo

the local function ‘num_partitions(n)’ is not smart at all

Todo

the local functions ‘num_partitions(n)’ and ‘choose_dj(n, rho)’ can be combined, as in [NW1978]. I have had better luck implementing algorithms from [NW1978] using the mathematical description and NOT using the fortran source.

Members

class combalg.combalg.permutation[source]

Permutations of letters.

static all(a)[source]

A generator that returns all permutations of the input letters.

Parameters:a (list) – the input set
Returns:all permutations of the input set, one at a time
static random(elements)[source]

Returns a random permutation of the input list :param a: the input set :type a: list :return: a shuffled copy of the input set

class combalg.combalg.composition[source]

Compositions of integer N into K parts.

static all(n, k)[source]

A generator that returns all of the compositions of n into k parts. :param n: integer to compose :type n: int :param k: number of parts to compose :type k: int :return: a list of k-elements which sum to n

Compositions are an expression of n as a sum k parts, including zero terms, and order is important. For example, the compositions of 2 into 2 parts:

>>> compositions(2,2) = [2,0],[1,1],[0,2].

NOTE: There are C(n+k-1,n) partitions of n into k parts. See: Stars and Bars.

static random(n, k)[source]

Returns a random composition of n into k parts.

Parameters:
  • n (int) – integer to compose
  • k (int) – number of parts to compose
Returns:

a list of k-elements which sum to n

Returns random element of compositions() selected uniformly at random.

class combalg.combalg.integer_partition[source]

Partitions of integers

static all(n)[source]

A generator that returns all integer partitions of n.

Parameters:n (int) – integer to partition
Returns:a list of integers that sum to n, one at a time.

This implementation is due to [ZS1998]. Integer partitions are unique ways of writing a sum with each term > 0, and order does not matter. The partitions of 5 are:

>>> [[5], [4, 1], [3, 2], [3, 1, 1], [2, 2, 1], [2, 1, 1, 1], [1, 1, 1, 1, 1]]
static num_partitions(n)[source]

Number of partitions of integer n.

Parameters:n – Integer n.
Returns:Number of partitions of n
static random(n)[source]

Returns a random integer partition of n.

Parameters:n (int) – integer to partition
Returns:a list of integers that sum to n, one at a time.
class combalg.combalg.set_partition[source]

Partitions of sets.

static all(n)[source]
A generator that returns all set partitions of [n] = {0,1,2,...,n-1}. The result is returned as a 3-tuple (p,q,nc): p - a list where p[i] is the population of the i-th equivalence class q - a list where q[i] is the equivalence class of i nc - the number of equivalence classes in the partition

Todo

The following will map the list q into a list of sets that make up the partition. I’d like to see a more efficient/pythonic implementation:

def map_set_partition(a, cls):
    y = []
    for t in range(len(a)):
        x = reduce(lambda x,y: x+[a[y]] if cls[y] == t else x, range(len(a)), [])
        if x:
            y.append(x)
        return y
static random(a)[source]

Returns a random partition of the input set

rooted_tree.py

Rooted Tree Algorithms. Well, only random selection. I believe there is enough material in chapter 13 of [NW1978] to implement an enumerated sequence (interesting challenge).

Members

combalg.rooted_tree.random(nn)[source]

Returns a random rooted tree on nn vertices

Parameters:nn (int) – number of vertices in the output tree.
Returns:a random rooted tree
Return type:list

The returned list is in Prufer Code. You can convert the result to an edge list by zipping it with the sequence [0,1,..,nn] and discarding the initial entry, which is always (0,0).

>>> result = rooted_tree.random(7)
>>> edge_list = list(zip(result, range(len(result))))[1:]

utility.py

These are some useful utility functions.

Members

combalg.utility.is_tree(num_vert, edge_list)[source]

Determines if edge_list describes a tree with num_vert vertices.

Parameters:
  • num_vert (int) – the number of vertices in the tree
  • edge_list (list of (int,int) tuples) – a list of edges (pairs of vertices)
Returns:

True if the input represents a tree, False otherwise

combalg.utility.listify(a)[source]

Takes an iterable and makes a sorted list of it and all iterable members. Creates a nice display.

Parameters:a (list) – the input list (elements may also be lists)
Returns:a printable string representing the input list
Return type:string

Todo

Todo

the local function ‘num_partitions(n)’ is not smart at all

(The original entry is located in /home/sstump/development/combalg-py/src/combalg/combalg.py:docstring of combalg.combalg, line 5.)

Todo

the local functions ‘num_partitions(n)’ and ‘choose_dj(n, rho)’ can be combined, as in [NW1978]. I have had better luck implementing algorithms from [NW1978] using the mathematical description and NOT using the fortran source.

(The original entry is located in /home/sstump/development/combalg-py/src/combalg/combalg.py:docstring of combalg.combalg, line 9.)

Todo

The following will map the list q into a list of sets that make up the partition. I’d like to see a more efficient/pythonic implementation:

def map_set_partition(a, cls):
    y = []
    for t in range(len(a)):
        x = reduce(lambda x,y: x+[a[y]] if cls[y] == t else x, range(len(a)), [])
        if x:
            y.append(x)
        return y

(The original entry is located in /home/sstump/development/combalg-py/src/combalg/combalg.py:docstring of combalg.combalg.set_partition.all, line 7.)

References

[NW1978](1, 2, 3, 4) “Combinatorial Algorithms (for Computers and Calculators),2nd ed.”, Nijenhuis & Wilf, Academic Press, 1978. http://www.math.upenn.edu/~wilf/website/CombinatorialAlgorithms.pdf
[ZS1998]“Fast Algorithms for Generating Integer Partitions”, Zoghbi & Stojmenovic, 1998. https://pdfs.semanticscholar.org/9613/c1666b5e48a5035141c8927ade99a9de450e.pdf

Indices and tables