Расширение и уменьшение списка наборов - PullRequest
0 голосов
/ 25 мая 2018

ОК, это сложно объяснить.Это сложность, которую я объясняю, затрудняет создание цикла, который я хочу.

Рассмотрим этот список из 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] может пересекаться с my_list_of_sets с индексом 0,1,2,3,4,5,7,9.

Правило 2: 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 с индексами вmy_list_of_sets [x]

ПравилоN: 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))

Это перечисляет my_output_list из 15 наборов.

Проблема 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 последовательно увеличивался в значении индекса и пропускал некоторые возможные комбинации.

Так что, хотя у меня уже есть скользящий фрагмент bd для итерации цикла 0 Я думаю, что мне дополнительно нужны itertools для просмотра индекса во всех комбинациях my_list_of_sets [0].

Параредактирует.Я не могу грубо заставить все комбо и убрать незаконные.Это список len 100, который составляет 100 ^ 100 комбинаций, и компьютер не может этого сделать.Я знаю, что мой ответ может лежать в itertools, но я не представляю его для продуктов списков длиной> 2.

1 Ответ

0 голосов
/ 25 мая 2018

Может стоить попробовать с точки зрения ИИ удовлетворение ограничения .Если вы подсчитаете, сколько вещей набор исключает, и сколько наборов исключает этот набор, вы можете начать с наименьшего ограничения и продолжить работу.

Для вашего примера выше (правая ось - это количество вещей, которые исключает наборнижняя ось - это количество вещей, исключающих этот набор)

   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. Нет больше действительных

You 'осталось с группой: 3, 5, 7

...