自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Python常用的算法——貪心算法(又稱貪婪算法),你知道嗎?

開發(fā) 后端 大數(shù)據(jù) 算法
貪心算法(又稱貪婪算法)是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優(yōu)上加以考慮,他所做出的的時在某種意義上的局部最優(yōu)解。

貪心算法(又稱貪婪算法)是指,在對問題求解時,總是做出在當前看來是好的選擇。也就是說,不從整體最優(yōu)上加以考慮,他所做出的的時在某種意義上的局部最優(yōu)解。

貪心算法并不保證會得到最優(yōu)解,但是在某些問題上貪心算法的解就是最優(yōu)解。要會判斷一個問題能否用貪心算法來計算。貪心算法和其他算法比較有明顯的區(qū)別,動態(tài)規(guī)劃每次都是綜合所有問題的子問題的解得到當前的最優(yōu)解(全局最優(yōu)解),而不是貪心地選擇;回溯法是嘗試選擇一條路,如果選擇錯了的話可以“反悔”,也就是回過頭來重新選擇其他的試試。

[[280667]]

1 找零問題

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

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

代碼如下:

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

2 背包問題

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

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

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

舉例: 

python常用的算法——貪心算法(又稱貪婪算法),你知道嗎?

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

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

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

分數(shù)背包代碼實現(xiàn):

  1. # 每個商品元組表示(價格,重量) 
  2. goods = [(60, 10), (100, 20), (120, 30)] 
  3. # 我們需要對商品首先進行排序,當然這里是排好序的 
  4. goods.sort(key=lambda x: x[0]/x[1], reverse=True
  5.   
  6. # w 表示背包的容量 
  7. def fractional_backpack(goods, w): 
  8.  # m 表示每個商品拿走多少個 
  9.  total_v = 0 
  10.  m = [0 for _ in range(len(goods))] 
  11.  for i, (prize, weight) in enumerate(goods): 
  12.  if w >= weight: 
  13.  m[i] = 1 
  14.  total_v += prize 
  15.  w -= weight 
  16.  # m[i] = 1 if w>= weight else weight / w 
  17.  else
  18.  m[i] = w / weight 
  19.  total_v += m[i]*prize 
  20.  w = 0 
  21.  break 
  22.  return m, total_v 
  23.   
  24. res1, res2 = fractional_backpack(goods, 50) 
  25. print(res1, res2) # [1, 1, 0.6666666666666666] 
  26. 1.3 拼接最大數(shù)字問題 

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

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

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

思路如下:

# 簡單的:當兩個等位數(shù)相比較

  1. a = '96' 
  2. b = '97' 
  3.   
  4. a + b if a > b else b + a 

# 當出現(xiàn)了下面的不等位數(shù)相比較,如何使用貪心算法呢?

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

  1.  a = '128' 
  2. b = '1286' 
  3.  # 字符串相加 
  4. a + b = '1281286' 
  5. b + a = '1286128' 
  6.   
  7. a + b if a + b > b + a else b + a 

數(shù)字拼接代碼如下:

  1. from functools import cmp_to_key 
  2.   
  3. li = [32, 94, 128, 1286, 6, 71] 
  4.   
  5. def xy_cmp(x, y): 
  6.  # 其中1表示x>y,-1,0同理 
  7.  if x+y < y+x: 
  8.  return 1 
  9.  elif x+y > y+x: 
  10.  return -1 
  11.  else
  12.  return 0 
  13.   
  14. def number_join(li): 
  15.  li = list(map(str, li)) 
  16.  li.sort(key=cmp_to_key(xy_cmp)) 
  17.  return "".join(li) 
  18.   
  19. print(number_join(li)) # 94716321286128 

4 活動選擇問題

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

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

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

python常用的算法——貪心算法(又稱貪婪算法),你知道嗎?

貪心結論:最先結束的活動一定是最優(yōu)解的一部分。

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

如果 a=b,結論成立

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

代碼如下:

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

5 最大子序和

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

代碼如下:

  1. def maxSubarray(li): 
  2.  s_max, s_sum = 0, 0 
  3.  for i in range(len(li)): 
  4.  s_sum += li[i] 
  5.  s_max = max(s_max, s_sum) 
  6.  if s_sum < 0: 
  7.  s_sum = 0 
  8.   
  9.  return s_max 

 

 

責任編輯:未麗燕 來源: 今日頭條
相關推薦

2021-10-14 06:52:47

算法校驗碼結構

2018-06-04 12:41:50

程序員貪心算法分析

2023-07-03 08:01:54

2020-12-24 18:44:34

RSA加密算法

2021-10-18 07:51:39

回溯算法面試

2020-04-22 11:19:07

貪心算法動態(tài)規(guī)劃

2014-06-03 10:05:13

2012-05-17 09:58:53

rsync

2018-11-21 10:47:46

排序算法TimsortPython

2023-10-28 09:00:03

進程系統(tǒng)服務

2019-03-05 11:22:17

操作系統(tǒng)調(diào)度算法

2020-11-12 08:22:29

貪心算法框架

2020-12-30 08:35:34

貪心算法監(jiān)控

2024-02-19 00:00:00

Console函數(shù)鏈接庫

2020-12-24 15:26:07

Redis數(shù)據(jù)庫

2020-12-03 11:07:15

數(shù)組貪心算法

2021-09-13 19:28:42

JavaNetty開發(fā)

2020-11-26 07:48:24

Shell 腳本內(nèi)置

2019-08-29 09:15:30

負載均衡算法備份

2023-12-12 08:41:01

點贊
收藏

51CTO技術棧公眾號