您的位置:首页 > 编程语言 > Python开发

python实现:分别采用递归方法与动态规划算法实现“币值最大化问题”和“找零问题”。要求动态地调整两个问题的规模,记录程序运行时间。绘制曲线图比较在相同规模n情况下采用递归方式和动态规划实现的效率

2018-12-18 16:56 1626 查看

动态规划算法实现币值最大化问题: 传入列表list。创建一个描述最大币值的列表C。在列表C开头位置添加0。C第一个位置添加硬币第一个。从index=2开始到index=最后硬币的位置,循环。C列表每个index等于硬币列表list对应位置的值加上index-2位置(不连续的)的值和,与index-1(上一个位置)中的最大值。直到循环结束,C列表最后一个位置记录了,最大币值。

 

递归实现币值最大化问题: 不用新窗帘最大币值列表C,在币值列表list里直接更新数据。递归返回Index位置上的值,等于硬币列表list对应位置的值加上index-2位置(不连续的)的值和,与index-1(上一个位置)中的最大值。另一个返回值为当前位置。

 

动态规划算法实现找零问题: 传入硬币列表和需要找零的金额。如果硬币列表中有需找零金额,只需一个硬币即可,直接返回1。创建一个长度为需找零金额的大小。从1到此金额做循环。找到每个金额的最少硬币数。循环内循环查找,此金额减去每种硬币面值,那种情况所需硬币数最小。存入temp。最终返回。

 

递归实现找零问题: 同动态算法一样,硬币面值中含有需找零金额时,返回1。其余情况返回最小所需硬币数。

 

 

import time
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #正常显示中文标签
import random


list = [5,1,2,10,6,2] #币值最大化列表
D = [1,2,5,10]#为了方便设置 从小到大排序的列表 并缺硬币最小值为1。

#动态规划算法实现 币值最大化问题
def coin(list):
    list.insert(0, 0)
    C=[]
    C.append(0)
    C.append(list[1])
    for _ in range(2,len(list)):
        C.append(max((list[_]+C[_-2]),C[_-1])) 
    return C

#递归实现 币值最大化问题
def coin2(list,i):
    if i == 0:
        return 0
    if i == 1:
        return list[1]
    return max((list[i]+coin2(list,i-2)),coin2(list,i-1))

#递归实现 零钱找零
def coins_change(coin_values, change):
    min_count = change
    if change in coin_values:
        return 1
    for value in [i for i in coin_values if i <= change]:
        count = 1 + coins_change(coin_values, change-value)
        if count < min_count:
            min_count = count
    return min_count

#print('需要硬币个数:',coins_change(D,32))

#动态规划实现 零钱找零
def ChangeMaking(coin_values, change):
    if change in coin_values:
        return 1
    F = []
    F.append(0)
    for _ in range(1,change+1): #创建一个长度为change的列表
        F.append(0)
    for i in range(1,change+1):
        temp = 999
        j = 1
        while(j <= len(coin_values) and i >= coin_values[j-1]):
            temp = min(F[i - coin_values[j-1]], temp)
            j += 1
        F[i] = temp +1
    return F[i]

#print('需要硬币个数:',ChangeMaking(D,32))

#硬币最大化  动态输入硬币列表
'''
list = []
lei = int(input(" 请输入硬币种类数:"))
print("输入硬币种类:")
for _ in range(0,lei):
    list.append(int(input()))
print('硬币为:',list)
print('动态算法不相邻硬币最大化:',coin(list).pop())
# list.insert(0,0)           #若也要运行coin(),则注销这行; 若只运行coin2,则不注销
print('递归算法不相邻硬币最大化:',coin2(list,6))
'''

#找零问题
'''
D = []
lei = int(input(" 请输入硬币种类数:"))
print("输入硬币种类(包含币值为1):")
for _ in range(0,lei):
    D.append(int(input()))
D.sort()
print('硬币为:',D)
money = int(input("输入需要找零金额:"))
print('递归算法需要硬币个数:',coins_change(D,money))
print('动态算法需要硬币个数:',ChangeMaking(D,money))
'''

#硬币最大化 折线图对比动态规划和递归
'''
start_coin = []
end_coin = []
start_coin2 = []
end_coin2 = []
x = []
y_coin = []
y_coin2 = []

for _ in range(0,10):
    print(_+1)
    list = []
    lei = int(input(" 请输入硬币种类数:"))
    x.append(lei)
    for i in range(0, lei):
        list.append(random.randint(1,10))
    print('硬币为:', list)

    start_coin.append(time.time())
    print(coin(list).pop())
    end_coin.append(time.time())

    start_coin2.append(time.time())
    print(coin2(list,lei))
    end_coin2.append(time.time())

for _ in range(0, len(start_coin)):
    print((end_coin[_]-start_coin[_])*100000)
    y_coin.append((end_coin[_]-start_coin[_])*100000)

for _ in range(0, len(start_coin)):
    print((end_coin2[_]-start_coin2[_])*100000)
    y_coin2.append((end_coin2[_]-start_coin2[_])*100000)


plt.plot(x, y_coin, label='coin', linewidth=1, color='r', marker='o', markerfacecolor='blue', markersize=8)
plt.plot(x, y_coin2, label='coin2', linewidth=1, color='b', marker='o', markerfacecolor='blue', markersize=8)
plt.xlabel('num')
plt.ylabel('time')

plt.title('visible')
plt.legend()
plt.show()
'''

#找零问题 折线图对比动态规划和递归
start_Recursive = []
end_Recursive = []
start_dynamic = []
end_dynamic = []
x = []
y_Recursive = []
y_dynamic = []

D = []
D = [1, 2, 3, 5, 10]
D.sort()

for _ in range(0,10):
    print('\n','第',_+1,'次循环')
    print('硬币为:', D)
    money = int(input("输入需要找零金额:"))
    x.append(money)

    start_Recursive.append(time.time())
    print(coins_change(D,money))
    end_Recursive.append(time.time())

    start_dynamic.append(time.time())
    print(ChangeMaking(D,money))
    end_dynamic.append(time.time())

for _ in range(0, len(start_Recursive)):
    print((end_Recursive[_]-start_Recursive[_])*100000)
    y_Recursive.append((end_Recursive[_]-start_Recursive[_])*100000)

for _ in range(0, len(start_dynamic)):
    print((end_dynamic[_]-start_dynamic[_])*100000)
    y_dynamic.append((end_dynamic[_]-start_dynamic[_])*100000)


plt.plot(x, y_Recursive, label='Recursive', linewidth=1, color='r', marker='o', markerfacecolor='blue', markersize=8)
plt.plot(x, y_dynamic, label='dynamic', linewidth=1, color='b', marker='o', markerfacecolor='blue', markersize=8)
plt.xlabel('num')
plt.ylabel('time')

plt.title('visible')
plt.legend()
plt.show()

 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐