2
votes

Based on this question

Ordered Fixed Length Combination of a String

I created a PHP algorithm that creates combinations of characters on a fixed length (basically a rewrite of the Java-answer)

private function getCombination($length, $input) {
    $result = array();

    if ($length == 0) {
        return $result;
    }

    $first = substr($input, 0, $length);
    $result[] = $first;

    if (strlen($input) == $length) {
        return $result;
    }

    $tails = $this->getCombination($length - 1, substr($input, 1));

    foreach ($tails as $tail) {
        $tmp = substr($input, 0, 1) . $tail;

        if (!in_array($tmp, $result)) {
            $result[] = $tmp;
        }
    }

    return array_merge($result, $this->getCombination($length, substr($input, 1)));
}

For another question, Create fixed length non-repeating permutation of larger set, I was given a (brilliant) algorithm that would make permutations indexable, effectively making them adressable by providing a "key" that would always produce the exact same permutation, when given the same set of characters and the same length.

Well, now I basically need the same but for combinations, in contrast to permutations as in my other question.

Can the algorithm above be modified in the same way? Meaning to create a function like

public function getCombinationByIndex($length, $index);

That will return one combination out of the thousand possible that is created with the algorithm without creating them beforehand?

1

1 Answers

1
votes

I have written a class in C# to handle common functions for working with the binomial coefficient, which is the type of problem that your problem appears to fall under - assuming that you working with combinations instead of permutations. It performs the following tasks:

  1. Outputs all the K-indexes in a nice format for any N choose K to a file. The K-indexes can be substituted with more descriptive strings or letters.

  2. Converts the K-indexes to the proper index of an entry in the sorted binomial coefficient table. This technique is much faster than older published techniques that rely on iteration. It does this by using a mathematical property inherent in Pascal's Triangle.

  3. Converts the index in a sorted binomial coefficient table to the corresponding K-indexes. I believe it is also faster than older iterative solutions.

  4. Uses Mark Dominus method to calculate the binomial coefficient, which is much less likely to overflow and works with larger numbers.

  5. The class is written in .NET C# and provides a way to manage the objects related to the problem (if any) by using a generic list. The constructor of this class takes a bool value called InitTable that when true will create a generic list to hold the objects to be managed. If this value is false, then it will not create the table. The table does not need to be created in order to use the 4 above methods. Accessor methods are provided to access the table.

  6. There is an associated test class which shows how to use the class and its methods. It has been extensively tested with 2 cases and there are no known bugs.

To read about this class and download the code, see Tablizing The Binomial Coeffieicent.

It should be pretty straight forward to port this class over to php. You probably will not have to port over the generic part of the class to accomplish your goals. Denending on the number of combinations you are working with, you might need to use a bigger word size than 4 byte ints.