2012-02-04 7 views
1

異なる組み合わせを生成するには効率的なアルゴリズムが必要です(繰り返すことはできません)。各組み合わせには、1〜99の範囲の5つのDistint番号(異なる番号)があります。結果は配列に格納する必要があります。可能であれば、番号と範囲をカスタマイズすることを許可したいと思います。番号の順序は関係ありません(01 02 03 = 03 01 02)異なる組み合わせを生成するPHP

Ex.: 
01 02 03 04 05 
02 03 04 05 06 
... 

誰でも私の作成に手伝ってもらえますか?私は配列からいくつかのランダムな組み合わせを拾いたいと思います。今、私はmt_randを使ってランダムな組み合わせを生成していますが、時間がかかりすぎるので遅いです!私は頻繁に繰り返すことが起こると信じて、新しいものと新しいものを生成する時間がかかります...

+0

fisher-yates shuffleを検索します。 –

+0

あなたはこれを行うために必要なメモリ量を認識していますか? 199から5の71,523,144のユニークな組み合わせがあります。実際にすべての組み合わせを知る必要があるのはなぜですか?それらをすべて作業するより良い選択肢はほとんどありません。必要な数のシャッフルされたユニークを生成するだけで、71,523,144よりはるかに少ないでしょう。 –

+0

[ループ速度を下げる方法]の複製が可能です(http://stackoverflow.com/questions/3109887/how-to-reduce-for-loop-speed) –

答えて

1

私はこれをすばやく投げて動作するようです。

<?php 

$range_low = 1; 
$range_hi = 99; 
$num_sets = 10; 

$set = generateSet($range_low, $range_hi, $num_sets); 

print_set($set); 

function generateSet($range_low, $range_hi, $numSets = 5, $numPerSet = 5) 
{ 
    $return = array(); 
    $numbers = array(); 

    for($i = $range_low; $i <= $range_hi; ++$i) { 
     $numbers[] = $i; 
    } 

    for ($s = 0; $s < $numSets; ++$s) { 
     $set = array_values($numbers); 
     shuffle($set); 

     $return[$s] = array(); 

     for ($i = 0; $i < $numPerSet; ++$i) { 
      $val = array_shift($set); 
      $return[$s][] = $val; 
     } 
    } 

    return $return; 
} 

function print_set($set) 
{ 
    foreach($set as $subset) { 
     foreach($subset as $value) { 
      echo str_pad($value, 2, '0', STR_PAD_LEFT) . ' '; 
     } 
     echo "\n"; 
    } 
} 

出力例:

90 75 89 43 57 
24 54 38 35 10 
77 21 55 33 83 
37 15 61 09 44 
25 31 85 17 20 
48 37 45 13 20 
82 70 74 64 72 
07 24 33 64 45 
34 13 39 33 05 
13 77 87 70 64 

フィッシャーイエーツに配列をシャッフル、あなたがシャッフルの代わりに使用できる機能についてthis comment on shuffleを参照してください。

希望に役立ちます。あなたが本当に絶対に可能なすべての組み合わせのフルセットが必要な場合は

+0

質問に記載されているように、これらの組み合わせは繰り返すことはできません。 1-99の場合、非常にまれに繰り返されますが、1-10のようなものを選択すると、コードで重複が多く発生します – Ranty

+0

配列から値をシフトして、同じセットで繰り返すことはできません値は配列から削除され、再度選択することはできません。 – drew010

+0

私はセット内で同じ数字を言っているわけではありません。私はそれが同じセットを生産すると言っている。 – Ranty

1

function combinations($set,$length) { 
    $combinations = array(); 

    $setCount = count($set); 
    for($i = 0, $n = $setCount; $i <= ($n - $length); $i++) { 
    $combination = array(); 
    $combination[] = $set[$i]; 

    if($length > 1) { 
     $combination = array_merge( 
     $combination, 
     combinations(array_slice($set,1+$i), $length-1) 
    ); 
    } 

    $combinations[] = $combination; 
    } 

    return $combinations; 
} 

$allYourNumbers = range(1,99); 
$allCombinations = combinations($allYourNumbers, 5); 

は、その後、あなたは$ allCombinationsをシャッフルし、好きなだけを抽出していますが、多くのメモリと多くをする必要がありますすることができます時間の...これを行うことができます決して効率的

1

ここでは、はるかに速く実行する必要がありますあなたが説明する簡単なコードです。

$numbers = range(1, 99); // numbers to pick from 
$length = 5; // amount of items in the set 
$sets_amount = 15; // amount of sets you want to generate 
shuffle($numbers); // randomize 

function get_set($length, &$numbers) { 
    return array_splice($numbers, 0, $length); 
} 

for ($i = 0; $i < $sets_amount; $i++) 
    print_r(get_set($length, $numbers)); 

注:いくつかの組み合わせが必要な場合にのみ機能します。あなたは可能なものすべてが欲しいと述べていないので、私はあなたがそれらの束を必要とすると思った - ここでそれを行うには非常に簡単かつ簡単な方法です。

少し遅く(生成するほど遅くなる)、を生成します。の量があれば、このコードを使用できます。

$numbers = range(1, 99); // numbers to pick from 
$length = 5; // amount of items in the set 
$sets_amount = 200; // amount of sets you want to generate 
$existing = array(); // where we store existing sets 
$shuffle_period = count($numbers) - $length - 1; // how often we re-randomize the elements 
$j = 0; 

for ($i = 0; $i < $sets_amount; $i++, $j++) { 
    if (!($i % $shuffle_period)) { 
     shuffle($numbers); // randomize at first go and on $shuffle_period 
     $j = 0; 
    } 
    do { 
     $arr = array_slice($numbers, $j, $length); 
    } while (in_array($arr, $existing)); 
    $existing[] = $arr; 
} 

print_r($existing); 
関連する問題