如何找到从多个数组中提取的数字的最小总和?

Posted

技术标签:

【中文标题】如何找到从多个数组中提取的数字的最小总和?【英文标题】:How to find the minimal sum of numbers drawn from multiple arrays? 【发布时间】:2014-04-18 08:37:47 【问题描述】:

我想知道解决以下问题的最佳方法是什么。 我是用 php 编写的,但它更像是一个一般性的编程问题,我猜它涉及搜索算法和组合。

给定一个包含多个数组/数字集的数组

$a[0] = array(1,2,3,4,5);
$a[1] = array(1,3,5,7,9);
$a[2] = array(2,4,6,8,10);

我想从每个数组中抽取一个数字,使抽取的数字之和尽可能小。 此外,数字必须从唯一的数组索引中提取,因此在此示例中您无法绘制 1、1、2。 上述数组中可能的最小数列是 3、1、4,总和为 8。

现在假设一个包含每个 m 数字的 n 数组/集合的输入数组,找到最佳数字序列的最合乎逻辑和最有效的方法是什么?

【问题讨论】:

看起来像你的作业!!! 这不是功课,我在创建应用程序时遇到了问题。我的解决方案包括n for 相互嵌套的循环以及一个用于跟踪最小总和的变量。它确实有效,但结果却是非常难看的代码,所以我只是想知道这里的正确方法是什么。我的猜测是最好递归解决,但我认为向其他程序员征求意见也无妨。 使用 min() 函数。然后从下一个数组中删除低于当前结果的任何内容。对下一个数组重复。不是真正的递归问题,因为您的数组不是递归的。 ToBe,我认为这行不通。如果我从第一个数组(在示例中)开始并使用 min() 函数,它将返回 1,而对于下一个数组,它将返回 3 和 6。这些值的总和将是 10,这不是最小的在这种情况下。 【参考方案1】:

假设所有数组都已排序,我们可以忽略索引 >= n 处的元素(因此我们可以专注于方阵 n * n) 我们像Permutations - all possible sets of numbers 一样递归地生成所有排列,并且对于每个排列,我们计算总和。虽然不是最优的,但是比n嵌套for循环要好:

$minSum = PHP_INT_MAX;

$a[0] = array(1,2,3,4,5);
$a[1] = array(1,3,5,7,9);
$a[2] = array(2,4,6,8,10);

function pc_permute($items, $perms = array( )) 
    global $a, $minSum;
    if (empty($items)) 
        $sum = 0;
        foreach($perms as $i => $p) 
          $sum += $a[$i][$p];
        
        if($sum<$minSum) 
          $minSum = $sum;
        
     else 
        for ($i = count($items) - 1; $i >= 0; --$i) 
             $newitems = $items;
             $newperms = $perms;
             list($foo) = array_splice($newitems, $i, 1);
             array_unshift($newperms, $foo);
             pc_permute($newitems, $newperms);
         
    


pc_permute(range(0,count($a)-1));

echo "$minSum\n";

【讨论】:

使用函数生成索引的排列,然后计算每个索引的总和似乎是一个非常好的方法。我自己没有及时想到,谢谢!

以上是关于如何找到从多个数组中提取的数字的最小总和?的主要内容,如果未能解决你的问题,请参考以下文章

总和至少为 K 的最小数字集

如何从数组中的数字中找到最大和最小数字[重复]

如何找到数组中所有数字的总和?

找到数组中所有对的最小差的总和

快速排序

JAVA怎样随机生成10W个数字, 要求: 10W个数字总等于50W而且每个数字最小1最大100, 求代码及思路