How can I produce all of the combinations of the values in N number of vb list of variable lengths?
Let's say I have N number of vb lists, e.g.
first = {'a', 'b', 'c', 'd'}
second = {'e'}
third = {'f', 'g', 'h', 'i', 'j'}
(Three list in this example, but its N number of lists for the problem.)
And I want to output all the combinations of their values, to produce a list of lists in the order.
{
{a,e,f}
{a,e,g}
{a,e,h}
{a,e,i}
{a,e,j}
{b,e,f}
{b,e,g}
....
{d,e,j}
}
A simple way to implement with python
Here's a fairly simple-minded way of doing in (i.e. no Linq).
Assuming a form with a Button and a ListBox.
Storing everything in Lists for simplicity:
Second list is just to keep track of progress through the permutations.
Load up the data...
And the rest...
Introduction
What you want to do is called: cartesian product
Let's do some naming before going further. I will name your input lists
L_i
where1 <= i <= n
. I will also nameS_i
the size of the input listL_i
.We could ask the question:
what is the size of the output ?
If there is only one list
L_1
, there will beS_1
output lists, each one containing exactly one element ofL_1
.If there are two lists
{L_1, L_2}
. For each element ofL_1
I can appendS_2
different elements ofL_2
. As there areS_1
elements ofL_1
it makesS_1*S_2
different output lists.We can continue the reasoning to
n
lists and prove that the number of output lists will be:S_1*...*S_n
.How does that help us ? Because we can now create a mapping between a number
i
and an output list.Given
i
a number0<=i<S_1*...*S_n
, the output list contains:Implementation example
I don't know VB.net so I chose C# which uses the same .net platform. I decided to use a
yield return
function so that we don't allocate more memory than needed. If you just need to print the outputs it will only consume a singleulong
of memory instead of allocating a very big list of output lists.The output is:
Limitation
One may ask :
what if the product of the lists length overflows the variable used to index the outputs ?
.This is a real theoretical problem, but I use a
ulong
in my code and if the total number of ouput lists overflows this variable there is little chance that you can enumerate the output whatever method you use. (because the theoretical output will contain more than2^64
lists).Applications
The OP didn't explain why he needed this algorithm in the first place. So the reader may wonder
why is this useful ?
. One reason among others may be to generate test cases for regression testing. Let's say you have a legacy function taking as input three variables. You could generate some possible values for each of the parameters and using the cartesian product collect result of the function for each possible set of parameters. After refactoring the legacy code, you could ensure there is no regression by comparing the new code output and the legacy code output.This is a combination problem, not one of permutations. We want all combinations of 3 elements, one taken from each set. The order is driven by the sets, not the elements. The total number of combinations is the product of the counts of the set. In the example, that would be 4 x 1 x 5 = 20. Since we don't know how many lists there are (call it N). It we knew what N was ahead of time, this would be easy. We could write some nested loops to generate the combinations. Not knowing it is what's makes this tricky. Recursion is probably the most elegant way to solve it.
This function can be called as follows. This example assumes that the lists are members of another list called lists.