生成不同的组合PHP

时间:2012-02-04 02:19:57

标签: php algorithm brute-force

我需要一种有效的算法来生成不同的组合(不允许重复)。每个组合有5个不同的数字(不同的数字),范围在1到99之间。结果必须存储在一个数组中。如果可能的话,我希望可以自定义数字和范围。数量顺序无关紧要(01 02 03 = 03 01 02)

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

有没有人可以帮我构建它?我想从数组中获取一些随机组合。现在我使用mt_rand生成随机组合但是它需要太多时间,所以很慢!我相信经常重复,然后需要时间来产生新的......新的...

3 个答案:

答案 0 :(得分: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 

让Fisher-Yates对阵列进行随机播放,请参阅this comment on shuffle以获取可用于替代随机播放的功能。

希望有所帮助。

答案 1 :(得分: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并提取任意数量的内容,但是你需要大量的内存和大量的时间......这样做永远不会高效

答案 2 :(得分: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);