There is a way to access k-indices from a rank without having to repeat all the previous ones. I discovered and published this technique a couple of years ago. So, if all you want to do is print every billionth combination, the class I wrote makes it almost trivial, and it takes no more than a few seconds of 1,000,000,000 to calculate all the combinations for the 27+ trillion combinations available at time intervals. 27 trillion / 1 billion = approximately 27,000 combinations to print.
The class is written in C # to handle common functions for working with the binomial coefficient. It performs the following tasks:
Prints all K-indices in a good format for any N that selects K to a file. K-indices can be replaced with more descriptive strings or letters.
Converts K-indices to the corresponding lexicographic index or ranking in a table of sorted binomial coefficients. This method is much faster than older published iteration-based methods. He does this using the mathematical property inherent in the Pascal Triangle, and is very efficient compared to iterating over a set.
Converts an index into a sorted table of binomial coefficients into the corresponding K-indices. The technique used is also much faster than older iterative solutions.
Uses the Mark Dominus method to calculate the binomial coefficient, which is much less likely to overflow and works with large numbers.
The class is written in .NET C # and provides a way to manage the objects associated with the problem (if any) using a common list. The constructor of this class takes a bool value, called InitTable, which, when true, will create a general list for storing objects to be managed. If this value is false, then it will not create a table. The table does not need to be created in order to use the 4 above methods. Access methods are provided to access the table.
There is a related test class that shows how to use the class and its methods. It has been widely tested in many cases, and there are no known errors. The class uses a mathematical relationship that can be seen from the Pascal Triangle to provide an efficient way to translate between rank and K-indices.
To read about this class and download the code, see Tablizing the Binomial Coefficient .
The following verified sample code will go through each unique combination:
public void Test10Choose5() { String S; int Loop; int N = 10; // Total number of elements in the set. int K = 5; // Total number of elements in each group. // Create the bin coeff object required to get all // the combos for this N choose K combination. BinCoeff<int> BC = new BinCoeff<int>(N, K, false); int NumCombos = BinCoeff<int>.GetBinCoeff(N, K); // The Kindexes array specifies the indexes for a lexigraphic element. int[] KIndexes = new int[K]; StringBuilder SB = new StringBuilder(); // Loop thru all the combinations for this N choose K case. for (int Combo = 0; Combo < NumCombos; Combo++) { // Get the k-indexes for this combination. BC.GetKIndexes(Combo, KIndexes); // Verify that the Kindexes returned can be used to retrive the // rank or lexigraphic order of the KIndexes in the table. int Val = BC.GetIndex(true, KIndexes); if (Val != Combo) { S = "Val of " + Val.ToString() + " != Combo Value of " + Combo.ToString(); Console.WriteLine(S); } SB.Remove(0, SB.Length); for (Loop = 0; Loop < K; Loop++) { SB.Append(KIndexes[Loop].ToString()); if (Loop < K - 1) SB.Append(" "); } S = "KIndexes = " + SB.ToString(); Console.WriteLine(S); } }
You will need to port the BinCoeff class to C ++ and use it instead of ints. Your application will have at least 2 cycles. The outer loop will create a BinCoeff object for each N selects case K. The inner loop will increment a long value by a billion and call the BinCoeff.GetKIndexes method, which will return a combination suitable for printing. The returned combination is in the form of an array with a null value (int / long). You can create another char array or a string that can be indexed with the values ββreturned by GetKIndexes.
If you need numbers that exceed what a long value might contain, you probably want to examine the class to use the BigInteger class.
Thanks for the link to the Wolfram Alpha calculator. The best binomial odds calculator that I found earlier that works with very large numbers (he accurately calculated the case, which gave more than 15,000 digits as a result) can be found here
Bob bryan
source share