Как заставить этот код работать лучше (список комбинаций)?

import random

def ordenar(inputx):
    inputx = list(inputx)
    inputx = sorted(inputx, key=int)
    return inputx

def get_numbers(totall):
    return random.sample(numeros, totall)

numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]

all_jogos = []
maximo_repetido = 9

vezes = 0

while True:
    numbers = get_numbers(15)
    for i in all_jogos:
        total_repetido = len(set(numbers).intersection(i))
        if total_repetido <= maximo_repetido:
            vezes += 1
        else:
            vezes = 0
            break
    if vezes >= len(all_jogos):
        all_jogos.append(numbers)
        print("%s," % ordenar(numbers))

В основном мое намерение состоит в том, чтобы сгенерировать списки из 15 чисел, чтобы между ними повторялось не более 9 чисел (переменная maximo_repetido), создавая как можно больше списков. Сравнение производится со всеми списками, содержащимися в all_jogos, которые растут с каждым циклом, пока условие принимается.

Проблема в том, что все возможные результаты никогда не могут быть получены, поскольку проверка/сравнение выполняется только после генерации 15 случайных чисел.

Как вы делаете условие/проверку/сравнение, когда вы собираетесь генерировать числа, заставляя вас искать только возможные результаты?


person Geek    schedule 02.06.2018    source источник
comment
Примечание: ordenar можно и нужно упростить до return sorted(inputx); входные данные уже представляют собой последовательности целых чисел, поэтому key=int является избыточным, а sorted уже преобразуется в новый list перед сортировкой, поэтому ручное построение списка с list() просто означает дополнительный бессмысленный временный список.   -  person ShadowRanger    schedule 02.06.2018
comment
Это правда, спасибо!   -  person Geek    schedule 02.06.2018


Ответы (1)


itertools.combinations(iterable, n) дает вам все комбинации элементов n длины в iterable. Это то, что вы хотите использовать здесь.

import itertools

numbers = range(1, 26)

combos = itertools.combinations(numbers, 15)

combos теперь является итератором (не списком, обратите внимание, поэтому, если вам нужно прочитать его более одного раза, вам нужно явно привести его) всех 15-длинных комбинаций чисел 1-25, и вы можете использовать A* или какой-либо другой алгоритм поиска пути, чтобы найти наилучшее возможное решение.

person Adam Smith    schedule 02.06.2018
comment
обратите внимание, что для этого определенно существует математическое решение, которое будет выполняться за постоянное время, но поиск этого решения зависит от вас! - person Adam Smith; 02.06.2018
comment
Этот код не ограничивает максимальное количество повторяющихся элементов среди всех возможных списков. (максимум 9) - person Geek; 02.06.2018
comment
@Geek правильно - это часть работы вашего алгоритма поиска пути (здесь не включена). Эта проблема обобщается на Как узнать, какая комбинация итераторов максимизирует определенную функцию полезности. - person Adam Smith; 02.06.2018
comment
Спасибо, но это все равно не решение моей проблемы. Я понятия не имею, как заставить ваш код работать так, как я хочу, так как я новичок в python. - person Geek; 02.06.2018
comment
@Geek, вот пример реализации A* в Python. Я бы предпочел A * здесь, так как у вас есть довольно четкая метрическая функция (в целом уменьшение количества перекрывающихся чисел на шаг будет лучше) - person Adam Smith; 02.06.2018
comment
Спасибо, теперь я понял вашу мысль :) - person Geek; 06.06.2018