我正在对组合算法进行一些练习,并试图弄清楚如何解决以下问题:
给定一组25位,设置(选择)15(非置换且无顺序):
n!/(k!(n-k)!) = 3.268.760
现在,对于每种可能性构建一个矩阵,我将每个独特的25位成员与所有其他25位成员交叉 在它之间的关系中,必须至少有11个共同的设置位(只有1个,而不是0个)。
让我试着说明将其表示为二进制数据,因此第一个成员将是:
0000000000111111111111111 (10 zeros and 15 ones) or (15 bits set on 25 bits)
0000000001011111111111111 second member
0000000001101111111111111 third member
0000000001110111111111111 and so on....
...
1111111111111110000000000 up to here. The 3.268.760 member.
现在,在1 x 1的矩阵上交叉这些值,我必须有15位共用。由于结果是> = 11,因此它是“有用的”结果。
对于1 x 2,我们有14位通用,所以也是有效的结果。
为所有成员执行此操作,最后,跨越1 x 3.268.760应该导致5位共同,因为它是< 11它不“有用”。
我需要的是找出(通过数学或算法)最小数量的成员,以涵盖所有具有11位共同点的可能性。
换句话说,如果对所有其他成员进行测试,那么一组N个成员在整个3.268.760 x 3.268.760宇宙中可能至少有11位。
使用蛮力算法我发现81位25位成员可能会得到这个。但我猜这个数字应该更小(接近12)。
我试图使用强力算法在3.268.760上进行12个成员的所有可能变化但是可能性的数量 它是如此巨大,以至于计算需要一百多年(3,156x10e69组合)。
我已经搜索过有关组合学的信息,但是有很多字段我不知道这些问题应该适合。
所以关于组合学领域的任何方向,或者对这些问题的任何算法都非常感激。
PS:仅供参考。两个成员的“相似度”使用以下公式计算:
(Not(a xor b)) and a
之后有一个小的递归循环来计算给定公共位数的位。
编辑:正如下面评论中所承认的那样(@btilly)是关系或link to image
的'分形'图像对于小于10位的值,色标范围从红色(15位匹配)到绿色(11位匹配)到黑色。
此图片只是4096个第一组的样本。
答案 0 :(得分:1)
tl; dr:你想在一个非常对称的大图上解决dominating set。 btilly是对的,你不应该期待一个确切的答案。如果这是我的问题,我会尝试从贪婪的解决方案开始的本地搜索。选择一组并尝试通过更改其他设置来摆脱它。这需要数据结构来跟踪哪些集合只被覆盖一次。
编辑:好的,这是一个更好的想法下限。对于从1到最优解的值的每个k,存在[25选择15] * k / [k集的最大联合覆盖]的下界。您的12的界限(实际上是10,通过我的计算,因为您忘记了一些邻居)对应于k = 1.证明草图:使用m组修复任意解,并考虑可以通过m的k获得的最大覆盖。构建一个分数解决方案,其中所选k的所有对称性被平均在一起并进行缩放,以便每个元素被覆盖一次。这个解决方案的成本是[25选择15] * k / [那些k集的最大联合覆盖],这至少与我们拍摄的下限一样大。然而,它仍然至少与原始的m-set解决方案一样小,因为每组的边际收益正在下降。计算最大覆盖范围通常很难,但有一个因素(e /(e-1)) - 近似(≈1.58)算法:贪婪,听起来好像你可以快速实现(注意:你需要选择每次覆盖最多未覆盖的其他集合的集合。通过将贪心解与e /(e-1)相乘,我们得到k个元素的最大覆盖范围的上界,这足以支持前一段中描述的下界。
警告:如果此上限大于[25选择15],则k太大!
答案 1 :(得分:0)
这类问题非常困难,你不应该期望找到确切的答案。
贪婪的解决方案应该产生“相当好”的答案。但是......如何贪婪?
我们的想法是始终选择下一个元素作为当前无法比拟的尽可能多的可能性。不幸的是,有超过300万可能的成员,你必须尝试匹配数百万不匹配的成员(注意,你最好的下一个猜测可能已经匹配你的候选集中的另一个成员..),甚至选择下一个元素可能是不可行的。 / p>
因此,我们必须对选择下一个元素感到贪婪。我们将选择每个位以最大化最终匹配所有当前不匹配元素的概率之和。
为此,我们需要一个二维查找表P
,这样P(n, m)
是两个随机成员共有至少11位的概率,如果m
在第一个成员中为1的第一个n
位在第二个成员中也是1。这个225概率表应该预先计算好。
可以使用以下规则轻松计算此表:
P(15, m)
,则m < 11
为0,否则为1。 n < 15
:
P(n, m) = P(n+1, m+1) * (15-m) / (25-n) + P(n+1, m) * (10-n+m) / (25-n)
现在让我们从一些彼此“相距甚远”的成员开始吧。我的建议是:
现在从您的(25个选择15个)成员的世界开始,消除所有与初始集合中的一个元素匹配的成员。
接下来我们进入算法的核心。
While there are unmatched members:
Find the bit that appears in the most unmatched members (break ties randomly)
Make that the first set bit of our candidate member for the group.
While the candidate member has less than 15 set bits:
Let p_best = 0, bit_best = 0;
For each unset bit:
Let p = 0
For each unmatched member:
p += P(n, m) where m = number of bits in common between
candidate member+this bit and the unmatched member
and n = bits in candidate member + 1
If p_best < p:
p_best = p
bit_best = this unset bit
Set bit_best as the next bit in our candidate member.
Add the candidate member to our collection
Remove all unmatched members that match this from unmatched members
The list of candidate members is our answer
我没有编写代码,因此我不知道这个算法会产生多么好的答案。但是假设它并不比你当前的好,对于77名候选成员(我们作弊并以4开始)你必须通过你无与伦比的候选人进行271次传球(25次找到第一位,24次找到第二位,等等到11找到15,再找到一个匹配的成员)。这是20867次传球。如果你有平均100万不匹配的成员,那就是200亿次操作。
这不会很快。但它应该在计算上可行。