Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.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
C# 如何确定一组值之和的任何组合是否等于某个值?_C#_Algorithm_Excel_Vba - Fatal编程技术网

C# 如何确定一组值之和的任何组合是否等于某个值?

C# 如何确定一组值之和的任何组合是否等于某个值?,c#,algorithm,excel,vba,C#,Algorithm,Excel,Vba,我在下面有一组值。我需要知道的是,这些值的任何组合是否和某个值相加(本例中为46134.77)。最好的办法是什么?当然,手动操作需要几个小时 如果它返回真的话,我需要知道这个组合是什么。我可以在Excel VBA或C#应用程序中设置此功能。什么都行。我只是不知道怎么去那里 125.00 1,000.00 1,039.36 1,171.60 1,200.00 1,320.00 1,680.00 1,757.20 1,768.80 1,970.00 2,231

我在下面有一组值。我需要知道的是,这些值的任何组合是否和某个值相加(本例中为46134.77)。最好的办法是什么?当然,手动操作需要几个小时

如果它返回真的话,我需要知道这个组合是什么。我可以在Excel VBA或C#应用程序中设置此功能。什么都行。我只是不知道怎么去那里

125.00 1,000.00 1,039.36 1,171.60 1,200.00 1,320.00 1,680.00 1,757.20 1,768.80 1,970.00 2,231.25 2,300.00 2,369.25 2,589.20 2,720.00 2,887.50 3,000.00 3,085.00 3,142.60 3,174.40 3,742.70 3,847.20 5,609.25 5,881.05 12,240.48 14,112.00 29,318.07 32,551.80 125 1,000.00 1,039.36 1,171.60 1,200.00 1,320.00 1,680.00 1,757.20 1,768.80 1,970.00 2,231.25 2,300.00 2,369.25 2,589.20 2,720.00 2,887.50 3,000.00 3,085.00 3,142.60 3,174.40 3,742.70 3,847.20 5,609.25 5,881.05 12,240.48 14,112.00 29,318.07 32,551.80
这几乎是一个有界问题,是计算机中研究最为深入的计算问题之一。本地:


意味着您应该准备编写一个大循环对每个(或几乎每个)数字组合进行汇总


我建议不要用手做这件事。几个小时是一个严重的低估这将花费你一生的时间。例如,从28个数字中进行选择时,有超过4000万个14个数字的组合。(这仅仅是14条)。

正如paislee在回答中已经提到的,这是一种对。事实上,这个特殊的问题被称为背包问题,就像背包问题一样,它是NP完全的

链接的Wikipedia页面显示了如何使用动态规划解决该问题,但请注意,由于其NP完整性,如果将整数列表设置得太大,则解决该问题的速度总是很慢/不可能

以下是一些更相关的SO问题:


    • 您所描述的是。在计算上很难有效地解决这个问题,但对于这么小的一个集合来说是可行的

      此特定输入的确切数字组合为:

      29,318.07 + 5,881.05 + 3,174.40 + 3,085.00 + 2,231.25 + 1,320.00 + 1,000.00 + 125.00
      
      我使用以下Perl脚本确定此解决方案:

      sub knapsack {
          my ($target, $path, @vals) = @_;
          if ($target == 0) {
              print "Got it: @$path\n";
              exit;
          }
          while (my $val = pop @vals) {
              next if $val > $target;
              knapsack($target - $val, [@$path, $val], @vals);
          }
      }
      
      knapsack(46134_77, [], (
          125_00,  1000_00, 1039_36, 1171_60, 1200_00, 1320_00, 1680_00, 1757_20,
          1768_80, 1970_00, 2231_25, 2300_00, 2369_25, 2589_20, 2720_00, 2887_50,
          3000_00, 3085_00, 3142_60, 3174_40, 3742_70, 3847_20, 5609_25, 5881_05,
          12240_48, 14112_00, 29318_07, 32551_80,
      ));
      

      请注意,我已经将十进制值转换为整数(将它们全部乘以100),因为浮点比较是一个雷区。(详情请参见。)

      请先阅读其他答案/评论。下面是一个可以用于一小部分数据的解决方案

      double[] nums = new double[] { 10,20,30,40,50,60,70,80,90,100,150,200,250,300,400,500};
      
      Parallel.ForEach(GetIndexes(nums.Length), list =>
      {
          if (list.Select(n => nums[n]).Sum()==350)
          {
              Console.WriteLine(list.Aggregate("", (s, n) => s += nums[n] + " "));
          }
      });
      
      IEnumerable<IEnumerable<int>> GetIndexes(int count)
      {
          for (ulong l = 0; l < Math.Pow(2, count); l++)
          {
              List<int> list = new List<int>();
              BitArray bits = new BitArray(BitConverter.GetBytes(l));
              for (int i = 0; i < sizeof(ulong)*8; i++)
              {
                  if (bits.Get(i)) list.Add(i);
              }
              yield return list;
          }
      }
      
      double[]nums=新的双[]{10,20,30,40,50,60,70,80,90100150200250300400500};
      Parallel.ForEach(getindex(nums.Length),list=>
      {
      if(list.Select(n=>nums[n]).Sum()==350)
      {
      Console.WriteLine(list.Aggregate(“,(s,n)=>s+=nums[n]+”);
      }
      });
      IEnumerable GetIndexes(整数计数)
      {
      for(ulong l=0;l
      是的,Daskwuff是对的。唯一一个加起来为46134.77的组合 这是一个:

      125 1,000.00 1,320.00 2,231.25 3,085.00 3,174.40 5,881.05 29318.07


      花了2秒钟才找到答案。我使用了SumMatch Excel加载项。

      可能的重复听起来像一个二元搜索树,其中每个节点的值都是上述节点的总和(如果为true)。可能的重复您和其他人都希望解决此问题。例如,这个服务员:几乎,至少——严格来说,背包问题是找到不超过目标的最接近的组合。这个解决方案只有在列表中的每个数字只使用一次时才有效。例如,它在nums={10}中找不到20