Note that there are some explanatory texts on larger screens.

plurals
  1. PORandomize matrix in perl, keeping row and column totals the same
    text
    copied!<p>I have a matrix that I want to randomize a couple of thousand times, while keeping the row and column totals the same:</p> <pre><code> 1 2 3 A 0 0 1 B 1 1 0 C 1 0 0 </code></pre> <p>An example of a valid random matrix would be:</p> <pre><code> 1 2 3 A 1 0 0 B 1 1 0 C 0 0 1 </code></pre> <p>My actual matrix is a lot bigger (about 600x600 items), so I really need an approach that is computationally efficient.</p> <p>My initial (inefficient) approach consisted of shuffling arrays using the <a href="http://oreilly.com/catalog/9780596003135" rel="nofollow noreferrer">Perl Cookbook</a> <a href="http://faq.perl.org/perlfaq4.html#How_do_I_shuffle_an_" rel="nofollow noreferrer">shuffle</a></p> <p>I pasted my current code below. I've got extra code in place to start with a new shuffled list of numbers, if no solution is found in the while loop. The algorithm works fine for a small matrix, but as soon as I start scaling up it takes forever to find a random matrix that fits the requirements.</p> <p>Is there a more efficient way to accomplish what I'm searching for? Thanks a lot!</p> <pre><code>#!/usr/bin/perl -w use strict; my %matrix = ( 'A' =&gt; {'3' =&gt; 1 }, 'B' =&gt; {'1' =&gt; 1, '2' =&gt; 1 }, 'C' =&gt; {'1' =&gt; 1 } ); my @letters = (); my @numbers = (); foreach my $letter (keys %matrix){ foreach my $number (keys %{$matrix{$letter}}){ push (@letters, $letter); push (@numbers, $number); } } my %random_matrix = (); &amp;shuffle(\@numbers); foreach my $letter (@letters){ while (exists($random_matrix{$letter}{$numbers[0]})){ &amp;shuffle (\@numbers); } my $chosen_number = shift (@numbers); $random_matrix{$letter}{$chosen_number} = 1; } sub shuffle { my $array = shift; my $i = scalar(@$array); my $j; foreach my $item (@$array ) { --$i; $j = int rand ($i+1); next if $i == $j; @$array [$i,$j] = @$array[$j,$i]; } return @$array; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload