每日算法第4天:温柔的贪心算法——外卖小哥配送问题
Posted AI科技与算法编程
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日算法第4天:温柔的贪心算法——外卖小哥配送问题相关的知识,希望对你有一定的参考价值。
废话不多说,直接上货....
不好意思,前几天有事,没来得及更新
贪心算法
贪婪(或贪婪)是设计算法最流行的方法之一。如果您读过民间故事,那么会有一个这样的故事:在装有许多菜肴的托盘上,我们将首先食用最好的菜肴,完成该菜肴后,我们将切换为第二道美味的菜肴,然后再转到第三道菜肴。
基于贪婪的思想设计了许多著名的算法,例如Dijkstra的最小帧算法,Kruskal的最小帧算法。
贪婪算法是一种组合优化算法。该算法通过在搜索中选择最优解的算法在每个步骤中选择局部最优解,以期找到全局最优解。
这里通过一个例子说明贪心算法是什么玩意儿,以了解如何实现贪心算法以及为什么此算法不是最佳算法。但是仍然有可用之处。
从数学的角度来讲,贪心算法就类似微分方程中的找解的问题,从某个初始解出发,去逼近给定的而目标以此获得很好的解。
贪婪算法应用示例
基于贪婪算法思想设计了许多著名的算法。这是这些算法之一:
硬币问题
推销员旅程的问题
Prim的最小算法
Kruskal的最小生成算法
Dijkstra的最小扩展算法
工作安排问题
背包问题
我们这里拿硬币和外卖小哥取餐问题作为案例:
1、硬币最少问题
假设你作为收收银员正在美国的一个超市卖口罩,如果目前你现有的美元面值只有1美元,2美元,5美元,10美元的硬币,规定收银员也就是你需要选择最少的硬币上给顾客,那么给定顾客零钱数的情况下,如何求得最少的硬币数?
假设:顾客给出的零钱的为19美元,也就是需要收银员退还顾客19美元
下面给出方案:
(1)1枚美10元硬币
(2)1枚5美元硬币
(3)两枚2美元硬币
至此,问题解决需要3步完成,所需硬币数目为4。当然还有其他方案,但是我们应该选择最优的,而非麻烦的。
具体实现源码:
def main():
d = [1, 2, 5, 10] # 存储每种硬币面值
d_num = [] # 存储每种硬币的数量
s = 0
# 拥有的零钱总和
temp = input('请输入每种零钱的数量:')
d_num0 = temp.split(" ")
for i in range(0, len(d_num0)):
d_num.append(int(d_num0[i]))
s += d[i] * d_num[i] # 计算出收银员拥有多少钱
sum = float(input("请输入需要找的零钱:"))
if sum > s:
# 当输入的总金额比收银员的总金额多时,无法进行找零
print("数据有错")
return 0
s = s - sum
# 要想用的钱币数量最少,那么需要利用所有面值大的钱币,因此从数组的面值大的元素开始遍历
i =3
while i >= 0:
if sum >= d[i]:
n = int(sum / d[i])
if n >= d_num[i]:
n = d_num[i] # 更新n
sum -= n * d[i] # 贪心的关键步骤,令sum动态的改变,
print("用了%d个%f美元硬币"%(n, d[i]))
i -= 1
if __name__ == "__main__":
main()
执行结果:
请输入每种零钱的数量:5 8 6 4
请输入需要找的零钱:19
用了1个10.000000美元硬币
用了1个5.000000美元硬币
用了2个2.000000美元硬币
Process finished with exit code 0
下面是限制一定条件下展开的,没考虑挣更多的钱,如有问题欢迎留言 以上是关于每日算法第4天:温柔的贪心算法——外卖小哥配送问题的主要内容,如果未能解决你的问题,请参考以下文章 外卖配送基于matlab蚁群算法求解外卖配送问题含Matlab源码 2351期 配送路径规划基于matlab遗传算法求解静态外卖骑手路径规划问题含Matlab源码 2248期