views:

120

answers:

4

Given a list of elements, does a shuffling algorithm exist that will guarantee that eventually a selected half portion will be on one side, and the remainder on the other?

Example: { 4, 3, 10, 7, 2, 9, 6, 8, 1, 5 }

Given the set above, I'd like to have a mixing algorithm that eventually moves the marked ones to the left, even though the algorithm itself has no idea what is and isn't "marked."

   { 4, 3, 10, 7, 2, 9, 6, 8, 1, 5 }
     X       X           X  X       X

Acceptable results would be:
   { 4, 10, 9, 6, 1, 3, 7, 2, 8, 5 }
   { 1, 9, 10, 4, 6, 2, 8, 5, 7, 3 }
   { 1, 4, 9, 10, 6, 3, 7, 5, 8, 2 } etc

Difficulty: The algorithm shouldn't use random numbers to mix the contents, it should be an iterative process. So Fisher-Yates is out.

+1  A: 

Would std::next_permutation() be what you want? (Since it creates all possible permutations, it will, eventually, also put the marked once to the left.)

sbi
Yes, it is actually! Thank you very much - I'm going to couple this with an algorithm that checks either side of the list after each permutation to see if the segments have balanced out.
Tim
@Tim: Given the rate at which the number of permutations expands with string size, that's likely to be _extremely_ slow.
Nick Johnson
+4  A: 

Split your list into two lists - flagged and unflagged. Shuffle both sublists, and put the flagged on one side and the unflagged on the other. Now you can use any shuffling algo you want.

glowcoder
+1 although I would extend it to select the half randomly (that is by iterating over the set and removing each element with a probability of one). Else this would lead to only the two halves being swapped repeatedly (and each one permuted).
Dave
@Dave I'm afraid I don't follow. If you're simply selecting them at random first, how is that different than just shuffling it? Perhaps I misunderstood the question?
glowcoder
The algorithm itself needs to be blind to what is and isn't marked. Each result of an iteration will be checked for validity, and if invalid, the process continues.
Tim
@Tim I see you've found your answer, but I'm quite curious! Could you be so kind as to give more context as to 1) How do you know if the given permutation is valid, 2) Why the algorithm cannot know what is flagged, and 3) What is the practical application for this? I'm not trying to be argumentative, in fact the opposite, I'd like to learn. Help me knowledge++!
glowcoder
@glowcoder I didn't think about that, just noticed that Your solution doesn't fulfill the requirement 100%. You have a valid point though: Where's the difference between permutation of the whole set and randomly selecting half of it and permuting both halves. Would be nice if someone with better math skills than me can show the equality (I'm guessing here) of both approaches.
Dave
A: 

Something like next_permutation will do the job, and (eventually) so will something like bogo sort. Either will eventually produce every possible permutation, including all the permutations you consider acceptable (along with some arbitrary number you don't).

Bogo sort shows that your: "The algorithm shouldn't use random numbers to mix the contents, it should be an iterative process. So Fisher-Yates is out." is a false dichotomy. Bogo sort mixes randomly and it's iterative.

Jerry Coffin
Less a false dichotomy and more of a requirement: I require the algorithm to not use randomness, but I'm not saying the goal can't be accomplished using it and iteration. Rather, Bogosort is just a random shuffling until an answer is found. Worst case complexity: is O(inf) and average is O(n * n!).
Tim
A: 

I think you are looking for an algorithm that: * Can be used to display a iterative process to a user that looks something like shuffling * Ends up with the original set separated into 2 (preselected) groups but randomly ordered within each group

Seems to me that something simple might suit you well consider for your ten numbers and using the terminology marked/unmarked for the groups this algorithm:

1. Randomly select two members of the set
2. if swapping these two members would result in a marked number 
     being moved into positions 1-5 then forget about this swap and start again
3. Swap these elements
4. Check if positions 1-5 have ONLY marked elements, 
     if so you are done, otherwise start again

This doesn't give an efficient statistically good shuffle like Fisher-Yates but does give you a good looking on screen mix up.

Elemental