Permutace

Školení, která pořádám

Občas (např. při luštění šifer) potřebuji pracovat s permutacemi. K tomu lze přistoupit dvěma způsoby – buď si pokaždé napsat funkci, která bude s permutací přímo pracovat tak, jak je potřeba, nebo napsat funkci, která vygeneruje všechny permutace, se kterými budeme pracovat až mimo ni. Druhý způsob je jistě univerzálnější:

<?php
/** Vygenerování permutací
* @param array pole z prvky, ze kterých se má permutace vytvořit, např. range(1, 2)
* @return array pole všech permutací, např. array(array(1, 2), array(2, 1))
* @copyright Jakub Vrána, http://php.vrana.cz/
*/
function permutace($prvky) {
    if (count($prvky) == 1) {
        return array($prvky);
    }
    $return = array();
    foreach ($prvky as $prvek) {
        foreach (permutace(array_diff($prvky, array($prvek))) as $zbytek) {
            $return[] = array_merge(array($prvek), $zbytek);
        }
    }
    return $return;
}

// použití
foreach (permutace(range(1, 3)) as $permutace) {
    echo implode(", ", $permutace) . "\n";
}
?>

Pro vyřazení prvku z pole se používá funkce array_diff, která prvek musí v poli znovu vyhledat. Rychlejší by nejspíš bylo použít funkci array_splice, která prvek vyjme přímo podle jeho pozice, ale bylo by s tím o něco víc práce.

Jakub Vrána, Řešení problému, 25.9.2006, diskuse: 6 (nové: 0)

Diskuse

pif:

moc hezký algoritmus, ale kdybych uvažoval, kde permutace použít v php ;DDD napadlo by mě pravé nefalšované nic. K pozastavení už je jen to, žes to někdy potřeboval.

Qels:

šlo by to přepsat do Céčka?

pif:

tedy kromě těch sterilních soutěží...

Juro Hajdúch:

Kombinatorika je zaujímavá, ale ma napadá (zatiaľ) len jedno použitie - lámanie hesla :-(. Inak dobrá funkcia. Večer sa idem hrať.

jux:

johooo, uz nekoho vidim, jak pomoci jednoho z nejpomalejsich skriptovacich jazyku na svete lusti hesla:))

josef:

    Mám jednu prosbu, potřeboval bych vědět  jednu věc ze života. Byl jsem v restauraci se dvěma kamarádama a číšník  měl 9 druhů různých nápojů, od sladkých až po ty nejtvrdší. Tyto nápoje nám  poprvé rozlil tak, že každý jsme měli   ve sklenici tři druhy nápojů. Dohromad tedy devět. Otázka zní, kolikrát musí číšník nalét  všech devět nápojů do skleniček,  po třech nápojích do skleničky, aby  všichni tři  hosté měli dohromady jinou skladbu nápoje ve skleničkách.  Je jedno jestli  ve skleničce bude nápoj  nahoře, uprostřed nebo dole( např. alžírská káva  vaječný koňak- káva- mléko nebo šlehačka. Obsah sklenice se může i zamýchat.  nevím jak to vypočítat domnívám se že se jedná o permutace. Dík za  odpověd

Vložit příspěvek

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

© 2005-2012 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.