Results 1 to 22 of 22

Thread: [RESOLVED] [2005] Find All Binary Combinations...

  1. #1

    Thread Starter
    Frenzied Member circuits2's Avatar
    Join Date
    Sep 2006
    Location
    Kansas City, MO
    Posts
    1,027

    Resolved [RESOLVED] [2005] Find All Binary Combinations...

    I have read all of the past posts but did not find any that were directly related to what I am trying to do here, save maybe one or two.

    Start with 2 numbers, we'll say 15 and 23 for now but they will be variable in the actuall application. I want to find all combinations of a 23 bit binary word that have exactly 15 1's. I know from the code below that there are 170,544 of them. However, I was wondering if there is a better or more efficient way to do this than my attempt as shown. It takes approx. a minute and a half, which isn't too bad considering there are over 8,000,000 combinations.

    Code:
    Private Sub SuggestNewWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles SuggestNewWorker.DoWork
    
    	Try
    
    		Dim fdrMax As Integer = 15
    		Dim fdrInv As Integer = 23
    		Dim combos As Integer = 0
    		Dim binWord As String = “”
    		Dim foundHighs As Integer = 0
    		Dim starter As Int64 = 2 ^ (fdrMax – 1)
    		Dim stopper As Int64 = 2 ^ (fdrInv – 1)
    		Dim volume As Int64 = stopper – starter
    		Dim progMark As Integer = CInt(stopper \ 100)
    		Dim progCheck As Integer = 0
    		Dim progRep As Integer = 0
    
    		For runner As Int64 = starter To stopper Step 1
    			For cnt As Integer = 1 To fdrInv
    				If runner And (2 ^ (cnt – 1)) Then
    					binWord = “1” & binWord
    					foundHighs += 1
    				Else
    					binWord = “0” & binWord
    				End If
    			Next cnt
    
    			If foundHighs = fdrMax Then
    				combos += 1
    			End If
    
    			If progCheck = progMark Then
    				progRep += 1
    				Me.SuggestNewWorker.ReportProgress(progRep)
    				progCheck = 0
    			Else
    				progCheck += 1
    			End If
    
    			binWord = “”
    			foundHighs = 0
    			Application.DoEvents()
    		Next Runner
    
    	Catch ex As Exception
    		MessageBox.Show(ex.Message)
    	End Try
    End Sub
    Show the love! Click (rate this post) under my name if I was helpful.

    My CodeBank Submissions: How to create a User Control | Move a form between Multiple Monitors (Screens) | Remove the MDI Client Border | Using Report Viewer with Visual Studio 2012 Express

  2. #2
    Fanatic Member
    Join Date
    Nov 2006
    Posts
    675

    Re: [2005] Find All Binary Combinations...

    Just one idea, don't start at 1 everytime. The first number that will have the number of 1's you are looking for is 2^X (X beging 15 in this case). So, that cuts out all the number before 2^15. That isn't great, unless the number of 1's you are looking for happens to be fairly close to the max (23 in this case). However, this might get you thinking.

    If 2^15 is this first, then 2^16 will have 15 combinations of numbers with 15 1's. That is this string, "111111111111111", with a single 1 from it replaces with a zero and a 1 tacked onto the beginning. Meaning:
    "1" & "111111111111110"
    "1" & "111111111111101"
    "1" & "111111111111011"
    "1" & "111111111110111"
    "1" & "111111111101111"
    "1" & "111111111011111"....

    That should knock out half of your numbers, in this case. It is starting to look like this is going to be recursive.
    VB.Net 2008
    .Net Framework 2.0

    "Must you breathe? 'Cause I need heaven..."

  3. #3

    Thread Starter
    Frenzied Member circuits2's Avatar
    Join Date
    Sep 2006
    Location
    Kansas City, MO
    Posts
    1,027

    Re: [2005] Find All Binary Combinations...

    If you look at my code, you will see that I am already doing what you suggested. I.E. The first combination will be 00000000111111111111111 and the last combination will be 11111111111111100000000. I am also using recursion already. The question is not how to do it, but if you can do it faster than I already am. Thank you for the post though.
    Show the love! Click (rate this post) under my name if I was helpful.

    My CodeBank Submissions: How to create a User Control | Move a form between Multiple Monitors (Screens) | Remove the MDI Client Border | Using Report Viewer with Visual Studio 2012 Express

  4. #4
    Frenzied Member
    Join Date
    Jul 2005
    Posts
    1,168

    Re: [2005] Find All Binary Combinations...

    try this for checking the number of times 1's show up:
    vb Code:
    1. Private Function func1(ByVal str As String, ByVal val As Integer) As Boolean
    2.         Dim x() As Char = str.ToCharArray
    3.         Dim upper As String = val - 1
    4.         Dim num As Integer
    5.         For i As Integer = 0 To upper
    6.             num = num + Convert.ToInt32((x(i).ToString()))
    7.         Next
    8.         If num = val Then
    9.             Return True
    10.         End If
    11.         Return False
    12.     End Function

    str is the string of the bit combination (23 in your example), and val is the number of 1's (15 in your example)

    edit: str is the "000000111", etc. Returns true if it has the correct number of 1's.
    Last edited by benmartin101; Mar 5th, 2007 at 04:19 PM.

  5. #5
    Fanatic Member
    Join Date
    Nov 2006
    Posts
    675

    Re: [2005] Find All Binary Combinations...

    Oops, I guess I jumped the gun on that one. I didn't scroll down. Well, one thing that would speed it up is completely removing any use of a string. You may have to get creative, but it always faster to use integers and such when you can.
    VB.Net 2008
    .Net Framework 2.0

    "Must you breathe? 'Cause I need heaven..."

  6. #6

    Thread Starter
    Frenzied Member circuits2's Avatar
    Join Date
    Sep 2006
    Location
    Kansas City, MO
    Posts
    1,027

    Re: [2005] Find All Binary Combinations...

    I'm not exactly sure that would be any faster. I did notice, though, that you used Int32 instead of Int64. The number 23 is variable and could exceed the limit of Int32.

    I think if I have to call a function from inside the routine, then it would actually take longer to process. Especially when the code is so brief.
    Show the love! Click (rate this post) under my name if I was helpful.

    My CodeBank Submissions: How to create a User Control | Move a form between Multiple Monitors (Screens) | Remove the MDI Client Border | Using Report Viewer with Visual Studio 2012 Express

  7. #7

    Thread Starter
    Frenzied Member circuits2's Avatar
    Join Date
    Sep 2006
    Location
    Kansas City, MO
    Posts
    1,027

    Re: [2005] Find All Binary Combinations...

    Quote Originally Posted by 18experience
    Oops, I guess I jumped the gun on that one. I didn't scroll down. Well, one thing that would speed it up is completely removing any use of a string. You may have to get creative, but it always faster to use integers and such when you can.
    I removed the string from the code shown above and gained a little speed. Not significant though...

    I think it may be as fast as I'm going to get.
    Show the love! Click (rate this post) under my name if I was helpful.

    My CodeBank Submissions: How to create a User Control | Move a form between Multiple Monitors (Screens) | Remove the MDI Client Border | Using Report Viewer with Visual Studio 2012 Express

  8. #8
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,109

    Re: [2005] Find All Binary Combinations...

    What do you want to do with these things once you get them? You could calculate the number that exist fairly readily, but I assume you want to do something more with them.

    A couple of suggestions:

    1) Get rid of the 2^ stuff. A faster technique would be to use bit shifting, which is much quicker than multiplication:

    vb Code:
    1. 'I don't know your runner and stopper stuff.
    2. dim x as integer
    3. dim n as integer = 1 'You'd need Int64, probably.
    4.  
    5. for x=0 to maxBitSize
    6.  if ((n << x) AND runner)>0 Then 'Actually, I don't know if runner is the right variable.
    7.   'It's a 1, add it.
    8.   foundhighs+=1
    9.  else
    10.   'It's a 0
    11.  end if
    12. next

    2) Don't use a string. You mentioned that you got rid of it. Did you do so completely? How did you build your bit string then? If you didn't, then at least you should be using a StringBuilder, because whenever you concatenate to a string, you don't simply add a character to the existing string. Instead, you allocate the memory for a new string that is the size of the old string plus one character, copy the existing string over to the new string, add the new character, and delete the old string. That's none too fast.
    My usual boring signature: Nothing

  9. #9
    Frenzied Member
    Join Date
    Jul 2005
    Posts
    1,168

    Re: [2005] Find All Binary Combinations...

    try this:

    My last sample gave the answer in 50 seconds(on my machine), this one gave it to me in 10seconds.
    vb Code:
    1. Private Sub Combo(ByVal bit As Integer, ByVal x As Integer)
    2.         Dim str As String = ""
    3.         For i As Integer = 0 To x - 1
    4.             str = str + "1"
    5.         Next
    6.         Dim power As Integer = bit
    7.  
    8.         Dim index As Integer = 0
    9.         For i As Integer = 0 To (2 ^ power) - 1
    10.             Dim bitcombo As String = Convert.ToString(i, 2)
    11.             bitcombo = bitcombo.Replace("0", "")
    12.             If bitcombo = str Then
    13.                 index = index + 1 'total number of times it appeared
    14.             End If
    15.         Next
    16.        
    17.     End Sub

    bit is corresponds to 23 and x corresponds to 15
    Last edited by benmartin101; Mar 5th, 2007 at 04:48 PM.

  10. #10
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,109

    Re: [2005] Find All Binary Combinations...

    Oh yeah, I should mention that I expect that there is a much faster technique than this, which is why I asked what you wanted to do with the results.

    In your example, you mentioned a 23 bit string with 15 bits set. Therefore, if you start with...oh heck, lets simplify it down to a 5 bit string with 3 set:

    11100

    Now, the next two would be to take the last bit, and shift it to the two open possibilities:

    11010
    11001

    Two possibilities = Number total bits-number set bits.

    Now, for each of these two, you can take the next bit, and move it to the two possibilities:

    10110
    10011

    and

    10101
    10011

    Now repeat this for the first bit. Thus you have 2 options for the first bit, 2 options for each of those for the second bit, and 2 options for each of those for the third bit. Since 2 is only Total - Set, you can calculate the number of options for all Total and Set.

    However, getting all of them is a pain, as the number balloons rapidly as Total - Set gets bigger.
    My usual boring signature: Nothing

  11. #11
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,109

    Re: [2005] Find All Binary Combinations...

    Quote Originally Posted by benmartin101
    try this:

    My last sample gave the answer in 50 seconds(on my machine), this one gave it to me in 10seconds.
    vb Code:
    1. Private Sub Combo(ByVal bit As Integer, ByVal x As Integer)
    2.         Dim str As String = ""
    3.         For i As Integer = 0 To x - 1
    4.             str = str + "1"
    5.         Next
    6.         Dim power As Integer = bit
    7.  
    8.         Dim index As Integer = 0
    9.         For i As Integer = 0 To (2 ^ power) - 1
    10.             Dim bitcombo As String = Convert.ToString(i, 2)
    11.             bitcombo = bitcombo.Replace("0", "")
    12.             If bitcombo = str Then
    13.                 index = index + 1 'total number of times it appeared
    14.             End If
    15.         Next
    16.        
    17.     End Sub

    bit is corresponds to 23 and x corresponds to 15
    Nice, using the stringbuilder to create str should be slightly faster, and << in place of the ^ would be VERY slightly faster (it would only be evaluated once).

    Wouldn't the length of the bitCombo remove the need for str entirely? After all, str is a bunch of 1's of length x.
    My usual boring signature: Nothing

  12. #12
    Frenzied Member
    Join Date
    Jul 2005
    Posts
    1,168

    Re: [2005] Find All Binary Combinations...

    Yes, your right about the str part. Instead of comparing the two strings, you just compare to make sure it's the proper length, and in that example, 15.

  13. #13

    Thread Starter
    Frenzied Member circuits2's Avatar
    Join Date
    Sep 2006
    Location
    Kansas City, MO
    Posts
    1,027

    Re: [2005] Find All Binary Combinations...

    Thank you both for your suggestions. The string portion is actually needed in later stages so I implemented your StringBuilder idea. I also converted my mathematical calculations to bit shifting, which I had not considered before and am glad you suggested it. All in all you have helped me reduce the processing time from about 90 seconds to approx. 23.

    I noticed what seemed to be a fundamental flaw in my calculations and made a slight adjustment. The new version gives me a significantly different answer so I was wondering if either of you could verify my results. When searching for every combination of 15 in a 23 bit word, I now get a result of 490,314 combinations. Before I was getting 170,544.

    Here is the current code:

    Code:
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    
         ' CLEAR LAST RESULTS
         Me.Label3.Text = ""
    
         Dim fdrMax As Integer = 15
         Dim fdrInv As Integer = 23
         Dim combos As Integer = 0
         Dim binWord As New StringBuilder(fdrInv)
         Dim foundHighs As Integer = 0
    
         ' SET BOUNDARIES
         Dim starter As Int64 = (1 << fdrMax) - 1
         Dim stopper As Int64 = (1 << fdrInv) - 1
    
         ' START MAIN LOOP
         For runner As Int64 = starter To stopper Step 1
    
              ' LOOP THROUGH VALUE AND VERIFY SET BITS
              For cnt As Integer = 1 To fdrInv
                   If runner And (1 << (cnt - 1)) Then
                        binWord.Insert(0, "1")
                        foundHighs += 1
                   Else
                        binWord.Insert(0, "0")
                   End If
              Next cnt
    
              ' IF SET BITS = fdrMax THEN ADD TO COMBOS
              If foundHighs = fdrMax Then
                   combos += 1
              End If
    
              ' RESET WORD AND HIGHS FOR NEXT LOOP
              binWord.Remove(0, fdrInv)
              foundHighs = 0
    
         Next runner
    
         Me.Label3.Text = combos & " combinations were found!"
    
    End Sub
    Show the love! Click (rate this post) under my name if I was helpful.

    My CodeBank Submissions: How to create a User Control | Move a form between Multiple Monitors (Screens) | Remove the MDI Client Border | Using Report Viewer with Visual Studio 2012 Express

  14. #14
    Fanatic Member
    Join Date
    Nov 2006
    Posts
    675

    Re: [2005] Find All Binary Combinations...

    When searching for every combination of 15 in a 23 bit word, I now get a result of 490,314 combinations. Before I was getting 170,544.
    The number of results is just Combination(23, 15). You can verify your results by solving that. It has to do with factorials and dividing by differences of factorials. It isn't very hard, if you can find the equation.
    VB.Net 2008
    .Net Framework 2.0

    "Must you breathe? 'Cause I need heaven..."

  15. #15

    Thread Starter
    Frenzied Member circuits2's Avatar
    Join Date
    Sep 2006
    Location
    Kansas City, MO
    Posts
    1,027

    Re: [2005] Find All Binary Combinations...

    Actually, you cannot use that method. Since I am counting in binary, then I am not considering ABC and CAB to be two different combinations. The factorial method, which I agree is quite simplistic, considers rearranged combinations to be different.

    I.E.

    ABC CAB BCA
    Factorials would see this as 3 combinations
    Binary sees all three as 1 single combination


    Edit: Also, the equation you referred to is 23 x 22 x 21 x 20 .. etc until you have multiplied 15 numbers. It's called permutations.
    Last edited by circuits2; Mar 6th, 2007 at 11:50 AM.
    Show the love! Click (rate this post) under my name if I was helpful.

    My CodeBank Submissions: How to create a User Control | Move a form between Multiple Monitors (Screens) | Remove the MDI Client Border | Using Report Viewer with Visual Studio 2012 Express

  16. #16
    Fanatic Member
    Join Date
    Nov 2006
    Posts
    675

    Re: [2005] Find All Binary Combinations...

    ABC CAB BCA
    Factorials would see this as 3 combinations
    Binary sees all three as 1 single combination
    You are speaking of permutations there. Order does not matter in combinations, it does matter in permutations.

    Think of your problem as 23 spaces, and you have to pick 15 spaces. Thats a combination.

    I am almost positive I am right, but either way, just look up both. Your answer is either C(23, 15) or P(23, 15). You can verify which is correct by using two small number like 2 and 6. Work it out by hand and see which equation gives you the correct result.

    EDIT: I would look it up myself, but I can't now.

    EDIT EDIT: If I remember correctly, P(x, y) is x!/y!. In this case, 23!/15!, or 23 x 22 x 21 x 20 x 19 x 18 x 17 x 16 = 19769460480. This seems pretty big. I don't remember what C(x, y) is, but I do remember that calculating combinations requires calculating permutations.
    Last edited by 18experience; Mar 6th, 2007 at 12:23 PM.
    VB.Net 2008
    .Net Framework 2.0

    "Must you breathe? 'Cause I need heaven..."

  17. #17

    Thread Starter
    Frenzied Member circuits2's Avatar
    Join Date
    Sep 2006
    Location
    Kansas City, MO
    Posts
    1,027

    Re: [2005] Find All Binary Combinations...

    You are using C() and P() as though they are functions or methods. I see where they are available in C#, but have not been able to find them in VB. Can you shed any light on this?
    Show the love! Click (rate this post) under my name if I was helpful.

    My CodeBank Submissions: How to create a User Control | Move a form between Multiple Monitors (Screens) | Remove the MDI Client Border | Using Report Viewer with Visual Studio 2012 Express

  18. #18
    Fanatic Member
    Join Date
    Nov 2006
    Posts
    675

    Re: [2005] Find All Binary Combinations...

    Sorry, I wasn't meaning to imply that they are functions or methods in VB, because they are not. I guess I should have just reposted instead of editing twice, but it look above, that is the formula for a permutation.

    All you need to do is create a Factorial function, which should be fun, provided you enjoy recursion. You can then use your Factorial function to create a Permutation function, and use that Permutation function to create a Combination function. All a combination uses are permutations, subtraction, and division.
    VB.Net 2008
    .Net Framework 2.0

    "Must you breathe? 'Cause I need heaven..."

  19. #19
    Fanatic Member
    Join Date
    Nov 2006
    Posts
    675

    Re: [2005] Find All Binary Combinations...

    vb Code:
    1. Private Function Fac(ByVal Num As Long) As Long
    2.         If Num <= 1 Then
    3.             Return 1
    4.         Else
    5.             Return Num * Fac(Num - 1)
    6.         End If
    7.     End Function
    8.  
    9.     Private Function Per(ByVal X As Long, ByVal Y As Long) As Long
    10.         Return Fac(X) / Fac(Y)
    11.     End Function

    There are factorial and permutation. Don't try Per(23, 15) though, it is causing an overflow. I don't know which datatype to use, but Integer and Long both cannot handle Per(23, 15).

    EDIT: You might wanna check, too. I don't remember those formulas very well, but this at least shows you how to do this once you get the formulas that are correct.
    Last edited by 18experience; Mar 6th, 2007 at 01:19 PM.
    VB.Net 2008
    .Net Framework 2.0

    "Must you breathe? 'Cause I need heaven..."

  20. #20
    Fanatic Member
    Join Date
    Nov 2006
    Posts
    675

    Re: [2005] Find All Binary Combinations...

    EDIT: You might wanna check, too. I don't remember those formulas very well, but this at least shows you how to do this once you get the formulas that are correct.
    For instance, I think Per should be:
    vb Code:
    1. Return Fac(X) / Fac(X - Y)
    VB.Net 2008
    .Net Framework 2.0

    "Must you breathe? 'Cause I need heaven..."

  21. #21

    Thread Starter
    Frenzied Member circuits2's Avatar
    Join Date
    Sep 2006
    Location
    Kansas City, MO
    Posts
    1,027

    Re: [2005] Find All Binary Combinations...

    I was able to locate the proper formula online:

    Choose(n,k) = (n * (n-1) * (n-2) * ... * (n-k+1)) / ( 1 * 2 * ... * k)

    which was taken from this MSDN article:
    http://msdn.microsoft.com/msdnmag/is...n/default.aspx

    It confirms my last results of 490,314.


    Thanks for the help!
    Show the love! Click (rate this post) under my name if I was helpful.

    My CodeBank Submissions: How to create a User Control | Move a form between Multiple Monitors (Screens) | Remove the MDI Client Border | Using Report Viewer with Visual Studio 2012 Express

  22. #22
    Fanatic Member
    Join Date
    Nov 2006
    Posts
    675

    Re: [RESOLVED] [2005] Find All Binary Combinations...

    No problem.

    Here is a group of function that can do that.
    vb Code:
    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2.         MsgBox(Com(23, 15))
    3.     End Sub
    4.  
    5.     Private Function Fac(ByVal Num As Decimal) As Decimal
    6.         'Factorial
    7.         If Num <= 1 Then
    8.             Return 1
    9.         Else
    10.             Return Num * Fac(Num - 1)
    11.         End If
    12.     End Function
    13.  
    14.     Private Function Per(ByVal X As Decimal, ByVal Y As Decimal) As Decimal
    15.         'Permutation
    16.         Return Fac(X) / Fac(X - Y)
    17.     End Function
    18.  
    19.     Private Function Com(ByVal X As Decimal, ByVal Y As Decimal) As Decimal
    20.         'Combination
    21.         Return Per(X, Y) / Fac(Y)
    22.     End Function
    Last edited by 18experience; Mar 6th, 2007 at 01:19 PM.
    VB.Net 2008
    .Net Framework 2.0

    "Must you breathe? 'Cause I need heaven..."

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width