贪婪算法:
在对问题求解时,总是做出在 当前看来是最好的选择 当 前 看 来 是 最 好 的 选 择 。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择,贪心策略使用的前提是局部最优能导致全局最优。
设计过程:
1、建立数学模型来描述问题;
2、把求解的问题分成若干个子问题;
3、对每一子问题求解,得到子问题的局部最优解;
4、把所有子问题的局部最优解合成原始问题的一个解。
下面利用贪婪算法解决0-1背包问题:
[0-1背包问题] 有一个背包,背包容量是M=150kg。有7个物品,物品不可以分割成任意大小。
要求:尽可能让装入背包中的物品总价值最大,但不能超过总容量。
物品 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|
重量 | 35kg | 30kg | 6kg | 50kg | 40kg | 10kg | 25kg |
价值 | 10 | 40 | 30 | 50 | 35 | 40 | 30 |
算法实现(Python 3):
"""
贪婪算法:
1) 贪婪算法不一定能得到全局最优解,贪婪得到的是局部最优解,最终结果取决于贪婪策略;
2) 贪婪算法的时间消耗比穷举法低很多;
3) 遗传算法在整个随机空间内搜索,效率低,训练慢,可以先使用贪婪算法生成遗传算法的初始化种群的个体,
以缩小搜索空间,加快训练时间。
"""
class Item(object):
def __init__(self,n,v,w):
self.name=n
self.weight=float(w)
self.value=float(v)
def getName(self):
return self.name
def getValue(self):
return self.value
def getWeight(self):
return self.weight
def __str__(self):
result = ' < '+self.name+' , '+str(self.value)+' , '+str(self.weight) + '>'
return result
def value(item):
return item.getValue()
def weight_inverse(item):
return 1.0/item.getValue()
def density(item):
return item.getValue()/item.getWeight()
def greedy(items,max_weight,key_function):
items_order = sorted(items,key=key_function,reverse = True)
result = []
total_value = 0.0
total_weight = 0.0
for i in range(len(items_order)):
if(total_weight + items_order[i].getWeight()) <= max_weight:
result.append(items_order[i])
total_value += items_order[i].getValue()
total_weight += items_order[i].getWeight()
return result,total_value
def build_item():
names=['A','B','C','D','E','F','G']
values = [35,30,6,50,40,10,25]
weights=[10,40,30,50,35,40,30]
Items=[]
for i in range(len(names)):
Items.append(Item(names[i],values[i],weights[i]))
return Items
def greedy_run(items,constraint,key_function):
taken,val=greedy(items,constraint,key_function)
print ('Total value of items taken = ', val)
for item in taken:
print (' ', item)
if __name__ == '__main__' :
items = build_item()
print ('Use greedy by value to fill knapsack of size:')
greedy_run(items, 150, value)
print ('\n Use greedy by weight to fill knapsack of size:')
greedy_run(items, 150, weight_inverse)
print ('\n Use greedy by density to fill knapsack of size:')
greedy_run(items, 150, density)
运行结果:
Use greedy by value to fill knapsack:
Total value of items taken = 155.0
< D , 50.0 , 50.0>
< E , 40.0 , 35.0>
< A , 35.0 , 10.0>
< B , 30.0 , 40.0>
Use greedy by weight to fill knapsack:
Total value of items taken = 106.0
< C , 6.0 , 30.0>
< F , 10.0 , 40.0>
< G , 25.0 , 30.0>
< B , 30.0 , 40.0>
< A , 35.0 , 10.0>
Use greedy by density to fill knapsack:
Total value of items taken = 150.0
< A , 35.0 , 10.0>
< E , 40.0 , 35.0>
< D , 50.0 , 50.0>
< G , 25.0 , 30.0>