Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
生成不同的PHP组合_Php_Algorithm_Brute Force - Fatal编程技术网

生成不同的PHP组合

生成不同的PHP组合,php,algorithm,brute-force,Php,Algorithm,Brute Force,我需要一个高效的算法来生成不同的组合(不允许重复)。每个组合有5个distint数字(不同的数字),范围在1到99之间。结果必须存储在数组中。如果可能的话,我想允许定制的数字和范围。数字的顺序无关紧要(01 02 03=03 01 02) 有人能帮我建吗?我想从数组中提取一些随机组合。现在,我使用mt_rand生成随机组合,但它需要太多时间,太慢了!我相信经常会重复,然后需要时间来生成一个新的和一个新的…我很快就把它放在一起,似乎有效 <?php $range_low = 1; $ran

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


有人能帮我建吗?我想从数组中提取一些随机组合。现在,我使用mt_rand生成随机组合,但它需要太多时间,太慢了!我相信经常会重复,然后需要时间来生成一个新的和一个新的…

我很快就把它放在一起,似乎有效

<?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";
    }
}
要让Fisher Yates洗牌数组,请参阅以获取可用于代替洗牌的函数


希望能有所帮助。

如果您确实需要一整套可能的组合:

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);
函数组合($set,$length){
$combines=array();
$setCount=计数($set);
对于($i=0,$n=$setCount;$i1){
$combination=array\u merge(
美元组合,
组合(数组_切片($set,1+$i),$length-1)
); 
} 
$compositions[]=$compositions;
} 
返回$组合;
} 
$AllYourNumber=范围(1,99);
$allCombinations=组合($AllYourNumber,5);

然后你可以洗牌$allCombinations并提取你想要的任何数量,但是你需要大量的内存和时间。。。这样做永远不会有效率

下面是一个简单的代码,它应该运行得相当快,并按照您所描述的方式执行

$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=范围(1,99);//可供挑选的数字
$length=5;//集合中项目的数量
$sets_金额=15;//要生成的集合数量
洗牌($number);//随机化
函数get_set($length,&$numbers){
返回数组_拼接($number,0,$length);
}
对于($i=0;$i<$set\u金额;$i++)
打印(获取集合($length,$number));
注意:它只在您需要几个组合时起作用。你没有说你想要所有可能的,所以我想如果你只需要一堆,这里有一个非常简单快捷的方法

对于稍微慢一点(生成的越多,速度就越慢),但是生成的集的数量越少,您可以使用此代码

$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);
$numbers=范围(1,99);//可供挑选的数字
$length=5;//集合中项目的数量
$sets_金额=200;//要生成的集合数量
$existing=array();//存储现有集合的位置
$shuffle\u period=count($numbers)-$length-1;//我们将元素重新随机化的频率
$j=0;
对于($i=0;$i<$set\u金额;$i++,$j++){
如果(!($i%$shuffle\u期间)){
shuffle($numbers);//在第一次尝试时随机化,并在$shuffle_期间随机化
$j=0;
}
做{
$arr=数组\ U片($numbers,$j,$length);
}while(在数组中($arr,$existing));
$existing[]=$arr;
}
印刷(现有);

搜索fisher yates shuffle。您是否意识到执行此操作需要多少内存?共有71523144个来自199年的5个独特组合。为什么你真的需要知道所有可能的组合?几乎可以肯定的是,有一个更好的替代方案来解决这些问题。。。可能只是生成您需要的任意多个混洗单品,这肯定比71523144少很多。可能是@Mark Baker的副本,谢谢您的评论!我考虑过生成一小块,然后提取我想要的组合。现在我使用一个带rand函数的循环,它似乎经常重复数字,然后我不得不再次运行循环,试图再次获得一个不同的组合,当组合开始增加时,它变得非常慢。你可以像中一样,但删除那些字符数高于1的。然后将字符转换为表示数字的字符(或者使用数字范围的数组而不是字符集,稍后在输出数组中使用值计数(而不是字符串))。如问题所述,组合不允许重复。在1-99的情况下,它们将很少重复,但是如果你选择1-10这样的值,那么你的代码将生成大量的重复项。将值从数组中移出,使其不能在同一集中重复,因为该值已从数组中删除,无法再次拾取。我不是说在一个集合中有相同的数字。我是说它会生产同样的产品。
$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);