Have an idea?

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

Constructed List with Prohibitions

I'm trying to create a constructed list that shows 5 random items from a list of 60 items. However, some items can't show up together such as, 1 & 2, or 3, 4, & 5, or 6 & 7, etc. (essentially prohibitions). Do you know the best way to program this so I end up with a list of 5 items that are truly random?
asked Aug 17, 2021 by j.kay (205 points)

1 Answer

0 votes
Interesting question.  I'm not a stats expert, but unless there are certain parallels in your prohibitions, I'm not certain that there is a perfectly fair solution to this problem.  The frequency that the prohibited items appear cannot be the same as the frequency of the non-prohibited items.

A "close enough" solution may be to go through picking items at random, but simply skipping past any items that are not valid with previously selected items.  Here's constructed list instructions that should do just that:

Begin Unverified Perl
# Params
my $items = 60;
my $choose = 5;
my %prohibitions = (
    1 => [2],
    2 => [1],
    3 => [4, 5],
    4 => [3, 5],
    5 => [3, 4],
    6 => [7],
    7 => [6]
);

# Run
my @arr = (1..$items);
my $i = $items;
while ($i--) {
    my $j = int(rand($i + 1));
    next if $i == $j;
    @arr[$i, $j] = @arr[$j, $i];
}

my $selections = 0;
my %banned = ();
while ($selections < $choose) {
    my $item = shift(@arr);
    if (!%banned{$item}) {
        my $prohs = $prohibitions{$item};
        if ($prohs) {
            foreach my $proh (@{$prohs}) {
                $banned{$proh} = 1;
            }
        }
        ADD(PARENTLISTNAME(), $item);
        $selections++;
    }
}
End Unverified
answered Aug 17, 2021 by Zachary Platinum Sawtooth Software, Inc. (201,875 points)
This worked perfectly! Thank you for helping & providing this code!
Error Using Actual Labels
I actually have a follow up question on this. I was testing this and only had numbers as the labels and everything worked perfectly. But once I added the actual labels (they're long sentences) it was giving me error #132. In my error log it says:
System Error:
syntax error at (eval 225) line 28, near "%banned{" syntax error at (eval 225) line 37, near "; }"

When I test locally it works fine, but doesn't work when I upload to our server.
Did you also change any part of the constructed list code when you changed your labels?
The only thing I changed was we have more prohibitions so I added those in but didn't change anything else. This is what my code looks like:
Begin Unverified Perl
# Params
my $items = 60;
my $choose = 5;
my %prohibitions = (
    1 => [2],
    2 => [1],
    3 => [4, 5],
    4 => [3, 5],
    5 => [3, 4],
    6 => [7],
    7 => [6],
    8 => [9],
    9 => [8],
    11 => [12, 13],
    12 => [11, 13],
    13 => [11, 12],
    14 => [15],
    15 => [14],
    16 => [17, 18],
    17 => [16, 18],
    18 => [16, 17],
    20 => [21, 22],
    21 => [20, 22],
    22 => [20, 21],
    23 => [24],
    24 => [23],
    25 => [26, 27],
    26 => [25, 27],
    27 => [25, 26],
    30 => [31],
    31 => [30],
    34 => [35],
    35 => [34],
    37 => [38],
    38 => [37],
    39 => [40, 41],
    40 => [39, 41],
    41 => [39, 40],
    42 => [43, 44],
    43 => [42, 44],
    44 => [42, 43],
    45 => [46],
    46 => [45],
    47 => [48],
    48 => [47],
    50 => [51],
    51 => [50],
    54 => [55],
    55 => [54],
    56 => [57, 58],
    57 => [56, 58],
    58 => [56, 57],
    59 => [60],
    60 => [59]
);
 
# Run
my @arr = (1..$items);
my $i = $items;
while ($i--) {
    my $j = int(rand($i + 1));
    next if $i == $j;
    @arr[$i, $j] = @arr[$j, $i];
}
 
my $selections = 0;
my %banned = ();
while ($selections < $choose) {
    my $item = shift(@arr);
    if (!%banned{$item}) {
        my $prohs = $prohibitions{$item};
        if ($prohs) {
            foreach my $proh (@{$prohs}) {
                $banned{$proh} = 1;
            }
        }
        ADD(PARENTLISTNAME(), $item);
        $selections++;
    }
}
End Unverified
It must be that Perl is running with different restrictions between your local and server environments.  If you replace "%" with "$" on line 71, does that work better?
Yep that seemed to be the issue. Thanks again for the help!
...