- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想出了一个新算法来解决 subset sum problem ,我认为是多项式时间。告诉我我要么错了,要么就是个天才。
快速入门事实:
子集和问题是一个 NP 完全问题。在多项式时间内求解它意味着 P = NP。长度为 N 的集合中的子集数为 2^N。
更有用的是,长度为 N 的唯一子集的数量最大是整个集合的总和减去最小元素,或者,任何子集可能产生的总和范围介于所有负元素的总和之间以及所有正元素的总和,因为没有和可能大于或小于所有正或负和,当我们添加额外元素时,它们以线性速率增长。
这意味着随着 N 的增加,重复子集的数量呈指数增加,而唯一的、有用的子集的数量仅呈线性增加。如果可以设计出一种算法可以尽早删除重复的子集,我们将在多项式时间内运行。一个简单的例子很容易从二进制文件中获取。仅从 2 的幂的数字,我们可以为任何整数值创建唯一的子集。因此,任何涉及任何其他数字的子集(如果我们拥有 2 的所有幂)都是重复的和浪费的。通过不计算它们及其导数,我们几乎可以节省算法的所有运行时间,因为与任何整数相比,作为 2 的幂的数字是对数发生的。
因此,我提出了一个简单的算法,可以删除这些重复项并省去计算它们及其所有导数的麻烦。
首先,我们将对只有 O(N log N) 的集合进行排序,并将其分成正负两半。负数的过程是相同的,所以我只会概述正数(现在这个集合意味着只是正数,只是为了澄清)。
想象一个由 sum 索引的数组,它包含正侧的所有可能结果总和的条目(记住,这只是线性的)。当我们添加一个条目时,值是子集中的条目。所以,数组[3] = { 1, 2 }。
一般来说,我们现在开始枚举集合中的所有子集。我们通过从一个长度的子集开始,然后添加到它们来做到这一点。当我们拥有所有唯一的子集时,它们会形成一个数组,我们只需按照 Horowitz/Sahni 中使用的方式对它们进行迭代。
现在我们从“第一代”值开始。也就是说,如果原始数据集中没有重复的数字,则保证这些值中没有重复的数字。即所有单值子集,以及所有长度的集合减去一个长度的子集。这些可以通过对集合求和并依次减去每个元素来轻松生成。此外,集合本身是有效的第一代和和子集,以及子集的每个单独元素。
现在我们做第二代值。我们遍历数组中的每个值,对于每个唯一的子集,如果没有它,我们就添加它并计算新的唯一子集。如果我们有重复,就会产生乐趣。我们将其添加到碰撞列表中。当我们要添加新的子集时,我们会检查它们是否在碰撞列表中。我们通过不太理想的(通常更大,但可以是任意的)相等子集作为键。当我们添加到子集时,如果我们会产生碰撞,我们什么都不做。当我们要添加更理想的子集时,它会错过检查并添加,从而生成公共(public)子集。然后我们只是重复其他几代。
通过以这种方式删除重复的子集,我们不必继续将重复项与集合的其余部分组合,也不必继续检查它们是否存在冲突,也不必对它们求和。最重要的是,通过不创建非唯一的新子集,我们不会从中生成新的子集,我相信这可以将算法从 NP 变为 P,因为子集的增长不再是指数级的——我们丢弃它们中的绝大多数在下一代“繁殖”并通过与其他非重复子集组合来创建更多子集之前。
我认为我没有很好地解释这一点。我有照片……它们在我的脑海里。重要的是,通过丢弃重复的子集,您可以消除几乎所有的复杂性。
例如,想象一下(因为我是手工做这个例子的)一个简单的数据集,它从 -7 到 7(不是零),我们的目标是零。排序和拆分,所以我们剩下 (1, 2, 3, 4, 5, 6, 7)。总和是 28。但是 2^7 是 128。所以 128 个子集适合范围 1 .. 28,这意味着我们事先知道 100 个集合是重复的。如果我们有 8 个,那么我们将只有 36 个插槽,但现在有 256 个子集。所以你可以很容易地看到,被骗的数量现在是 220,比以前多了一倍多。
在这种情况下,第一代值是 1, 2, 3, 4, 5, 6, 7, 28, 27, 26, 25, 24, 23, 22, 21,我们将它们映射到它们的组成成分,所以
1 = { 1 }
2 = { 2 }
...
28 = { 1, 2, 3, 4, 5, 6, 7 }
27 = { 2, 3, 4, 5, 6, 7 }
26 = { 1, 3, 4, 5, 6, 7 }
...
21 = { 1, 2, 3, 4, 5, 6 }
1 = { 1 }
2 = { 2 }
// Didn't add 1 to 2 to get 3 because that's a dupe
3 = { 3 } // Add 1 to 3, amagad, get a duplicate. Repeat the process.
4 = { 4 } // And again.
...
8 = { 1, 7 }
21? Already has 1 in.
...
27? We already have 28
1? Existing duplicate
3? Get a new duplicate
...
9 = { 2, 7 }
10 = { 1, 2, 7 }
21? Already has 2 in
...
26? Already have 28
27? Got 2 in already.
1? Existing dupe
2? Existing dupe
4? New duplicate
5? New duplicate
6? New duplicate
7? New duplicate
11 = { 1, 3, 7 }
12 = { 2, 3, 7 }
13 = { 1, 2, 3, 7 }
1? Existing dupe
2? Existing dupe
3? Existing dupe
5? New duplicate
6? New duplicate
7? New duplicate
8? New duplicate
9? New duplicate
14 = {1, 2, 4, 7}
15 = {1, 3, 4, 7}
16 = {2, 3, 4, 7}
17 = {1, 2, 3, 4, 7}
1,2,3,4 existing duplicate
6,7,8,9,10,11,12 new duplicate
18 = {1, 2, 3, 5, 7}
19 = {1, 2, 4, 5, 7}
20 = {1, 3, 4, 5, 7}
21 = new duplicate
最佳答案
这并不能证明 P = NP。
你没有考虑正数的可能性:1、2、4、8、16等......所以当你对子集求和时不会有重复,所以它会在 O(2^N) 中运行在这种情况下的时间。
您可以将此视为特殊情况,但对于其他类似情况,该算法仍然不是多项式。您所做的这个假设是您从子集总和的 NP 完全版本转向仅解决简单(多项式时间)问题的地方:
[assume the sum of the positive numbers grows] at a linear rate when we add extra elements.
Thus, the problem is most difficult if N and P are of the same order.
If P (the number of place values) is a small fixed number, then there are dynamic programming algorithms that can solve it exactly.
关于polynomial-math - 我是多项式时间的子集求和算法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3125795/
我正在执行大型 ffdf 对象的子集,我注意到当我使用 subset.ff 时,它会生成大量 NA。我通过使用 ffwhich 尝试了另一种方法,结果要快得多,并且没有生成 NA。这是我的测试: li
我对 Prolog 有点陌生。我正在尝试编写一个函数subset(Set, Subset) 来确定Subset 是否是Set 的子集(duh)。另外,如果第二个参数没有实例化,它应该输出每个可能的子集
一、题目 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 二、示例 输入:nums = [1,2
我想从数据帧的操作中排除一列。当然,我可以在没有要排除的列的情况下复制数据框,但这似乎是一种解决方法。我认为必须有一种更简单的方法来进行子集化。 所以这个示例代码应该显示我在做什么。 df colMe
我有一个 SpatialPolygonsDataFrame我通过使用 readOGR 读取 shapefile 创建的在 rgdal包裹。我正在尝试使用它来使用 spsample 生成采样网格在 sp
我想解决一个简单的问题,但即使我尝试了很多不同的方法,我也找不到解决方案。我正在使用 SICStus Prolog (如果这很重要),并且我想获取列表的所有子列表/子集(我不知道哪个术语是正确的),其
我目前正在使用 shinyTable,它是 HandsonTable (https://github.com/trestletech/shinyTable) 的 shiny 兼容实现。巧合的是,我意识
我正在 Delphi 中构建一个表单,其中包含服务下拉列表和用于选择服务的附加组件网格。我获取的数据来自 API,并且我将服务的数据存储在 ADODataSet 中,如下所示: ID (integer
subset() 函数有问题。如何通过观察次数对我的数据框的一个因子进行子集化? NAME CLASS COLOR VALUE antonio
我想知道是否有任何简单的算法来比较一个散列是否是另一个散列的子集。 例如,如果 $HASH{A} = B; $HASH{B} = C; $HASH{C} = D; $HASH2{A} = B; $HA
这个问题在这里已经有了答案: Array combinations without repetition (1 个回答) 关闭 8 年前。 给定一个数组,如何在 postgresql 中找到一定大小
我有下一个程序。我应该如何在 main 中使用迭代器以显示总和为 0 的子集? 我的程序应该打印: 2 -2 5 -5 # include # include using namespace st
我正在寻找一个可以自定义的 Markdown 解析器,最好是 Javascript。特别是,我想删除使用实际 HTML 标签的选项。我尝试编辑摊牌的来源,但无法弄清楚。 Jquery 集成也很好,尽管
我有一个包含名称列表的文件(引用文件 1): Apple Bat Cat 我有另一个文件(引用文件 2),其中包含名称列表和详细信息引用: Apple bla blaa aaaaaaaaagggggg
我有两个带有排序行的文件。一个文件 (B) 是另一个文件 (A) 的子集。我想找到 A 中不在 B 中的所有行。理想情况下,我想创建一个包含这些行的文件 (C)。这在 Unix 中可能吗?我正在寻找一
我有一个包含肽序列的列的数据框,我只想保留字符串中没有内部“R”或“K”的行。 df1 <- data.frame( Peptide = c("ABCOIIJUHFSAUJHR", "AOFI
这个问题在这里已经有了答案: How to subset matrix to one column, maintain matrix data type, maintain row/column na
假设我有一个列表向量: library(tidyverse) d 2) # A tibble: 5 x 1 x 1 2 3 4 5 最佳答案 应该是 lengt
我自己从来没有运行过javadoc(无论是在命令行还是ant's javadoc task;我将使用ant)——我需要为我编写的库生成一个javadoc。 问题是我的 java 库被组织成几个包,在
假设一个多方加密方案,类似于答案:Encryption with multiple different keys? . 那是。一组键K可以用来破译密文。 有没有办法过期: K'⊆ K 这样 K \ K
我是一名优秀的程序员,十分优秀!