【发布时间】:2018-05-25 07:10:32
【问题描述】:
好的,这是一个很难解释的问题。正是我解释它的困难使得创建我想要的循环变得困难。
考虑一下这个 10 组的列表
my_list_of_sets = [
{0,1,2,3,4,5,7,9},
{0,1,2,4,5,6,7},
{0,1,2,3,4,8,9},
{1,3,4,5,6,7,8,9},
{1,2,3,4,5,6},
{3,4,5,6,7,8,9},
{1,2,3,5,6,8,9},
{2,3,4,5,6,7,8},
{2,5,6,7,8,9},
{3,4,6,7,8,9}]
我想应用以下类型的规则来扩展这些列表的交集。
规则 1:my_list_of_sets[0] 可以与索引为 0,1,2,3,4,5,7,9 的 my_list_of_sets 相交。
规则 2:my_list_of_sets[1] 可以与索引为 0,1,2,4,5,6,7 的 my_list_of_sets 相交
RuleX:my_list_of_sets[x] 可以与索引在 my_list_of_sets[x] 中的 my_list_of_sets 相交
RuleN:My_list_of_sets[1] 不能与 my_list_of_sets[3] 或 my_list_of_sets[8] 或 my_list_of_sets[9] 共存。
并以递归方式执行此操作,直到我展开可以“共存”的集合的输出列表。
我执行的循环流程
my_output_list_item = my_list_of_sets[0] & my_list_of_sets[0]
{0,1,2,3,4,5,7,9}
my_output_list_item = my_output_list_item & my_list_of_sets[1] #Skipped no index
{1,2,4,5,7}
然后我可以继续与索引 2,4,5,7 相交...
my_output_list_item = my_output_list_item & my_list_of_sets[2]
{0,1,2,4}
my_output_list_item = my_output_list_item & my_list_of_sets[4]
{1,2,4}
直到我将 my_list_of_sets[0] 作为索引进入 my_list_of_sets 并找到一个没有“异议”的集合 {1,2,4}。抱歉,我想不出一个更好的词来表示可以相交的集合。
问题 1 您会注意到,如果我的循环的第一次迭代是任意的 my_list_of_sets[0] & my_list_of_sets[1] 索引 3 在第一次迭代中被删除。如果第一遍是任意的 my_list_of_sets[0] 和 my_list_of_sets[2],我会得到不同的结果。
my_output_list_item = my_list_of_sets[0] & my_list_of_sets[2] #Skipped one index
{0,1,2,3,4,9}
my_output_list_item = my_output_list_item & my_list_of_sets[3]
{1,3,4,9}
my_output_list_item = my_output_list_item & my_list_of_sets[4]
{1,3,4}
my_output_list_item = my_output_list_item & my_list_of_sets[1]
{1,4}
根据开始交叉点的索引,我得到了 {1,2,4} 和 {1,4}。 这意味着我的输入数据顺序已与结果相关,并且它是一个集合,没有固有顺序。
出于这个原因,我尝试通过使用滚动切片窗口沿着集合进行并执行所有起始索引的交集来解决问题 1。 这是我到目前为止的代码。
my_output_list = set()
for i in range(len(my_list_of_sets)):
set_as_list = list(my_list_of_sets[i]) #need a list here because it will be indexed from various offsets
for slice_index in range(0, len(set_as_list)): # the index is used to make sure all items are started with every other bd
new_item = my_list_of_sets[i]
for bd in set_as_list[slice_index::] + set_as_list[:slice_index:]:
if bd in new_item: # need this if statement as new_item is getting smaller each loop of bd.
new_item = new_item.intersection(my_list_of_sets[bd])
my_output_list.add(frozenset(new_item))
这将枚举到 15 个集合的 my_output_list。
问题 2: 但是这段代码仍然遗漏了一些组合
my_output_list_item = my_list_of_sets[0]
my_output_list_item = my_output_list_item & my_list_of_sets[2] #Skipped one index
my_output_list_item = my_output_list_item & my_list_of_sets[4] #Skipped one index
my_output_list_item = my_output_list_item & my_list_of_sets[1]
{1,2,4}
my_output_list_item = my_list_of_sets[0]
my_output_list_item = my_output_list_item & my_list_of_sets[2] #Skipped one index
my_output_list_item = my_output_list_item & my_list_of_sets[9] #Skipped two index
my_output_list_item = my_output_list_item & my_list_of_sets[3]
my_output_list_item = my_output_list_item & my_list_of_sets[4]
{3,4}
my_output_list_item = my_list_of_sets[0]
my_output_list_item = my_output_list_item & my_list_of_sets[2] #Skipped one index
my_output_list_item = my_output_list_item & my_list_of_sets[0] #Skipped three index
my_output_list_item = my_output_list_item & my_list_of_sets[1]
my_output_list_item = my_output_list_item & my_list_of_sets[2]
my_output_list_item = my_output_list_item & my_list_of_sets[4]
{1,2,4}
等等。
我相信这个缺失的{3,4} 是由于滚动切片bd 的索引值顺序增加而忽略了一些可能的组合。
因此,虽然我已经拥有循环迭代 0 的滚动切片 bd,但我认为我还需要一个 itertools 来遍历 my_list_of_sets[0] 的所有组合中的索引。
几处编辑。我不能暴力破解所有组合并删除非法组合。它是 len 100 列表,即 100^100 个组合,而计算机无法做到。 我知道我的答案可能在于 itertools,但我并没有想象它适用于长度大于 2 的列表的产品。
【问题讨论】:
-
这里对您的问题进行了更简洁的表述:您正在寻找可以共存的最大集合组(并打印出该组中的集合)。如果每个集合包含组中所有其他集合的索引,则一组集合可以共存。对吗?
-
是的。踢球者是您碰巧组装集合的递归序列会影响结果。
-
不清楚你的目标是什么。我认为这包含了您的大部分规则:
all(all(my_list_of_sets[i] & u for i in u) for u in my_list_of_sets)。但我不明白 RuleN 是关于什么的。 FWIW,这看起来像 Block Design 问题。 -
规则 N 也在交叉点中实现,但它会使代码不稳定,具体取决于输入交叉点的索引序列。您对块设计确实是正确的,bd 计数器是一个线索。让我研究一下那个 wiki 条目。
-
错字。集合可以与自身存在。会修复的。