Using php, I am looking to find a set of unique combinations of a specified length while making sure that no two identical values are present in more than one combination. For example, if I want to find all unique combinations of 3 values (fallback to combinations of 2 values if 3 are not possible) with this array:
$array = array(
array('1', '2'),
array('3', '4'),
array('5', '6'),
);
One possible set of combinations is 123, 456, 14, 15, 16, 24, 25, 26, 34, 35, 36 Note that each number is always combined once and only once with a different number. No duplicate number pairs show up in any combination. Just for clarity's sake, even though 123 and 135 would be unique combinations, only one of these would be returned since the pair 13 occurs in both. The main criteria is that all numbers are eventually grouped with each other number, but only once.
In the final product, the number of arrays and number of values will be notably larger as in:
$array = array(
array('1', '2', '3', '4', '5', '6', '7', '8'),
array('9', '10', '11', '12', '13', '14', '15', '16'),
array('17', '18', '19', '20', '21', '22', '23', '24'),
array('25', '26', '27', '28', '29', '30', '31')
);
Any help/code to accomplish this would be most appreciated.
UPDATE:
I've taken the brute force approach. First off, I'm using the pear package Math_Combinatorics to create the combinations, starting with a specified maximum size grouping and working my way down to pairs. This way I can get all possible combinations when iterating through to strip out any duplicate clusters within the groups. This code works but is extremely memory intensive. Generating all combinations for an array of 32 values in groups of 6 uses an excess of 1.5G of memory. Is there a better algorithm or approach that will let me use bigger arrays without running out of memory? Here the current state of the code:
require_once 'Combinatorics.php';
$combinatorics = new Math_Combinatorics;
$array = range(1,20,1);
$maxgroup = (6);
$combinations = $combinatorics->combinations($array, $maxgroup);
for($c=$maxgroup-1;$c>1;$c--)
{
$comb = $combinatorics->combinations($array, $c);
$combinations = array_merge($combinations, $comb);
$comb = null;
}
for($j=0;$j<sizeof($combinations);$j++)
{
for($i=sizeof($combinations)-1;$i>=$j+1;$i--)
{
$diff = array_intersect($combinations[$j], $combinations[$i]);
if(count($diff)>1)
{
unset($combinations[$i]);
}
}
$combinations = array_values($combinations);
}
print_r($combinations);