Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中的贪心算法_Python_List_Sorting_Tuples_Greedy - Fatal编程技术网

Python中的贪心算法

Python中的贪心算法,python,list,sorting,tuples,greedy,Python,List,Sorting,Tuples,Greedy,我希望掠夺中的c(aList,c)等于0 List = [('Gold', 10, 500), ('Silver', 5, 200), ('Diamond', 2, 2000), ('Platinum', 20, 1000)] aList = sorted(List, key = lambda x : x[2]) # sort the list above 根据每个元组的第三个值给出排序列表。所以我得到: [('Silver', 5, 200), ('Gold', 10, 500), ('P

我希望掠夺中的c(aList,c)等于0

List = [('Gold', 10, 500), ('Silver', 5, 200), ('Diamond', 2, 2000), ('Platinum', 20, 1000)]
aList = sorted(List, key =  lambda x : x[2]) # sort the list above
根据每个元组的第三个值给出排序列表。所以我得到:

[('Silver', 5, 200), ('Gold', 10, 500), ('Platinum', 20, 1000), ('Diamond', 2, 2000)]
我试图让掠夺(aList,c)不断地从c中减去每个元组(2,20,10,5)的中间值,直到c=0

这是我的密码:

List = [('Gold', 10, 500), ('Silver', 5, 200), ('Diamond', 2, 2000), ('Platinum', 20, 1000)]
aList = sorted(List, key =  lambda x : x[2]) # sort the list above

def plunder(aList, c):
    aList[-1] = list(aList[-1])
    i = aList[-1]
    r = 0
    if c > 0 and i[1] != 0:
        c -= 1
        i[1] -=1
        r += 1
        return plunder(aList, c-r)
    elif c == 0:
        pass
        print('Done')
    else:
        return plunder(aList[:-1], c-r)

plunder(aList, 10)
但当我运行它时,它会打印“完成”,新列表是:

[('Silver', 5, 200), ('Gold', 10, 500), ('Platinum', 20, 1000), ['Diamond', 0, 2000]]
当我在pythonshell中输入c时,它告诉我c没有定义。我如何解决这些问题

如果c值是10。我的预期产出是:

[('Silver', 5, 200), ('Gold', 10, 500), ['Platinum', 12, 1000], ['Diamond', 0, 2000]]

我从10颗钻石中减去尽可能多的钻石(10-2=8),所以剩下0颗钻石。然后我从20个platinums中减去8,platinums的重量变为12(因为我得到了8个platinums。现在我的c(“容量”)是0.2菱形+8个platinums=10(这是我的c)。

主要的问题是,您依赖Python的pass by reference来修改列表。 这在一开始很好,但当你到达

plunder(aList[:-1], c-r)
Python创建列表的副本,并继续修改该副本。因此,在钻石耗尽后,原始列表保持不变(您点击
其他
部分)

请注意,您可以在打印的
列表中看到这种行为,因为只有最后一个条目是
列表
,而所有其他条目都是元组

[
 ('Silver', 5, 200), 
 ('Gold', 10, 500), 
 ('Platinum', 20, 1000), 
 ['Diamond', 0, 2000]   #Only list
]
如果将
print alist[-1]
语句添加到函数中,您可以更清楚地看到它

['Diamond', 2, 2000]
['Diamond', 1, 2000]
['Diamond', 0, 2000]
['Platinum', 20, 1000]
['Platinum', 19, 1000]
['Platinum', 18, 1000]
['Platinum', 17, 1000]
['Platinum', 16, 1000]
['Platinum', 15, 1000]
['Platinum', 14, 1000]
['Platinum', 13, 1000]
['Platinum', 12, 1000]

因此,您的算法确实有效,但由于无法保留结果,因此不会(完全)影响原始列表。

主要问题是,您依赖Python的列表传递引用来修改列表。 这在一开始很好,但当你到达

plunder(aList[:-1], c-r)
Python创建列表的副本,并继续修改该副本。因此,在钻石耗尽后,原始列表保持不变(您点击
其他
部分)

请注意,您可以在打印的
列表中看到这种行为,因为只有最后一个条目是
列表
,而所有其他条目都是元组

[
 ('Silver', 5, 200), 
 ('Gold', 10, 500), 
 ('Platinum', 20, 1000), 
 ['Diamond', 0, 2000]   #Only list
]
如果将
print alist[-1]
语句添加到函数中,您可以更清楚地看到它

['Diamond', 2, 2000]
['Diamond', 1, 2000]
['Diamond', 0, 2000]
['Platinum', 20, 1000]
['Platinum', 19, 1000]
['Platinum', 18, 1000]
['Platinum', 17, 1000]
['Platinum', 16, 1000]
['Platinum', 15, 1000]
['Platinum', 14, 1000]
['Platinum', 13, 1000]
['Platinum', 12, 1000]

因此,您的算法确实有效,但由于您无法保留结果,因此它不会(完全)影响您的原始列表。

我认为这是一种更简单的方法。只需在可用的宝藏中进行迭代,并从每一个宝藏中获取尽可能多的信息

def demo():
    units_to_plunder = 10
    treasure = new_treasure_pile()
    plundered_units = plunder_units(treasure, units_to_plunder)
    print treasure
    print plundered_units

    units_to_plunder = 1000
    treasure = new_treasure_pile()
    plundered_units = plunder_units(treasure, units_to_plunder)
    print treasure
    print plundered_units



def plunder_units(treasure, total_plunder_units):
    treasure_sorted = list(sorted(treasure, key=lambda t: t[2], reverse=True))
    plundered = list()
    for treasure_type in treasure_sorted:
        # stop condition when desired units taken
        if total_plunder_units <= 0:
            break
        t_units_to_take = min(total_plunder_units, treasure_type[1])
        # update the 3 moving parts
        treasure_type[1] -= t_units_to_take
        plundered.append([treasure_type[0], t_units_to_take, treasure_type[2]])
        total_plunder_units -= t_units_to_take
    return plundered


def new_treasure_pile():
    return [['Gold', 10, 500],
            ['Silver', 5, 200],
            ['Diamond', 2, 2000],
            ['Platinum', 20, 1000]]


if __name__ == '__main__':
    demo()
c=1000的输出(全部接受)
我认为这是一个更简单的方法。只需在可用的宝藏中迭代,并从每个宝藏中获取尽可能多的信息

def demo():
    units_to_plunder = 10
    treasure = new_treasure_pile()
    plundered_units = plunder_units(treasure, units_to_plunder)
    print treasure
    print plundered_units

    units_to_plunder = 1000
    treasure = new_treasure_pile()
    plundered_units = plunder_units(treasure, units_to_plunder)
    print treasure
    print plundered_units



def plunder_units(treasure, total_plunder_units):
    treasure_sorted = list(sorted(treasure, key=lambda t: t[2], reverse=True))
    plundered = list()
    for treasure_type in treasure_sorted:
        # stop condition when desired units taken
        if total_plunder_units <= 0:
            break
        t_units_to_take = min(total_plunder_units, treasure_type[1])
        # update the 3 moving parts
        treasure_type[1] -= t_units_to_take
        plundered.append([treasure_type[0], t_units_to_take, treasure_type[2]])
        total_plunder_units -= t_units_to_take
    return plundered


def new_treasure_pile():
    return [['Gold', 10, 500],
            ['Silver', 5, 200],
            ['Diamond', 2, 2000],
            ['Platinum', 20, 1000]]


if __name__ == '__main__':
    demo()
c=1000的输出(全部接受)
您可以发布您的预期输出吗?也就是说,您希望列表的结尾是什么样子?第5行中的
aList[-1]=list(aList[-1]
的要点是什么?aList[-1]=list(aList[-1]将元组转换为列表。因为我可以更改列表中的元素,但不能更改元组中的元素。我认为这可能是您的问题。当您键入
aList[-1]=list(aList[-1])
时,现在aList有一个列表-即
['Diamond',22000]
-作为它的最后一个元素。这应该是一个元组。对吗?这看起来像背包问题,权重被替换为文章数。请发布您的预期输出?也就是说,您希望列表的结尾是什么样子?第5行中的
aList[-1]=list(aList[-1]
的意义是什么?aList[-1]的意义是什么=列表(aList[-1]是将元组转换为列表。因为我可以更改列表中的元素,但不能更改元组中的元素。我认为这可能是您的问题。当您键入
aList[-1]=列表(aList[-1])
时,现在aList有一个列表-即
['Diamond',22000]
-作为它的最后一个元素。这应该是一个元组。对吗?这看起来像是背包问题,权重被ArticleNumber替换。我想补充一点,函数从基本情况中不返回任何内容,因此结果不能沿调用堆栈累积。我想补充一点,函数从基本情况中不返回任何内容,因此,结果不能沿调用堆栈累积。