2012-11-29 4 views
0

У меня есть список элементов и вы хотите создать все возможные подмножества. Поэтому я использую рекурсивную функцию с номером позиции и списком всех выбранных элементов в качестве параметров. Функция вызывается с 0 в качестве первого параметра и выполняет следующие действия:как использовать инструкцию yield python

  • Он смотрит на пункт, описанного параметром индекса
  • Он выбирает его
  • Он называет себя с увеличенным параметром индекса
  • Это отменяет товар
  • Он называет себя с порядковым параметром индекса

Я нуждаясь возможными подмножества чтобы что-то оптимизировать, но поскольку список будет очень длинным, я не могу смотреть на них всех. Сначала я попытался использовать грубую силу для учета всех подмножеств, но это была наивная идея. Теперь новый план состоит в том, чтобы создать жадный алгоритм, который принимает первый «полезный» выбор: я хочу посмотреть на все подмножества, пока не найду тот, который соответствует моим потребностям, и решил, что оператор yield python является правильным выбором. Вот код:

def bruteForceLeft(selected,index): 
    #left is the list of which i need subsets 
    #its a gobal variable. to test the code, just make sure that you have a 
    #list called left in scope 
    if index==len(left): 
     #print(selected) 
     yield selected 
    else: 
     #the algorithm stores the selection in a tuple of two lists 
     #that's necessary since there's a second list called right as well 
     #I think you can just ignore this. Think of selected as a list that 
     #contains the current selection, not a tuple that contains the current 
     #selection on the right as well as the left side. 
     selected[0].append(left[index]) 
     bruteForceLeft(selected,index+1) 
     selected[0].pop() 
     bruteForceLeft(selected,index+1) 

#as you can see I pass a tuple of two empty lists to the function. 
#only the first one is used in this piece of code 
for option in bruteForceLeft(([],[]) ,0): 
    print(option) 
    #check if the option is "good" 
    #break 

Выход: ничего

Сначала я думал, что я сделал ошибку в генерации подмножеств, но в если условие вы можете увидеть, что у меня есть комментировал заявление для печати , Если я раскомментирую этот оператор печати и вместо этого закомментирую инструкцию yield, будут напечатаны все возможные варианты выбора - и цикл цикла будет прерван

С оператором yield код работает без ошибок, но он ничего не делает.

+0

Я все еще не понимаю, какой должен быть вход/выход. – Aesthete

+1

Это не отвечает на ваш вопрос, но если вы не делаете это как упражнение, вероятно, стоит проверить [itertools.combinations] (http://docs.python.org/2/library/itertools.html# itertools.combinations). Все подмножества были бы объединением комбинаций длины (1) в длину (n), я считаю, – goncalopp

+0

goncalopp, вы просто напомнили мне, почему я люблю python – lhk

ответ

4

Проблема заключается в том, что при рекурсивном вызове bruteForceLeft полученные значения не получают магического значения из прилагаемой функции. Таким образом, вы должны заново дать им себя:

(Edit: Я на самом деле просто проверил это, и ваш код ошибки, но я уверен, что повторно не уступающие является проблемой)

+0

имеет смысл, я попробую его – lhk

+0

работает отлично, +1 и принят. Спасибо за быстрый ответ. – lhk

+0

hm, я могу принять ответ через 6 минут - думаю, нам нужно подождать – lhk

Смежные вопросы