【问题标题】:Efficiently generate all combinations (at all depths) whose sum is within a specified range [closed]有效地生成总和在指定范围内的所有组合(在所有深度)[关闭]
【发布时间】:2019-08-15 03:16:47
【问题描述】:

我有一组 80 个数字,我想找到总计达到给定数字的组合列表。下面的代码工作正常,但它需要太长时间,有人可以帮我提供一个可以更快处理它的增强版本吗?

public void sum_up(List<int> numbers, int target)    
        {
            sum_up_recursive(numbers, target, new List<int>());
        }

        public void sum_up_recursive(List<int> numbers, int target, List<int> partial)
        {
            int s = 0;
            foreach (int x in partial) s += x;

            if (s == target)
                val +=" sum(" + string.Join(",", partial.ToArray()) + ")=" + target + Environment.NewLine;

            if (s == target && string.Join(",", partial.ToArray()).Contains("130") &&
                string.Join(",", partial.ToArray()).Contains("104"))
            {
                string gg = " sum(" + string.Join(",", partial.ToArray()) + ")=" + target;
                val += " || || sum(" + string.Join(",", partial.ToArray()) + ")=" + target + Environment.NewLine;
            }

            if (s >= target)
                return;

            for (int i = 0; i < numbers.Count; i++)
            {
                List<int> remaining = new List<int>();
                int n = numbers[i];
                for (int j = i + 1; j < numbers.Count; j++) remaining.Add(numbers[j]);

                List<int> partial_rec = new List<int>(partial);
                partial_rec.Add(n);
                sum_up_recursive(remaining, target, partial_rec);
            }
            lblResult.Text = val;                
        }

        private void btnCheck_Click(object sender, EventArgs e)
        {

            string[] vendorVal = txtvendor.Text.Split(',');
            int[] myInts = Array.ConvertAll(vendorVal, s => int.Parse(s));
            List<int> numbers = myInts.ToList();
            int target = Convert.ToInt32(txtDifference.Text);
            sum_up(numbers, target);

        }

感谢任何帮助...

【问题讨论】:

  • 是的,可以找到重复项,并且愤怒可以从 0 到 5000 不等
  • 如果您在浏览器中搜索“Sum to target algorithm”,您会找到比我们在此处管理的更能解释这一点的参考资料。

标签: c# algorithm checksum


【解决方案1】:

您一次又一次地重新计算相同的部分总和 - 这个过程需要很多时间。如果目标总和值合理并且您有足够的内存 - 使用动态编程方法。

创建长度为(TargetSum + 1) 的数组A,其中包含中间和的可能变体。

对于每个项目值 V 循环从 sum S=TargetSumV(反向遍历有助于避免重复使用同一项目)。如果条目 A[S - V] 不为空 - 添加来自 A[S - V] 的所有变体,并将 V 添加到 A[V] 中。最后A[TargerSum] 将包含所有可能的组合。

还可以考虑memoization 技术 - 它可能是从您的递归函数构造的 - 只需记住字典中的 sum 变体并重用存储的变体。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-04
    • 1970-01-01
    • 2017-07-10
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多