Цикл не выполняется и попадает в первую итерацию — проблема с рюкзаком Python (без ошибок)

#python #function #loops #lambda #knapsack-problem

#python #функция #циклы #лямбда #рюкзак-проблема

Вопрос:

Я новичок в Python и пробую свои навыки в уже запущенных кодах. Невозможно получить выходные данные по мере необходимости в виде списка выходных данных, а получить только первый ввод и детали.

Блоки кода функции. блок-1

 class Food(object):
    def __init__(self,n,v,w):
        self.name=n
        self.value=v
        self.calories=w
        
    def getValue(self):
        return self.value
    
    def getCost(self):
        return self.calories
    
    def density(self):
        return self.getValue()/self.getCost()
    
    def __str__(self):
        return self.name   ': <' str(self.value)  ',' str(self.calories) '>'
  

блок-2

 def buildMenu(names,values,calories):
    menu=[]
    for i in range(len(values)):
        menu.append(Food(names[i],values[i],calories[i]))
        return menu
  

блок-3

 def greedy(items,maxCost,keyFunction):
    itemsCopy=sorted(items,key=keyFunction,reverse=True)
    result=[]
    totalValue,totalCost=0.0,0.0
    
    for i in range(len(itemsCopy)):
        if(totalCost itemsCopy[i].getCost())<=maxCost:
            result.append(itemsCopy[i])
            totalCost =itemsCopy[i].getCost()
            totalValue =itemsCopy[i].getValue()
    return (result,totalValue)
  

блок-4

 def testGreedy(items,constraint,keyFunction):
    taken,val=greedy(items,constraint,keyFunction)
    print('Total value of items taken',val)
    for item in taken:
        print('  ',item)
  

блок-5

 def testGreedys(foods,maxUnits):
    print('Use greedy by value to allocate',maxUnits,'calories')
    testGreedy(foods,maxUnits,Food.getValue)
    print('nUse greedy by cost to allocate',maxUnits,'calories')
    testGreedy(foods,maxUnits,lambda x:1/Food.getCost(x)) 
    print('nUse greedy by density to allocate',maxUnits,'calories')
    testGreedy(foods,maxUnits,Food.density)
  

Основные блоки кода и ввод.

 names=['wine','beer','pizza','burger','fries','cola','apple','donut','cake']
values=[89,90,95,100,90,79,50,10]
calories=[123,154,258,354,365,150,95,195]
foods=buildMenu(names,values,calories)
testGreedys(foods,750)
  

Текущий вывод ниже принимает только первый элемент.На самом деле он должен выполняться для всего списка входных элементов в именах.

 Use greedy by value to allocate 750 calories
Total value of items taken 89.0
   wine: <89,123>

Use greedy by cost to allocate 750 calories
Total value of items taken 89.0
   wine: <89,123>

Use greedy by density to allocate 750 calories
Total value of items taken 89.0
   wine: <89,123>
  

Запросите вашу помощь для отладки и выясните, почему полный цикл не выполняется должным образом.

Ответ №1:

Ваш return for menu находится в цикле при создании меню. Это приводит к тому, что он возвращает только один элемент в меню, перемещая его на один отступ.

 def buildMenu(names,values,calories):
    menu=[]
    for i in range(len(values)):
        menu.append(Food(names[i],values[i],calories[i]))
    return menu

Total value of items taken 318.0
   apple: <50,95>
   wine: <89,123>
   cola: <79,150>
   beer: <90,154>
   donut: <10,195>
  

Комментарии:

1. Это сработало. Спасибо, что просветили меня. Это была действительно серьезная ошибка с моей стороны.

2. Это происходит! Всегда полезно помнить, что return функция завершит работу при ее вызове.

3. Спасибо за советы, которые очень важны, особенно при запуске вложенных циклов, мы не сможем определить проблемы.