n 个值的非重复二进制对
Posted
技术标签:
【中文标题】n 个值的非重复二进制对【英文标题】:Non repeating binary pairs of n values 【发布时间】:2014-07-08 01:10:29 【问题描述】:我正在使用购物车算法并且我遇到以下问题,我需要尝试所有可能的 n 值拆分以确定最佳值。所以假设我有 3 个值(“低”、“中”、高) 那么可能的分割(对)将是:(假设 low=0,medium=1,high=2)
0,1-2 低,中高 1,0-2 中、低-高 2,1-0 高,中低对于 4 个值(a、b、c、d),它将是:
ab,cd ac,bd ad,bc abc,d adb,c adc,b bcd,a问题是我不知道 n 所以解决方案必须是递归的。可能的拆分为 2n-1-1。我真的被卡住了,大部分代码对于购物车来说都是完整的,我真的不想将它限制为二进制值。
【问题讨论】:
似乎可能性的数量是n!
- 你不是在寻找一个排列 - 每个“值”都需要出现一次 - 还是我误解了你?
应该是不重复的 low,medium-high 和 low,high-medium 一样,请见谅。
还是没跟上,4个值的所有可能组合是什么?
如果我完全理解这个问题;您想将 n 个元素分成 2 组,它们在组中的顺序无关紧要。所以 4 个元素的可能性是: O , 1, 2, 3 & 1 , 0, 2, 3 & 2 , 0, 1, 3 & 3 , 0, 1, 2 & 0, 1 , 2, 3 & 0, 2 , 1, 3 & 0, 3 , 1, 2 我的问题是你怎么知道最好的一对组?有没有评价函数?
是的,我使用基尼指数,我不知道如何使用递归方式生成对。
【参考方案1】:
拆分是您的集合及其补集的子集。
由于您希望将拆分的 A-B 和 B-A 视为相同,因此您始终可以将输入集中的第一个值放在左侧。我们还需要注意不要包含一侧没有元素的拆分(例如:“abcd-”),
将这些放在 Python 中:
from itertools import chain, combinations
def powerset(s):
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
def splits(s):
ss = set(s[1:])
for p in powerset(s[1:]):
if not p: continue
cmpl = ss.difference(p)
yield ''.join([s[0]] + sorted(cmpl)), ''.join(p)
print list(splits('abcd'))
print list(splits('012'))
【讨论】:
我不知道python,我试过在线编译器,它没有编译。不过还是谢谢...【参考方案2】:假设输入集中的所有项目都是唯一的......
当您说可能的拆分为 2n-1-1 时,您暗示了您自己问题的答案。那是正确的。例如,有四个项目有 23-1 = 7 个拆分。
如果您考虑 4 位二进制数的所有可能值,您可以了解如何轻松找到所有可能的拆分。
ABCD
0000 ignore (not a split if all items in same group)
0001 ABC,D
0010 ABD,C
0011 AB,CD
0100 ACD,B
0101 AC,BD
0110 AD,BC
0111 A,BCD
1000 ignore (same as 0111)
1001 ignore (same as 0110)
1010 ignore (same as 0101)
1011 ignore (same as 0100)
1100 ignore (same as 0011)
1101 ignore (same as 0010)
1110 ignore (same as 0001)
1111 ignore (not a split if all items in same group)
所以算法是将变量count
从1增加到2n-1-1,并且对于每个count
,根据@987654324中的相应位是否将项目分组@ 是 0 或 1。
【讨论】:
惊人的答案,如此简单但我从未想过。谢谢。以上是关于n 个值的非重复二进制对的主要内容,如果未能解决你的问题,请参考以下文章
信息存储——当值X是2的非负整数n次幂时,如何表示成十六进制
2022-02-21:不含连续1的非负整数。 给定一个正整数 n ,返回范围在 [0, n] 都非负整数中,其二进制表示不包含 连续的 1 的个数。 输入: n = 5 输出: 5 解释: 下面是带