Antimatroid, The

niche for the aesthetics, mathematics and computer science

Posts Tagged ‘Combinatorics

One tree, many possibilities: Part 2

without comments

Implementation

In my previous post, I wrote about how to construct a rule based tree that allows one to generate the outputs of a number of counting functions. In this installment, I am providing the corresponding implementation in C#. This source code in intended for pedagogical use only. Now, onto the show…

All five functions rely on the basic tree definition of T_{n}(S, \sigma) which is treated as a kernel function in the implementation.

private List<List<T>> kernel<T>(List<T> S, Func<List<T>, int, List<T>> sigma, int N) {
    return kernel<T>(S, sigma, N, new List<T>());
}

private List<List<T>> kernel<T>(List<T> S, Func<List<T>, int, List<T>> sigma, int N, List<T> u) {
    List<List<T>> R = new List<List<T>>(new List<T>[] { u });
    if (N <= 0)
        return R;

    for (int n = 0; n < S.Count; n++) {
        List<T> v = new List<T>(u);
        v.Add(S[n]);
        R.AddRange(kernel<T>(sigma(S, n), sigma, N - 1, v));
    }

    return R;
}

Apart from the kernel, we still need a couple surjective functions to implement the remaining functions. As discussed in the previous post, we need two functions, one that returns all elements of a list except for a specified index, and one that returns all elements of a list greater than a specified index.

private List<T> notEqual<T>(List<T> S, int n) {
    return new List<T>(S.Where((x, m) => m != n));
}

private List<T> greaterThan<T>(List<T> S, int n) {
    return new List<T>(S.Where((x, m) => m > n));
}

The remaining implementations of the n-ary Cartesian Product, Permutation, k-Permutation, Power Set and k-Combination are now rather trivial.

public List<List<T>> nAryCartesianProduct<T>(List<T> S, int n) {
    List<List<T>> R = kernel<T>(S, (x, y) => x, n);
    R.RemoveAll((x) => x.Count < n);
    return R;
}

public List<List<T>> permutation<T>(List<T> S) {
    return kPermutation<T>(S, S.Count);
}

public List<List<T>> kPermutation<T>(List<T> S, int k) {
    List<List<T>> R = kernel<T>(S, notEqual, k);
    R.RemoveAll((x) => x.Count != k);
    return R;
}

public List<List<T>> powerset<T>(List<T> S) {
    return kernel<T>(S, greaterThan, S.Count);
}

public List<List<T>> kCombination<T>(List<T> S, int k) {
    List<List<T>> R = kernel<T>(S, greaterThan, k);
    R.RemoveAll((x) => x.Count != k);
    return R;
}

In the next post, I’ll wrap things up by going over time complexity, correctness and why this is all just a stepping stone to much more efficient approaches.

Written by lewellen

2008-07-06 at 7:50 pm

Posted in Uncategorized

Tagged with ,

One tree, many possibilities

without comments

Introduction

Given the finite set S and the surjective function \sigma, Let T_{n}\left(S, \sigma\right) be a complete |S|-ary tree of depth n such that T_{0}\left(S, \sigma\right) = \emptyset, T_n(S, \sigma) = T_{n - 1}(S, \sigma) \{ \left( T_{n - 1}(S, \sigma) \oplus s \right) | s \in \sigma(S) \}. For example, Let A = \{0, 1\} and \\f = S \to S, T_{2}\left(A, \\f\right) = \emptyset \{ \left(\emptyset, 0\right) \{ \left(\emptyset, 0, 0\right), \left(\emptyset, 0, 1\right) \}, \left(\emptyset, 1\right) \{ \left(\emptyset, 1, 0\right), \left(\emptyset, 1, 1\right) \} \}. Pictured bellow is T_{3}\left(A, \\f \right) with omitting \emptyset for brevity.

It should be evident from the example that the set of nodes at depth n is the n-ary Cartesian product of S, S^{n} = S \times \ldots \times S.

Now, if we change \\f to now be \\f : S \to \{ s | s \in S \wedge \nu(s) \neq \nu\left(parent\left(s\right)\right)\}, where \nu : S \leftrightarrow \mathbb{N}_{0}, the set of all leaf nodes at depth |S| is the set of permutations of S, S!. Extending the example above, T_{2} \left( A, \\f \right) = \{ \{ \left( \emptyset, 0, 1 \right) \}, \{ \left( \emptyset, 1, 0 \right) \} \}.

Without changing the definition of \\f, it is possible to produce all possible k-permutations from T, P(S, k) by selecting all nodes at depth k.

At this point, if we make a small change to \\f : S \to \{ s | s \in S \wedge \nu\left(s\right) > \nu\left( parent\left(s\right)\right)\}, every node in T now represents the power set of S, 2^{S}. Again, using the example from above, T_{2} \left( A, \\f \right) = \emptyset \{ \left( \emptyset, 0 \right), \left( \emptyset, 1 \right) \{ \left( \emptyset, 1, 1 \right) \} \}.

Finally, without any further changes to the definition of \\f, it is possible to produce all possible n-combinations from T, C(S, n), by selecting all nodes at depth n.

T is a very elegant way of representing and enumerating some of the most rudimentary combinatorial operations of introductory mathematics. In this series of post we’ll explore each operation and look at implementations, time complexities and possible applications.

Written by lewellen

2008-06-29 at 8:25 pm

Posted in Uncategorized

Tagged with ,