Author Topic: Ordered Combinations Generator  (Read 2804 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Ordered Combinations Generator
« on: September 08, 2020, 02:09:51 pm »
An Ordered Combinations Generator is a beautiful thing :) (using letters to represent elements in a set)

Code: QB64: [Select]
  1. _TITLE "Generate all the combination subsets of an n element set" ' b+ 2020-09-08
  2. DEFLNG A-Z
  3. DIM set$, N, j, i, idx, L$, k, tot, test$
  4. ' we will use letters to represent each element of the set
  5. set$ = "abcdefg" ' for starters try a 7 element set
  6.  
  7. N = LEN(set$)
  8. 'should be 2^n sets of combinations
  9. DIM subsets$(0 TO N), Counts(0 TO N)
  10.  
  11. 'designate the empty set as *
  12. subsets$(0) = "*"
  13. Counts(0) = 1
  14. ' the single element sets
  15. FOR j = 1 TO N
  16.     IF j = 1 THEN
  17.         subsets$(1) = MID$(set$, j, 1)
  18.     ELSE
  19.         subsets$(1) = subsets$(1) + "," + MID$(set$, j, 1)
  20.     END IF
  21. Counts(1) = N
  22. FOR i = 2 TO N ' number of elements
  23.     REDIM iM$(1)
  24.     idx = 0
  25.     Split subsets$(i - 1), ",", iM$()
  26.     'try to add the jth element to the i-1 subset to make a subset of i elements
  27.     FOR j = 1 TO N
  28.         L$ = MID$(set$, j, 1)
  29.         FOR k = j TO UBOUND(iM$)
  30.             IF INSTR(iM$(k), L$) = 0 THEN ' make a new set of i elements
  31.                 test$ = sorted$(iM$(k), L$)
  32.                 IF INSTR(subsets$(i), test$) = 0 THEN 'not added yet
  33.                     idx = idx + 1
  34.                     IF idx = 1 THEN
  35.                         subsets$(i) = test$
  36.                     ELSE
  37.                         subsets$(i) = subsets$(i) + "," + test$
  38.                     END IF
  39.                 END IF
  40.             END IF
  41.         NEXT
  42.         Counts(i) = idx
  43.     NEXT
  44.  
  45. FOR i = 0 TO N
  46.     tot = tot + Counts(i)
  47.     PRINT Counts(i); ": "; subsets$(i)
  48. PRINT tot; " total subsets when N ="; N
  49.  
  50. FUNCTION sorted$ (sort$, L$)
  51.     DIM i, m$, b$, added
  52.     FOR i = 1 TO LEN(sort$)
  53.         IF L$ < MID$(sort$, i, 1) THEN EXIT FOR
  54.     NEXT
  55.     sorted$ = MID$(sort$, 1, i - 1) + L$ + MID$(sort$, i)
  56.  
  57. 'notes: REDIM the array(0) to be loaded before calling Split '<<<< IMPORTANT dynamic array and empty, can use any lbound though
  58. 'This SUB will take a given N delimited string, and delimiter$ and create an array of N+1 strings using the LBOUND of the given dynamic array to load.
  59. 'notes: the loadMeArray() needs to be dynamic string array and will not change the LBOUND of the array it is given.  rev 2019-08-27
  60. SUB Split (SplitMeString AS STRING, delim AS STRING, loadMeArray() AS STRING)
  61.     DIM curpos AS LONG, arrpos AS LONG, LD AS LONG, dpos AS LONG 'fix use the Lbound the array already has
  62.     curpos = 1: arrpos = LBOUND(loadMeArray): LD = LEN(delim)
  63.     dpos = INSTR(curpos, SplitMeString, delim)
  64.     DO UNTIL dpos = 0
  65.         loadMeArray(arrpos) = MID$(SplitMeString, curpos, dpos - curpos)
  66.         arrpos = arrpos + 1
  67.         IF arrpos > UBOUND(loadMeArray) THEN REDIM _PRESERVE loadMeArray(LBOUND(loadMeArray) TO UBOUND(loadMeArray) + 1000) AS STRING
  68.         curpos = dpos + LD
  69.         dpos = INSTR(curpos, SplitMeString, delim)
  70.     LOOP
  71.     loadMeArray(arrpos) = MID$(SplitMeString, curpos)
  72.     REDIM _PRESERVE loadMeArray(LBOUND(loadMeArray) TO arrpos) AS STRING 'get the ubound correct
  73.  
  74.  

an almost ordered bplus.PNG
* an almost ordered bplus.PNG (Filesize: 5.41 KB, Dimensions: 418x164, Views: 269)
« Last Edit: September 08, 2020, 02:24:16 pm by bplus »

Offline DANILIN

  • Forum Regular
  • Posts: 128
    • Danilin youtube
Re: Ordered Combinations Generator
« Reply #1 on: September 08, 2020, 02:46:42 pm »
Formula for N digital is Sx combination

S2 = N*(N-1) / (1*2)
for N=5: S2 = 5*4/2 = 20/2 = 10

S3 = N*(N-1)*(N-2) / (1*2*3)
for N=5: S3 = 5*4*3/6 = 60/6 = 10

S4 = N*(N-1)*(N-2)*(N-3) / (1*2*3*4)
for N=5: S3 = 5*4*3*2/24 = 120/24 = 5

Visualization:

 
komblife.gif
Russia looks world from future. big data is peace data.
https://youtube.com/playlist?list=PLBBTP9oVY7IagpH0g9FNUQ8JqmHwxDDDB
i never recommend anything to anyone and always write only about myself

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Ordered Combinations Generator
« Reply #2 on: September 08, 2020, 03:15:57 pm »
But for completely ordered sets specially in the subset of 1 element sets you must start with letters in order.

Here is example of disorder:
 
DANILin.PNG


BTW who knew that the number of proper subsets of a set with N elements is 2^N? = number of all combinations you can make with N things.

Right, Pascal knew.
« Last Edit: September 08, 2020, 06:45:43 pm by bplus »

Offline Rubidium

  • Newbie
  • Posts: 10
Re: Ordered Combinations Generator
« Reply #3 on: October 06, 2020, 07:18:30 pm »
Code: QB64: [Select]
  1. DIM q(20) AS _UNSIGNED INTEGER 'index digit holders
  2. DIM A$(26) 'sample space of the alphabet
  3.  
  4. FOR i = 1 TO 26 'create an alphabet deck of cards A$()
  5.     A$(i) = CHR$(64 + i)
  6.  
  7.  
  8. n = 7 'number of different characters to use
  9. u = 1 ' initialize by choosing 1 of n characters skipping the combination of nothing 7 C 0
  10.  
  11. PRINT "CHARACTERS n:"; n
  12. OPEN "combination_space.csv" FOR OUTPUT AS #1
  13.  
  14.     'combination counter
  15.     q(1) = q(1) + 1
  16.  
  17.     IF q(1) > n THEN
  18.         FOR i = 1 TO u 'as in nCu: where u is the current number of "digits"
  19.             IF q(i) > n - i + 1 THEN 'digit combination limit
  20.                 q(i + 1) = q(i + 1) + 1
  21.                 FOR k = (i) TO 1 STEP -1
  22.                     q(k) = q(k + 1) + 1
  23.                 NEXT k
  24.                 IF i = u THEN u = u + 1
  25.             END IF
  26.         NEXT i
  27.     END IF
  28.  
  29.     '// BELOW IS JUST FOR DISPLAY
  30.     S$ = ""
  31.     PRINT #1, " ,";
  32.     FOR i = 1 TO u
  33.         PRINT "["; RIGHT$(STR$(u - i + 1), 1); "]";
  34.         PRINT #1, "q["; RIGHT$(STR$(u - i + 1), 1); "],";
  35.     NEXT i
  36.     PRINT #1, ""
  37.     PRINT
  38.  
  39.  
  40.     FOR i = 1 TO u
  41.         S$ = A$(q(i)) + S$
  42.         PRINT q(u - i + 1);
  43.     NEXT i
  44.     PRINT #1, S$; ",";
  45.     FOR i = 1 TO u
  46.         PRINT #1, q(u - i + 1); ",";
  47.     NEXT i
  48.  
  49.     PRINT " = "; S$
  50.  
  51.     PRINT #1, ""
  52.     PRINT #1, ""
  53.     PRINT
  54.     SLEEP
  55. LOOP UNTIL u = n
  56. PRINT "COMPLETED TOTAL COMBOS"
  57.  
  58.  


I made a similar one too so I thought I'd post.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Ordered Combinations Generator
« Reply #4 on: October 06, 2020, 07:39:07 pm »
@Rubidium

Nice! welcome to the forum.

With the empty set, the number of subsets or combinations add up to 2^N where N = number of elements but maybe you know already :)

Offline Rubidium

  • Newbie
  • Posts: 10
Re: Ordered Combinations Generator
« Reply #5 on: October 06, 2020, 07:43:37 pm »
I didn't until I read your post :)

It's amazing how that works out.

Marked as best answer by bplus on October 15, 2020, 08:25:18 am

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Ordered Combinations Generator
« Reply #6 on: October 15, 2020, 12:22:19 pm »
This might be an even better way to get combination listings, eg don't need split and sort at all!

Code: QB64: [Select]
  1. _TITLE "Simple method to generate combinations of n items" ' b+ 2020-10-15
  2.  
  3. ' decisions: powers are base 0 so keep items$() array also base 0
  4. ' number of anything is usually base 1 so if we say number of items it would go from 1 to n
  5. ' but if we say topItemIndex we have a base 0 item count for accessing array wo errors.
  6. ' So call number of items base 1 >>> topIndex = nItems -1
  7.  
  8. DEFLNG A-Z
  9.     INPUT "Item to add to set for combos, nothing to end list "; item$
  10.     IF item$ <> "" THEN 'item is not nothing
  11.         nItems = nItems + 1 ' number is base 1
  12.         items$(nItems - 1) = item$ 'add n-th item to 0 based array
  13.         'increment the index and
  14.         IF nItems + 1 > 10 THEN EXIT DO ' keep count at 10 or less so don't need to DIM an array
  15.     ELSE
  16.         EXIT DO
  17.     END IF
  18.  
  19. ' generating listings of combos
  20. topComboIndex = 2 ^ nItems - 1 ' base 0 array
  21. FOR i = 0 TO topComboIndex ' just going to print but could make list in array or process combo immediately
  22.     b$ = "" ' for building a combination
  23.     FOR power = 0 TO nItems - 1
  24.         IF i AND 2 ^ power THEN
  25.             IF b$ = "" THEN b$ = items$(power) ELSE b$ = b$ + ", " + items$(power)
  26.         END IF
  27.     NEXT
  28.     PRINT i + 1; "= "; b$, 'the combiunation built
  29.  

EDIT: previous code was working but it was confusing why. For sake of clarity like I might need to use this some time in future I renamed variables and reworked code around the count of how many items we will make combinations with. For n items you will get 2 ^ n combinations the first will be the empty set or nothing.

The conflict between base 1 stuff and base 0 stuff really gave me a headache today but I think I have it cleared now.

« Last Edit: October 15, 2020, 04:04:04 pm by bplus »

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
Re: Ordered Combinations Generator
« Reply #7 on: October 15, 2020, 06:22:03 pm »
Not really adding much to the discussion, but this kind of thinking lends itself to some interesting --- notation? For lack of a better word.

Remember when we did the play problem of finding a secret message inside a jumble of random text? Steve and bplus had loops and INSTR based answers, but I went a weird statistical way, documented here:

http://wfbarnes.net/homedata/Ordo%20Ab%20Chao.pdf

Point is, the combination lists bplus is going after are what I called the phi-sequences. (When I get to a PC I'll actually run the code.)

Any direct application in mind so far?
« Last Edit: October 15, 2020, 06:23:15 pm by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Ordered Combinations Generator
« Reply #8 on: October 15, 2020, 07:20:11 pm »
Quote
Any direct application in mind so far?

I've used it in Knapsack problem from Rosetta Code when I learned my first approach will not work generally for such like problems, the combination approach does.
 https://www.qb64.org/forum/index.php?topic=3091.msg124013#msg124013

Also used combinations to optimize a Gin Hand. When a card intersects a Straight set and a group set have to decide which set to use it because can't be used in both. So run through all combinations of using intersect cards in one set or the other and see which returns highest points and / or least deadwood.
https://www.qb64.org/forum/index.php?topic=2550.msg123905#msg123905

I intend to update my Gin Hand Optimizer code with this generator code to dump outside Combination Tables and do more conventional Gin Game variations.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
Re: Ordered Combinations Generator
« Reply #9 on: October 15, 2020, 08:12:36 pm »
This stuff is interesting - I just skimmed across an article earlier that was all about the end of "luck" in gambling, in that Han Solo kind of way - because we are so good nowadays at calculating probabilities on the fly - gambling and gaming in general is thick with applied science these days...
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Ordered Combinations Generator
« Reply #10 on: October 15, 2020, 09:26:27 pm »
Yeah business has been gambling scientifically for centuries.