扩展和缩小集合列表

时间:2018-05-25 07:10:33

标签: python loops set slice

好的,这是一个难以解释的问题。我解释它的难度使得创建我想要的循环变得困难。

考虑这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}]

我想应用以下类型的规则来扩展这些列表的交集产品。

Rule1:my_list_of_sets [0]可以与索引为0,1,2,3,4,5,7,9的my_list_of_sets相交。

Rule2:my_list_of_sets [1]可以与my_list_of_sets相交,索引为0,1,2,4,5,6,7

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的列表产品。

1 个答案:

答案 0 :(得分:0)

从AI constraint satisfaction的角度来看,值得一试。如果你计算出一组排除了多少东西,以及有多少组排除了这一组,你可以从最小约束开始并开始工作。

对于上面的示例(右轴是设置排除的内容,底部轴是排除该设置的数量)

   0 1 2 3 4 5 6 7 8 9
0: 1 1 1 1 1 1 0 1 0 1 | 2
1: 1 1 1 0 1 1 1 1 0 0 | 3
2: 1 1 1 1 1 0 0 0 1 1 | 3
3: 0 1 0 1 1 1 1 1 1 1 | 2
4: 0 1 1 1 1 1 1 0 0 0 | 4
5: 0 0 0 1 1 1 1 1 1 1 | 3
6: 0 1 1 1 0 1 1 0 1 1 | 3
7: 0 0 1 1 1 1 1 1 1 0 | 3
8: 0 0 1 0 0 1 1 1 1 1 | 4
9: 0 0 0 1 1 0 1 1 1 1 | 4
   - - - - - - - - - - 
   7 4 3 2 2 2 3 2 3 3 

约束总和:

  • 0 = 9
  • 1 = 7
  • 2 = 6
  • 3 = 4
  • 4 = 6
  • 5 = 5
  • 6 = 6
  • 7 = 5
  • 8 = 7
  • 9 = 7

所以,既然你已经解决了你的约束:

  1. 从最不受约束的集合开始:3
  2. 3擦掉0,2,8
  3. 添加您的下一个最小约束仍然有效:5
  4. 5擦掉1,9,2
  5. 添加您的下一个最小约束仍然有效:7
  6. 7擦掉4和6
  7. 没有更多有效的
  8. 你留下了一组:3,5,7