Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm - generating all combinations from items that must be chosen in sequence

I'm looking to find out if a particular algorithm already exists. I want to use it in an application, but I've also seen this come up in several Project Euler problems too.

I'm looking to calculate a specific type of permutation/output set, where the next item chosen must be one from a finite set of options in only the following set.

For example, say I've got 3 arrays

$a1 = array("a", "b", "c");
$a2 = array("d", "e", "f");
$a3 = array("g", "h", "i");

I'm looking to generate all the possibilities of a sequence containing at most 1 element from each array, chosen in order. That is to say as output, I'd like to see:

adg aeg afg
adh aeh afh
adi aei afi

bdg beg bfg 
bdh beh bfh
bdi bei bfi

cdg ceg cfg
cdh ceh cfh
cdi cei cfi

Looking to implement the algorithm in either PHP or Javascript. In essence it will go through a variable number of arrays containing a variable number of elements, and output all of the possiblities of sequences that can occurr in sequential order.

Does this exist?

If so, what is it called? Technically this isnt a permutation or a combination from what I know about both.

EDIT: Daniel Fischer has informed me this is a Cartesian product, here is an implementation taken from the PHP website:

function array_cartesian_product($arrays)
{
    $result = array();
    $arrays = array_values($arrays);
    $sizeIn = sizeof($arrays);
    $size = $sizeIn > 0 ? 1 : 0;
    foreach ($arrays as $array)
        $size = $size * sizeof($array);
    for ($i = 0; $i < $size; $i ++)
    {
        $result[$i] = array();
        for ($j = 0; $j < $sizeIn; $j ++)
            array_push($result[$i], current($arrays[$j]));
        for ($j = ($sizeIn -1); $j >= 0; $j --)
        {
            if (next($arrays[$j]))
                break;
            elseif (isset ($arrays[$j]))
                reset($arrays[$j]);
        }
    }
    return $result;
}
like image 628
barfoon Avatar asked Nov 04 '22 10:11

barfoon


1 Answers

It's a cartesian product, if exactly one item is chosen from each list/array, more precisely a list of the elements of the cartesian product. For lists, it's in Haskell's standard library:

Prelude> sequence ["abc","def","ghi"]
["adg","adh","adi","aeg","aeh","aei","afg","afh","afi","bdg","bdh","bdi","beg","beh"
,"bei","bfg","bfh","bfi","cdg","cdh","cdi","ceg","ceh","cei","cfg","cfh","cfi"]

I think for PHP or Javascript, you have to code it yourself.

like image 160
Daniel Fischer Avatar answered Nov 09 '22 05:11

Daniel Fischer