根据唯一性级别

时间:2016-12-26 23:55:50

标签: php arrays sorting combinations

我正在尝试创建一个输入4个参数的函数:

function getUniqueSubsets($num_arr, $subset_count, $subset_size, $uniq_level)

哪里

  1. $num_arr - n个数组。
  2. $subset_size - 子集大小
  3. $subset_count - 子集数量
  4. $uniq_level - [1,100]范围之间的数字,表示不正常程度。
  5. 所以基于$ uniq_level,我想从数字数组生成数字组合。 $uniq_level基本上是生成的一组组合中唯一元素的百分比。因此,如果我们想要从给定的数字数组中获得100%的唯一组合,我们将给出100并且函数必须生成完全独特的组合。

    如果为1 - 可能会有很多重复。

    我写了一个生成所有可能组合的函数

    function combine_all(array $numbers) {
        $count = count($numbers);
    
        $result = array_map('strval', $numbers);
        for($i = 1; $i < $count; ++$i) {
            $combinations = array_slice($result, pow($count, $i-1));
            foreach($numbers as $number) {
                foreach($combinations as $combination) {
                    $result[] = $number . ',' . $combination;
                }
            }
        }
    
        return $result;
    }
    

    我无法弄清楚,如何实现唯一性百分比以及使用PHP 7.0实现此目的的最高性能效率方法。

    有什么建议吗?是否有任何内置的PHP功能可能在这种情况下有用?

1 个答案:

答案 0 :(得分:1)

我会在这里发表我的想法,这可能不是完美的解决方案。

首先,你的函数正在获取所有可能的数组子集(n ^ n),这太多了,你只需要大小为$ subset_size的子集。让你改变功能以这种方式工作,这是我的解决方案:

function getUniqueSubsets($num_arr, $subset_count, $subset_size, $uniq_level) {
    $candidates = combine_all($arr_num, $subset_size);
    $result = array();
    while ($subset_count > 0 && count($candidates)){
        $possibility = mt_rand(0, mt_getrandmax() - 1) / mt_getrandmax() * 100; // this random formula is from some stackoverflow anser
        if ($possibility > $uniq_level){ // your possibility is bigger than uniq_level needed, so you just add random element
            array_push($result, get_random_and_remove($candidates)); // this should be simple function that gets and removes random element from $candidates array.
        }else{
            $element_to_add = get_next_and_remove($candidates, $result); //I'll do explanation of this function later
            if (!$element_to_add) {
                // there is no next uniq element to be added, program should exit and tell user that it cannot get result
                return false;
            }
            array_push($result, $element_to_add)
        }
        $subset_count--;
    }
    return $result;
}

get_random_and_remove应该很容易实现。棘手的是get_next_and_remove(array $candidates, array $result)。对于这个,我将用语言解释我将如何做到这一点:

  1. 随机化$ candidates array
  2. 从中获取并删除下一个元素
  3. 检查该元素是否足够独特(将其与$ result数组中的元素进行比较) - 这可以通过各种方式完成,您需要决定如何。我的建议是,如果两种组合的元素都少于$subset_size/2 - 1,则它们可能被称为唯一。
  4. 如果所选元素不是唯一的,请转到第2步,直到找到唯一元素并返回它,或者没有更多元素并返回false
  5. 我暂时没有编写PHP,很抱歉可能出现错误,但这个问题与任何语言都无关。如果您需要更多帮助,请不要犹豫,我会扩展解决方案。