简体   繁体   中英

Loop not running and get struck with the first iteration -Python Knapsack problem (No error)

Self new to Python and trying my skills on already run codes. Unable to get the output as required as a list of output rather getting only the first input and the details.

Function code blocks. block-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)+'>'

block-2

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

block-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)

block-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)

block-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)

Main code blocks and input.

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)

Current output below is taking only the first element.Actually it should run for the entire input item list in names.

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>

Request your help to debug and find out why the complete loop not running as intended.

Your return for menu is in the loop when you build a menu. This causes it to only ever return one item in the menu, move it back one indentation.

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM