【问题标题】:Finding as many elements as possible that sums up as close to a given number as possible找到尽可能多的元素,这些元素的总和尽可能接近给定的数字
【发布时间】:2014-09-30 11:01:31
【问题描述】:

给定一个整数数组,A1、A2、...、An 和整数 P、C。

从数组 A 中找到一个计数 C 的整数集合,其中总和尽可能接近 P,并且应该使用尽可能多的元素。

例子

A = [3, 7, 2, 7, 25, 10, 5, 12, 1]
P = 15
C = 4

S1 = [3, 5, 7] = 15
S2 = [2, 5, 7, 1] = 15
S3 = [3, 5, 7, 1] = 16
S4 = [2, 7, 7] = 16

【问题讨论】:

  • 听起来像是功课……
  • 我可以确保它不是,它是一种算法,用于从交易中选择一组贵重物品以获得近似值。仅仅因为我没有以“我正在尝试”开始我的问题并不意味着这是家庭作业。
  • 这是 NP 完备的(很容易显示从子集和的减少),因此对于大的 n 将没有可行的算法。
  • 这就是我所担心的,A 的大小有时会很大有没有办法暴力破解或选择接近的东西,直到我们找到足够接近的值?
  • 评估解决方案的函数是什么?例如,尚不清楚 S1(完美目标,但只有三个元素)是否比 S3(接近但四个元素)更好(或更差)。

标签: arrays algorithm


【解决方案1】:

这是我想出的递归解决方案,但它并没有真正削减它,对不起,如果它不是最漂亮的代码 sn-p,这就是我来这里的原因。

$A = array();
$P = rand(1000, 9999) / 100;

for($i = 0; $i < 100; $i++)
    $A []= rand(100, 999) / 100;

print_r(array($P, $A));

for($i = 0, $ASz = count($A); $i < $ASz; $i++)
{
    $Aclone = $A;

    array_splice($Aclone, $i, 1);

    $result = foo($Aclone, $P, array($A[$i]));

    print_r(array($result, array_sum($result)));
}

function foo($A, $P, $Set)
{
    $lowest = abs($P - array_sum($Set));
    $lowestS = $Set;
    $popVal = -1;

    foreach($A as $offset => $newNum)
    {
        $Pr = $Set;
        $Pr []= $newNum;

        $qDist = abs($P - array_sum($Pr));

        if($qDist < $lowest)
        {
            $lowestS = $Pr;
            $lowest = $qDist;
            $popVal = $offset;
        }
    }

    if($popVal == -1)
        return $Set;

    $tempA = $A;
    array_splice($tempA, $popVal, 1);

    return foo($tempA, $P, $lowestS);
}

测试:http://sandbox.onlinephpfunctions.com/code/4a3dcd9af8b9a4561903007ccea343d745b8ab71

【讨论】:

    【解决方案2】:

    这实际上与流行的问题“改变制造”相同。查看该算法的详细信息和代码实现的链接:

    http://karmaandcoding.blogspot.in/2012/01/coin-change-problem-with-limit-on.html

    Coin change with limited number of coins

    【讨论】:

    • 我并不是真正的标准硬币找零问题,因为它应该尽可能多地使用数组中的整数。
    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 2016-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    相关资源
    最近更新 更多