如果您想要一些上下文,我之前发布了another question。看来我采用这种方法走错了路。
Addition chains可用于最小化取幂数所需的乘法次数。例如, 7 需要四次乘法。两个计算 2 = a×a和a 4 = a 2 ×a 2 ,另外两个计算 7 = a 4 ×a 2 ×a。
同样,我正在尝试为一组数字生成所有可能的“减法链”。例如,给定一组数字{1, 2, 3}
,我试图生成以下排列。
{1, 2, 3}
{1, 2, 3}, {1, 2}
{1, 2, 3}, {1, 2}, {1}
{1, 2, 3}, {1, 2}, {2}
{1, 2, 3}, {1, 2}, {1}, {2}
{1, 2, 3}, {1, 3}
{1, 2, 3}, {1, 3}, {1}
{1, 2, 3}, {1, 3}, {3}
{1, 2, 3}, {1, 3}, {1}, {3}
{1, 2, 3}, {2, 3}
{1, 2, 3}, {2, 3}, {2}
{1, 2, 3}, {2, 3}, {3}
{1, 2, 3}, {2, 3}, {2}, {3}
{1, 2, 3}, {1, 2}, {1, 3}
{1, 2, 3}, {1, 2}, {1, 3}, {1}
{1, 2, 3}, {1, 2}, {1, 3}, {2}
{1, 2, 3}, {1, 2}, {1, 3}, {3}
{1, 2, 3}, {1, 2}, {1, 3}, {1}, {2}
{1, 2, 3}, {1, 2}, {1, 3}, {1}, {3}
{1, 2, 3}, {1, 2}, {1, 3}, {2}, {3}
{1, 2, 3}, {1, 2}, {1, 3}, {1}, {2}, {3}
# and so on...
通过从排列中的另一个集合中删除单个元素,可以找到排列中的每个元素(除{1, 2, 3}
之外)。
例如,排列{1, 2, 3}, {1}
无效,因为无法通过从{1}
删除单个元素来构建{1, 2, 3}
。
是否有已知算法可以找到电源组功率集的这个子集?我的实现将在Python中,但问题是语言无关。另外,我实际上并不想要包含具有单个元素的集合的排列(例如{1, 2, 3}, {1, 2}, {1}
),因为它们对应于不感兴趣的“独裁者”案例。
答案 0 :(得分:1)
生成所有这些列表的算法可以按如下方式工作:对于当前列表中的每个集合,创建一个副本,删除一个元素,将其添加到列表中,然后递归调用算法。您还必须确保不生成重复项,这可以通过确保新列表“比较小”(通过(排序的)元素的长度或成对比较)而不是前一个来完成。
这是Python中的一个实现,作为生成器函数,没有太多优化。这似乎现在运行得很好,生成所有子集而没有任何重复。
def generate_sets(sets, min_num=2):
yield sets
added = set() # new sets we already generated in this iteration
for set_ in sets:
# only if the current set has the right length
if min_num < len(set_) <= len(sets[-1]) + 1:
for x in set_:
# remove each element in turn (frozenset so we can put in into added)
new = set_.difference({x})
# prevent same subset being reachable form multiple sets
frozen = frozenset(new)
if frozen not in added:
added.add(frozen)
# recurse only if current element is "smaller" than last
if (len(new), sorted(new)) < (len(sets[-1]), sorted(sets[-1])):
for result in generate_sets(sets + [new], min_num):
yield result
对于generate_sets([{1,2,3}], min_num=2)
,这会生成以下列表:
[{1, 2, 3}]
[{1, 2, 3}, {2, 3}]
[{1, 2, 3}, {2, 3}, {1, 3}]
[{1, 2, 3}, {2, 3}, {1, 3}, {1, 2}]
[{1, 2, 3}, {2, 3}, {1, 2}]
[{1, 2, 3}, {1, 3}]
[{1, 2, 3}, {1, 3}, {1, 2}]
[{1, 2, 3}, {1, 2}]
对于generate_sets([{1,2,3}], 1)
,共生成45个集合列表。
但是,我没有看到与您之前问题的关联:{1, 2, 3}, {1, 2}
,{1, 2, 3}, {1, 3}
和{1, 2, 3}, {2, 3}
是否应该被视为等效?