贪心算法讲解(集合覆盖问题,旅行商问题求解)
教室調度問題
假設有如下課程表,你希望將盡可能多的課程安排在某間教室上。
你沒法讓這些課都在這間教室上,因為有些課的上課時間有沖突。
你希望在這間教室上盡可能多的課。如何選出盡可能多且時間不沖突的課程呢?
這個問題好像很難,不是嗎?實際上,算法可能簡單得讓你大吃-一驚。具體做法如下。
很多人都跟我說,這個算法太容易、太顯而易見,肯定不對。但這正是貪婪算法的優點一簡單易行! 貪婪算法很簡單:每步都采取最優的做法。在這個示例中,你每次都選擇結束最早的課。用專業術語說,就是你每步都選擇局部最優解,最終得到的就是;全局最優解。信不信由你,對于這個調度問題,上述簡單算法找到的就是最優解!
貪心算法可能找到的不是最優解,但接近最優解啦。
集合覆蓋問題
假設你辦了個廣播節目,要讓全美50個州的聽眾都收聽得到。為此,你需要決定在哪些廣播臺播出。在每個廣播臺播出都需要支付費用,因此你力圖在盡可能少的廣播臺播出。現有廣播臺名單如下。每個廣播臺都覆蓋特定的區域,不同廣播臺的覆蓋區域可能重疊。
我們用貪心算法求解
貪婪算法可化解危機!使用下面的貪婪算法可得到非常接近的解。
代碼
出于簡化考慮,這里假設要覆蓋的州沒有那么多,廣播臺也沒有那么多。
全部代碼
語言:python
旅行商問題
旅行商問題(TravelingSalesmanProblem,TSP)一個商品推銷員要去若干個城市推銷商品,該推銷員從一個城市出發,需要遍歷所有城市一次且只能一次,回到出發地。應如何選擇行進路線,以使總的行程最短。目前解決TSP問題的方法有許多種,比如:貪心算法、動態規劃算法、分支限界法;也有智能算法。本文先介紹貪心算法:
數據 如下圖,第一列城市名。第二列坐標x,第三列坐標y
語言:python
貪心算法思路:隨便選擇出發城市,然后每次選擇要去的下一個城市時,都選擇還沒去的最近的城市。
第一步:讀取數據
import pandas as pd import numpy as np import math import timedataframe = pd.read_csv("TSP.csv", sep=",", header=None) v = dataframe.iloc[:, 1:3]#去除第一列12345678910,只保留x,y print(v)第二步:計算城市之間的距離
train_v= np.array(v) train_d=train_v #初始化距離 為10*10的全0矩陣 dist = np.zeros((train_v.shape[0],train_d.shape[0])) #print(dist.shape)#(10,10)#計算距離矩陣 for i in range(train_v.shape[0]):for j in range(train_d.shape[0]):dist[i,j] = math.sqrt(np.sum((train_v[i,:]-train_d[j,:])**2)) print(dist)第三步:計算距離和路徑
""" s:已經遍歷過的城市 dist:城市間距離矩陣 sumpath:目前的最小路徑總長度 Dtemp:當前最小距離 flag:訪問標記 """i=1 n=train_v.shape[0]#城市個數 j=0 sumpath=0#目前的最小路徑總長度 s=[]#已經遍歷過的城市 s.append(0)#從城市0開始 start = time.clock() while True:k=1#從1開始,因為人在城市0,所以我們設定先從城市1開始選擇Detemp=float('inf')#當前最小距離while True:flag=0#訪問標記,否0if k in s:#是否訪問,如果訪問過,flag設為1flag = 1if (flag==0) and (dist[k][s[i-1]] < Detemp):#如果未訪問過,并且距離小于最小距離j = k;Detemp=dist[k][s[i - 1]];#當前兩做城市相鄰距離k+=1#遍歷下一城市if k>=n:break;s.append(j)i+=1;sumpath+=Detempif i>=n:break;sumpath+=dist[0][j]#加上dist[0][j] 表示最后又回到起點 end = time.clock() print("結果:") print(sumpath) for m in range(n):print("%s-> "%(s[m]),end='') print() print("程序的運行時間是:%s"%(end-start))該段代碼借鑒 他人
代碼解析:數字k表示當前我們選擇前往下一個城市時,我們需要計算所有未訪問過的城市和當前城市距離。
數字i 用于控制訪問過的城市,我們需要到達每一個城市。
代碼中有兩個while
里面那個while表示選擇下一城市時,需要遍歷所有未訪問過的城市,然后選擇距離當前城市最近的城市,賦值給j
外面while,表示我們的每一步,我們需要去每個城市。
作者:電氣-余登武
總結
以上是生活随笔為你收集整理的贪心算法讲解(集合覆盖问题,旅行商问题求解)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 合肥字节跳动工资待遇 高薪岗位有这些
- 下一篇: 2022款五菱宏光s3方向盘怎么调高低?