n个值的非重复二进制对

时间:2014-05-19 23:01:50

标签: c algorithm tree classification regression

我正在使用购物车算法,我有以下问题,我需要尝试所有可能的n值分割,以确定最佳。所以我想说我有3个值("低", " medium",high)那么可能的分裂(对)将是:(假设 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,一个

问题是我不知道n因此解决方案必须是递归的。可能的分裂是 2 n-1 -1 。我真的很困难,大部分代码都是完整的购物车,我真的不想把它限制为二进制值。

2 个答案:

答案 0 :(得分:2)

假设输入集中的所有项都是唯一的......

当你说可能的分裂是2 n-1 -1时,你暗示了你自己问题的答案。那是正确的。例如,有四个项目有2个 3 -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增加到2 n-1 -1,并且对于每个count,根据对应的项将项分成组count中的位为0或1。

答案 1 :(得分: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'))