带有 2675 个数字列表的子集总和
Posted
技术标签:
【中文标题】带有 2675 个数字列表的子集总和【英文标题】:Subset Sum with a list of 2675 numbers 【发布时间】:2017-03-24 14:51:06 【问题描述】:我正在寻找是否可以有效解决问题的是/否答案。我很确定以我们目前可用的计算技术状态是不可能的。我很高兴知道我错了。所以这里什么都没有。
我有一个2576
号码列表。我试图在列表中找到总计为44576.54
的数字组合。数字列表包含从 5 位(两位精度)到 8 位(两位精度)的数字。
非常感谢您的帮助!
【问题讨论】:
“介绍”+1。如果您想在合理的时间内找到所有组合,我会说不!但不确定。也许某处有一些巫术算法。 列表中有负数吗?如果不是,那么最多四个 5 位数字可以是和的一部分,并且根本不能使用 6/7/8 位数字。这大大减少了要检查的组合数量。请注意,以浮点数指定数字会导致问题 - 任何数字总和都不太可能完全等于 44576.54,即使这是数学上正确的结果。最好将所有内容乘以 100,并且只处理整数。 【参考方案1】:你错了。经典的动态规划算法将在现代计算硬件上快速解决这个问题。
【讨论】:
即使是非正整数?你能详细说明吗? @大卫 @ishan 是的,即使是非正整数(尽管大多数实现都需要对数组进行不同的索引)。 谢谢@David,你能指导我找到一个 URL 或任何可以帮助我在合理时间内解决该问题的材料 @ishan en.wikipedia.org/wiki/Subset_sum_problem,在伪多项式时间算法下。【参考方案2】:这是动态规划算法,并且已经在Emercoin 引擎中实现,用于选择最佳 UTXO 子集。 有关此解决方案,请参阅 source code 和 article。
该算法的共同思路如下:
你有一组不同长度的“棒”(长度是你的数值)。 您需要选择杆的子集,总长度为 4457654。
让您创建标志线,总和 + 1 的长度,即 4457655。如果找到值“i”的总和子集,则 LINE[i] = 1,如果找到值“i”的子集,则为零没有找到。最初,整个数组都是零填充的,因为没有找到任何总和。
标记 LINE[0] := 1;这意味着,0.00 美元的总和可以很容易地找到 - 这是空子集。
而(LINE[4457654] == 0):
从套装中获取下一根杆。 将此棒应用到阵列的末端。即,在 LINE[4457654] 处的杆末端,在 LINE[4457654 - 杆长度]处的杆开始。 将杆从阵列末端移动到开始,并且: 如果 LINE[杆开始] == 1,则 LINE[杆结束] := 1;【讨论】:
【参考方案3】:这个问题基本上有两种解决方案:
动态编程:复杂度总和*n,所以在您的情况下,这将非常大,您的程序不会在几天内完成。
回溯解决方案:复杂度 2^n,这意味着您的程序不会结束多年,这就是为什么它被称为 NP-Hard 问题
我已经研究子集和问题很长时间了,我有一个算法,我已经测试了 n=400,它在几秒钟内就给出了结果。 目前我正在撰写论文以使其发表。分享您的意见。我会让你知道它是什么子集,这也将帮助我验证我的算法是否能解决实际问题。
顺便说一句,你能告诉我为什么你需要得到子集和吗?你的用例是什么?
【讨论】:
以上是关于带有 2675 个数字列表的子集总和的主要内容,如果未能解决你的问题,请参考以下文章
回溯 - 给定一组数字,找到总和等于 M 的所有子集(给定 M)