Have an idea?

Visit Sawtooth Software Feedback to share your ideas on how we can improve our products.

Randomize list with 4 items never next to each other

I have a list of 19 items that need to be randomized but items 1-4 can never appear next to each other.   I started by creating a random constructed list for items 1-4 and another random constructed list for items 5-19.  I'm having a tough time figuring inserting the random list of the first 4 with the other list so they aren't next to each other but maintain 'random' order.
asked Oct 26 by Jay Rutherford Gold (38,025 points)
Hi Jay,

Can you give an example explaining a bit what sequence is allowed?
Can 3 out of the four appear together? Or they should fully be separate?
Items 1-4 can NEVER appear together.  So items 1-19 are to be randomized, but items 1-4 can never appear together within that randomization.

As of now I created a list where 5-19 are randomized and another list where 1-4 are randomized.  I can then bring them together inserting the each of the 4 randomized items in every 3rd or 4th position, which is not really a true randomization.
I'm generally curious why the whole list is randomized but some items can't be next to each other.  Is this just a weird client request?

I don't know how to do this in one swoop without trying some sort of trial and error, like generate 1 number between 1 and 19, then generate a second number between 1 and 19 and if |Num1-Num2| < 1 make a new Num2 because they are too close and build up to 4 numbers.  That seems like a LOT of code to write.

Maybe there is a "good enough" solution, like generate a random number between 1-4, insert 1st item from random list containing items 1-4, then generate a new number between 1-4 and add it to the first one to get the insert spot for random item 2, and just keep going?
Yeah Brian, it's one of those weird client requests.  I believe I have an acceptable solution.  I've created a randomized list with items 1-4 and then I've taken items 5-19 and randomized them in a new list.  I've then inserted the 4 items this way:

Insert(SysRand(1,3),Q1ListAD,1)
Insert(SysRand(5,7),Q1ListAD,2)
Insert(SysRand(9,11),Q1ListAD,3)
Insert(SysRand(13,15),Q1ListAD,4)


This way I always use position 4,8 and 12 as a buffer between the ones that can't be shown together.  I believe it's 'random enough' to suffice.

1 Answer

0 votes
Please try these constructed list instructions:

Begin Unverified Perl
# Parameters
my $plist = 'list1';
my @items = (1, 2, 3, 4);

# Run
ADD($plist);
foreach my $item (@items) {
    REMOVE($plist, $item);
}
RANDOMIZE();
my $len = LISTLENGTH($plist) - scalar(@items);

my @bannedInserts = ();
while (scalar(@items)) {
    # Choose item to add
    my $addIndex = int(rand(scalar(@items)));
    my $addItem = $items[$addIndex];
    splice(@items, $addIndex, 1);
    
    # Insert
    my @options = ();
    for (my $i = 1; $i <= $len + 1; $i++) {
        my $banned = 0;
        for (my $j = 0; $j < scalar(@bannedInserts) && !$banned; $j++) {
            $banned = $bannedInserts[$j] == $i;
        }
        if (!$banned) {
            push(@options, $i);
        }
    }
    my $insert = $options[int(rand(scalar(@options)))];
    INSERT($insert, $plist, $addItem);
    $len++;
    
    # Update banned indices
    for (my $i = 0; $i < scalar(@bannedInserts); $i++) {
        if ($bannedInserts[$i] > $insert) {
            $bannedInserts[$i] = $bannedInserts[$i] + 1;
        }
    }
    push(@bannedInserts, $insert);
    push(@bannedInserts, $insert + 1);
}
End Unverified


Line 3 must be updated with the name of the predefined list.

If the number of these special items were made much larger, there are some optimizations that would be prudent to make.  But the performance ought to be sufficient for this case.
answered Oct 26 by Zachary Platinum Sawtooth Software, Inc. (156,375 points)
I'm sure Zachary's "wizard like" solution works a treat (as always).

I have had this type of weird request before and I used the INSERT function and generated some random numbers that did not conflict with each other and it worked fine.
...