找到与另一个子集和匹配的最小子集和

2024-04-27

我有一个现实世界的问题(不是家庭作业!),需要找到集合 A 的子集之和等于其他集合 B 的子集之和。

一个非常相似的问题,有一个有用的答案is here https://stackoverflow.com/questions/443712/algorithm-to-find-subset-within-two-sets-of-integers-whose-sums-match.

考虑这个例子:

@a = qw(200 2000 2000 2000 4000);
@b = qw(528 565 800 1435 2000 2000 2872);

Using the code https://stackoverflow.com/questions/443712/algorithm-to-find-subset-within-two-sets-of-integers-whose-sums-match/443950#443950在该问题的接受答案中提供,我得到以下输出:

sum(200 2000 4000) = sum(528 800 2000 2872)
sum(200 4000 4000) = sum(528 800 2000 2000 2872)
sum(200 4000) = sum(528 800 2872)
sum(200 2000 2000 2000 4000) = sum(528 800 2000 2000 2000 2872)

出于我的目的,我只想要使用输入集中最少元素的答案。在这个例子中,我只想

sum(200 4000) = sum(528 800 2872)

因为所有其他答案也都有200 and 4000总而言之。也就是说,我正在寻找“最简单”的可能总和(从某种意义上说,它们使用最少的元素)。有人可以建议一种相当有效的方法吗? (蛮力是可以的,因为我的数组没有那么大。)

另外,我应该注意到输出的第二行,sum(200 4000 4000) ...,不正确,因为4000仅出现一次@a。恐怕我对算法的理解不够深入,无法理解为什么会发生这种情况。

任何有关这些的帮助将不胜感激!


这个问题是 NP 完全问题,因此除非 P=NP,否则您将不得不对输入的大小进行指数运算。现在,此类问题的妙处在于,实际上有两种解决方法,这两种方法可以将指数放在问题的不同方面。

首先,如果您的总和没有太多元素,您可以通过搜索所有组合来暴力解决此问题。此方法与集合中的元素数量成指数关系,并且在每个容器最多包含 20 个左右元素的情况下也能很好地工作。在那之后,事情会变得非常糟糕。

第二种选择是使用动态规划。与之前的方法不同,该算法在写出每个数字所需的位数方面呈指数增长。您要做的就是跟踪所有可能和的集合以及生成它们所需的最小元素数。这是对您在答案中链接到的解决方案的简单修改。

下面是一些 python 代码,它生成它们可以相交的所有可能值:

    def gen_sum(a):
        r = { 0: [] }
        for x in a:
            for y, v in r.items():
                if not (x+y) in r or len(r[x+y]) > len(v) + 1:
                    r[x+y] = v + [x]
        return r

    def gen_sums(a, b):
        asum = gen_sum(a)
        bsum = gen_sum(b)
        return [ (k, v, bsum[k]) for k,v in asum.items() if k in bsum ][1:]

在您的示例数据上运行它,我得到:

[(4000, [4000], [2000, 2000]), (6000, [2000, 4000], [565, 1435, 2000, 2000]), (2000, [2000], [2000]), (4200, [200, 4000], [528, 800, 2872]), (10200, [200, 2000, 2000, 2000, 4000], [528, 565, 800, 1435, 2000, 2000, 2872]), (8200, [200, 2000, 2000, 4000], [528, 800, 2000, 2000, 2872]), (6200, [200, 2000, 4000], [528, 800, 2000, 2872])]

编辑:修正了一个错字,而且还注意到很多人已经很快回答了这个问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

找到与另一个子集和匹配的最小子集和 的相关文章

  • 我怎样才能找到圆的所有点? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 给定半径和圆心坐标 如何找到圆的所有
  • 如何修复错误嵌套/未闭合的 HTML 标签?

    我需要通过使用正确的嵌套顺序关闭任何打开的标签来清理用户提交的 HTML 我一直在寻找一种算法或Python代码来做到这一点 但除了PHP等中的一些半生不熟的实现之外 还没有找到任何东西 例如 类似的东西 p p ul li Foo bec
  • 比较周期性数据的快速方法

    假设我有任意类型的数据集 A B C D 并且我想将其与另一个数据集进行比较 我希望 A B C D B C D A C D A B 和 D A B C 的比较成立 但是不适用于 A C B D 或任何其他未类似排序的集合 有什么快速方法可
  • 这个洗牌算法有什么问题吗?

    我一直在做一些休闲假期计算 我的迷你项目是模拟意大利游戏 tomboli 一个关键的组成部分是对以下过程的模拟 游戏由一名男子控制 他拿着一袋 90 个弹珠 编号为 1 到 90 他从袋中随机取出一颗弹珠 每次向玩家喊出弹珠编号 经过一番思
  • 用 ruby​​ 解决旅行商问题(50 多个位置)

    我在一家快递公司工作 目前 我们 手动 解决了 50 多个地点的路线 我一直在考虑使用 Google Maps API 来解决这个问题 但我读到有 24 点的限制 目前我们在服务器中使用 Rails 因此我正在考虑使用 ruby 脚本来获取
  • 我能否确保在 5.10+ 上编写的 Perl 代码可以在 5.8 上运行?

    Perl 5 10 和 5 12 的一些新功能 例如 say 被定义为功能 您可以使用 feature 编译指示显式启用或禁止这些功能 但其他添加 例如正则表达式的命名捕获组 是隐式的 当我使用 5 10 解释器编写 Perl 但希望它也能
  • 如何最小化两个子多边形的最大纵横比?

    我想使用直线将凸多边形切成给定面积比的两部分 以使两个子多边形的较大纵横比最小化 目前我的方法包括选择一个随机起点 计算将多边形分割成目标区域的适当终点 然后计算两个纵横比中较大的一个 然后重复这个很多次 直到我足够接近最小值 多边形 A
  • 如果公司使用 C++、C# 或 Java 作为应用语言,为什么还要学习 Perl、Python、Ruby? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想知道为什么 C C Java 开发人员想要学习动态语言 假设公司不会将其主要开发语言从 C C Java 切换到动态语言 那么动态
  • C# 计算LRC(纵向冗余检查)

    我一直在到处研究这个问题 所有 LRC 实现似乎都没有给我正确的答案 花了几天时间后 我决定将我的代码放在这里 看看其他人是否可以发现问题 这是代码 C Input Data 31303030315E315E31303030325E315E
  • O(mn) 比 O((m+n)^2) 更好吗?

    算法的输入是m and n 我的算法的时间复杂度是O mn 我有一个时间复杂度为的基准算法O m n 我的实现在时间复杂度方面是否优于基准 许多评论者和回答者希望只考虑以下情况 m n或者至少当它们通过一个常数因子相关时 这不是它的工作原理
  • perl生成字符串来匹配正则表达式

    我尝试找到一种方法来生成与正则表达式匹配的字符串 例如以下正则表达式 A Z 6 6 A Z2 9 A NP Z0 9 A Z0 9 3 3 0 1 我尝试过 Cpan 上的一些 perl 模块不起作用 gt 字符串 随机 gt 正则表达式
  • Perl - HTTP::代理捕获 XHR/JSON 通信

    网站http openbook etoro com main http openbook etoro com main 有一个实时提要 由 javascript 通过 XHR keep alive 请求生成 并以 gzip 压缩 JSON
  • Java:使用indexOf方法根据另一个数组对数组进行排序

    我想根据另一个数组 索引 的排序顺序迭代两个数组 A B 在本例中为 10 34 32 21 String A a b c d String B e f g h int indexes 10 34 32 21 为这里的坏例子道歉 我已经更新
  • 当目标是查找某个字符串的所有出现情况时,KMP 最坏情况的复杂度是多少?

    我还想知道哪种算法在查找另一个字符串中所有出现的字符串时具有最坏情况的复杂性 博耶 摩尔算法似乎具有线性时间复杂度 KMP 算法在查找字符串中所有出现的模式时具有线性复杂度 如 Boyer Moore 算法1 如果您尝试在 aaaaaaaa
  • 如何在 dijkstra 算法中以 O(log n ) 时间更新优先级队列中的键?

    过去一周我一直在研究 dijkstra 算法 我在 java 中有正确的运行代码 它使用数组来计算标准 findMin 函数 该函数为您提供距离最小的顶点 显然它是 O n 现在我希望使用优先级队列 最小堆 来实现它 我的思考过程是 whi
  • Perl Mongo 查找对象 ID

    你会认为这是一件简单的事情 我有一个集合中的对象 ID 列表 我想根据对象 ID 获取单个记录 谷歌搜索过 但没有任何帮助 所以我有对象 ID 5106c7703abc120a04070b34 my client MongoDB Mongo
  • 以一定角度遍历二维数组

    通常我们按行或列遍历数组 但这里我想以角度遍历它 我会尝试解释我的意思 因此 假设角度是 45 度 那么它会搜索为 0 0 then 0 1 1 0 then 0 2 1 1 2 0 等等 抱歉 无法上传图像 因为我是新用户 不允许这样做
  • 两个非嵌套循环的大 O 表示法

    对于两个非嵌套的 for 循环 大 O 表示法是什么 Example for int i 0 i
  • 在无向图中查找强连通分量

    我想在无向图中找到强连接的组件 即如果我从节点开始A然后我会回到节点A并且每条边都被恰好访问一次 对于有向图可以使用Tarjan算法来寻找强连通分量 但是对于无向图怎么办 我认为您错过了强连通分量的含义 强连接组件 如果所有顶点对之间都存在
  • 如何拆分一行并重新排列其元素?

    我在一行中有一些数据 如下所示 abc edf xyz rfg yeg udh 我想呈现如下数据 abc xyz yeg edf rfg udh 以便打印备用字段并用换行符分隔 有没有这样的衬里 下列awk脚本可以做到这一点 gt echo

随机推荐