分配选项唯一算法

时间:2015-12-17 17:49:47

标签: php arrays algorithm

我有一个二维数组。每个子阵列都包含许多选项。我正在尝试编写一个脚本,为每一行选择其中一个选项。选择的选项必须是唯一的。一个例子:

$array = array(
    1 => array(3,1),
    2 => array(3),
    3 => array(1,5,3),
);

有了解决方案:

$array = array(
    1 => 1,
    2 => 3,
    3 => 5,
);

我已经完成了脚本,但我不确定它是否正确。这是我的剧本。我正在做的描述在评论中。

function pickUnique($array){
    //Count how many times each option appears
    $counts = array();
    foreach($array AS $options){
        if(is_array($options)){
            foreach($options AS $value){
                //Add count
                $counts[$value] = (isset($counts[$value]) ? $counts[$value]+1 : 1);
            }
        }
    }
    asort($counts);

    $didChange = false;


    foreach($counts AS $value => $count){

        //Check one possible value, starting with the ones that appear the least amount of times
        $key = null;
        $scoreMin = null;

        //Search each row with the value in it. Pick the row which has the lowest amount of other options
        foreach($array AS $array_key => $array_options){
            if(is_array($array_options)){
                if(in_array($value,$array_options)){
                    //Get score
                    $score = 0;


                    $score = count($array_options)-1;

                    if($scoreMin === null OR ($score < $scoreMin)){
                        //Store row with lowest amount of other options
                        $scoreMin = $score;
                        $key        = $array_key;
                    }
                }
            }
        }
        if($key !== null){
            //Store that we changed something while running this function
            $didChange = true;


            //Change to count array. This holds how many times each value appears.
            foreach($array[$key] AS $delValue){
                $counts[$delValue]--;
            }

            //Remove chosen value from other arrays
            foreach($array AS $rowKey => $options){
                if(is_array($options)){
                    if(in_array($value,$options)){
                        unset($array[$rowKey][array_search($value,$options)]);
                    }
                }
            }

            //Set value
            $array[$key] = $value;
        }

    }

    //validate, check if every row is an integer
    $success = true;
    foreach($array AS $row){
        if(is_array($row)){
            $success = false;
            break;
        }
    }
    if(!$success AND $didChange){
        //Not done, but we made changes this run so lets try again
        $array = pickUnique($array);
    }elseif(!$success){
        //Not done and nothing happened this function run, give up.
        return null;
    }else{
        //Done
        return $array;
    }


}

我的主要问题是我无法验证这是否正确。接下来我也很确定这个问题已经解决了很多次,但我似乎无法找到它。我可以证明这一点的唯一方法(据我所知)是通过为随机数组运行代码很多次并在遇到无法解决的数组时停止。然后我手动检查。到目前为止,结果都很好,但这种验证方式是不正确的。

我希望有人可以帮助我,无论是解决方案,问题的名称还是验证方法。

0 个答案:

没有答案