溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用Python貪心算法

發布時間:2021-11-20 11:15:32 來源:億速云 閱讀:154 作者:iii 欄目:編程語言

這篇文章主要介紹“怎么使用Python貪心算法”,在日常操作中,相信很多人在怎么使用Python貪心算法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么使用Python貪心算法”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

1 找零問題

假設商店老板需要找零 n 元錢,錢幣的面額有100元,50元,20元,5元,1元,如何找零使得所需錢幣的數量最少?(注意:沒有10元的面額)

那要是找376元零錢呢? 100*3+50*1+20*1+5*1+1*1=375

代碼如下:

# t表示商店有的零錢的面額 t = [100, 50, 20, 5, 1]   # n 表示n元錢 def change(t, n):  m = [0 for _ in range(len(t))]  for i, money in enumerate(t):  m[i] = n // money # 除法向下取整  n = n % money # 除法取余  return m, n   print(change(t, 376)) # ([3, 1, 1, 1, 1], 0)

2 背包問題

常見的背包問題有整數背包和部分背包問題。那問題的描述大致是這樣的。

一個小偷在某個商店發現有 n 個商品,第 i 個商品價值 Vi元,重 Wi  千克。他希望拿走的價值盡量高,但他的背包最多只能容納W千克的東西。他應該拿走那些商品?

  • 0-1背包:對于一個商品,小偷要么把他完整拿走,要么留下。不能只拿走一部分,或把一個商品拿走多次(商品為金條)

  • 分數背包:對于一個商品,小偷可以拿走其中任意一部分。(商品為金砂)

對于 0-1 背包 和 分數背包,貪心算法是否都能得到最優解?為什么?

顯然,貪心算法對于分數背包肯定能得到最優解,我們計算每個物品的單位重量的價值,然后將他們降序排序,接著開始拿物品,只要裝得下全部的該類物品那么就可以全裝進去,如果不能全部裝下就裝部分進去直到背包裝滿為止。

而對于此問題來說,顯然0-1背包肯定裝不滿。即使偶然可以,但是也不能滿足所有0-1背包問題。0-1背包(又叫整數背包問題)還可以分為兩種:一種是每類物品數量都是有限的(bounded)。一種是數量無限(unbounded),也就是你想要的多少有多少,這兩種都不能使用貪心策略。0-1背包是典型的第一種整數背包問題。

分數背包代碼實現:

# 每個商品元組表示(價格,重量) goods = [(60, 10), (100, 20), (120, 30)] # 我們需要對商品首先進行排序,當然這里是排好序的 goods.sort(key=lambda x: x[0]/x[1], reverse=True)   # w 表示背包的容量 def fractional_backpack(goods, w):  # m 表示每個商品拿走多少個  total_v = 0  m = [0 for _ in range(len(goods))]  for i, (prize, weight) in enumerate(goods):  if w >= weight:  m[i] = 1  total_v += prize  w -= weight  # m[i] = 1 if w>= weight else weight / w  else:  m[i] = w / weight  total_v += m[i]*prize  w = 0  break  return m, total_v   res1, res2 = fractional_backpack(goods, 50) print(res1, res2) # [1, 1, 0.6666666666666666] 1.3 拼接最大數字問題

有 n 個非負數,將其按照字符串拼接的方式拼接為一個整數。如何拼接可以使得得到的整數最大?

例如:32, 94, 128, 1286, 6, 71 可以拼接成的最大整數為 94716321286128.

注意1:字符串比較數字大小和整數比較數字大小不一樣!!!  字符串比較大小就是首先看第一位,大的就大,可是一個字符串長,一個字符串短如何比較呢?比如128和1286比較

思路如下:

# 簡單的:當兩個等位數相比較

a = '96' b = '97'   a + b if a > b else b + a

# 當出現了下面的不等位數相比較,如何使用貪心算法呢?

# 我們轉化思路,拼接字符串,比較結果

 a = '128' b = '1286'  # 字符串相加 a + b = '1281286' b + a = '1286128'   a + b if a + b > b + a else b + a

數字拼接代碼如下:

from functools import cmp_to_key   li = [32, 94, 128, 1286, 6, 71]   def xy_cmp(x, y):  # 其中1表示x>y,-1,0同理  if x+y < y+x:  return 1  elif x+y > y+x:  return -1  else:  return 0   def number_join(li):  li = list(map(str, li))  li.sort(key=cmp_to_key(xy_cmp))  return "".join(li)   print(number_join(li)) # 94716321286128

4 活動選擇問題

假設有 n 個活動,這些活動要占用同一片場地,而場地在某時刻只能供一個活動使用。

每一個活動都有一個開始時間 Si 和結束時間 Fi (題目中時間以整數表示)表示活動在 [Si, fi) 區間占用場地。(注意:左開右閉)

問:安排哪些活動能夠使該場地舉辦的活動的個數最多?

貪心結論:最先結束的活動一定是最優解的一部分。

證明:假設 a 是所有活動中最先結束的活動,b是最優解中最先結束的活動。

如果 a=b,結論成立

如果 a!=b,則 b 的結束時間一定晚于 a 的結束時間,則此時用 a 替換掉最優解中的 b ,a  一定不與最優解中的其他活動時間重疊,因此替換后的解也是最優解。

代碼如下:

# 一個元組表示一個活動,(開始時間,結束時間) activities = [(1, 4), (3, 5), (0, 6), (5, 7), (3, 9), (5, 9), (6, 10), (8, 11),  (8, 12), (2, 14), (12, 16)]   # 保證活動是按照結束時間排好序,我們可以自己先排序 activities.sort(key=lambda x:x[1])   def activity_selection(a):  # 首先a[0] 肯定是最早結束的  res = [a[0]]  for i in range(1, len(a)):  if a[i][0] >= res[-1][1]: # 當前活動的開始時間小于等于最后一個入選活動的結束時間  # 不沖突  res.append(a[i])  return res   res = activity_selection(activities) print(res)

5 最大子序和

求最大子數組之和的問題就是給定一個整數數組(數組元素有負有正),求其連續子數組之和的最大值。下面使用貪心算法逐個遍歷。

代碼如下:

def maxSubarray(li):  s_max, s_sum = 0, 0  for i in range(len(li)):  s_sum += li[i]  s_max = max(s_max, s_sum)  if s_sum < 0:  s_sum = 0    return s_max

到此,關于“怎么使用Python貪心算法”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女