Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm trying to write vb.net code to return unique combinations for set My set contains 3 different elements. I've found similar post this Post but couldn't find any VB solution to get this results

Example:

Elements: 1, 2, 3

{ 1, 2, 3}

Result must be

1
2
3
12
13
23
123
...........
>...................

i,m trying to achieve this by using following code

Function GetCombinations(ByVal depth As Integer, ByVal values As String()) As IEnumerable(Of String)
    If depth > values.Count + 1 Then Return New List(Of String)
    Dim result = New List(Of String)

    For i = 0 To depth - 1
        For y = 0 To values.Count - 1
            If i = 0 Then
                result.Add(values(y))
            Else
                result.Add(values(i - 1) + values(y))
            End If
        Next
    Next
    Return result
End Function

To Get the result

Dim reslt = GetCombinations(4, data_array)

?reslt
Count = 12
    (0): "1"
    (1): "2"
    (2): "3"
    (3): "11"
    (4): "12"
    (5): "13"
    (6): "21"
    (7): "22"
    (8): "23"
    (9): "31"
    (10): "32"
    (11): "33"

Hint: I work with Mathematics and manage to calculate no of combinations. i can test the out with this formula

Example there is this formula called nCr. it means out of n number of element how many way of taking r number of elements with unique combinations of r.

nPr = n!/(n-r)!
n! = 1 * 2 * 3 * 4* ... (n-1) * n

Elements: 1, 2, 3
In this case n = 3 and r can be 1, 2, and 3 all

number of combinations  = 3P1 + 3P2 + 3P3
                                          = 3!/2! + 3!/1! + 3!/0!
                                          = 6/2 + 6/1 + 6/1                    (0!=1)
                                          = 3+6+6
                                          = 15 
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
762 views
Welcome To Ask or Share your Answers For Others

1 Answer

Knowing the term makes it easier to find existing algorithms. What you're looking for is a power set. Here's a quick VB.NET translation of a C# implementation I found on Rosetta Code:

Public Function GetPowerSet(Of T)(ByVal input As IEnumerable(Of T)) As IEnumerable(Of IEnumerable(Of T))
    Dim seed As IEnumerable(Of IEnumerable(Of T)) = {Enumerable.Empty(Of T)()}
    Return input.Aggregate(seed, Function(a, b) a.Concat(a.Select(Function(x) x.Concat({b}))))
End Function

Testing:

For Each x In GetPowerSet({1, 2, 3})
    Console.WriteLine(String.Join(", ", x))
Next

Output:

1
2
1, 2
3
1, 3
2, 3
1, 2, 3

EDIT - Based on your latest explanation, I think you need a different approach. It seems you want combinations with repetitions / replacement, for all sizes up to the input size. You could simply call one of those algorithms with parameters (S, k) for each value of k from 1 to n and join all the results into a single set of results.

Translating Python's algorithm:

Public Iterator Function GetCombinationsWithReplacement(Of T)(source As IEnumerable(Of T), size As Integer) As IEnumerable(Of IEnumerable(Of T))
    Dim pool = source.ToList()
    Dim n = pool.Count
    If n = 0 AndAlso size > 0 Then
        Return
    End If
    Dim indices = Enumerable.Repeat(0, size).ToList()
    Yield indices.Select(Function(i) pool.Item(i))
    While True
        Dim index As Nullable(Of Integer) = Nothing
        For i = size - 1 To 0 Step -1
            If indices.Item(i) <> n - 1 Then
                index = i
                Exit For
            End If
        Next
        If Not index.HasValue Then
            Return
        End If
        indices = indices.Take(index.Value).Concat(Enumerable.Repeat(indices.Item(index.Value) + 1, size - index.Value)).ToList()
        Yield indices.Select(Function(i) pool.Item(i))
    End While
End Function

(You will need to modify this if your VB.NET compiler doesn't support Yield.)

The results of calling this with different sizes are:

GetCombinationsWithReplacement({1, 2, 3}, 1):

{1}
{2}
{3}

GetCombinationsWithReplacement({1, 2, 3}, 2):

{1, 1}
{1, 2}
{1, 3}
{2, 2}
{2, 3}
{3, 3}

GetCombinationsWithReplacement({1, 2, 3}, 3):

{1, 1, 1}
{1, 1, 2}
{1, 1, 3}
{1, 2, 2}
{1, 2, 3}
{1, 3, 3}
{2, 2, 2}
{2, 2, 3}
{2, 3, 3}
{3, 3, 3}

We can join these into a single sequence with all 19 subsets:

Public Iterator Function GetCombinationsWithReplacementAllSizes(Of T)(source As IEnumerable(Of T)) As IEnumerable(Of IEnumerable(Of T))
    Dim pool = source.ToList()
    For size = 1 To pool.Count
        For Each subset In GetCombinationsWithReplacement(pool, size)
            Yield subset
        Next
    Next
End Function

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...