算法圖解 學習筆記

1.快速排序

import random

def quick_sort(ary):
    #基線條件:爲空或者只包含一個元素的數組是"有序"的
    if len(ary)<2:
        return ary
    else:
        print "in...",ary
        pivot=ary[0] #基準值
        less=[]      #所有小於基準值的數值放這
        greater=[]   #所有大於基準值的數值放這
        for i in ary[1:]:
            if i<=pivot:
                less.append(i)
            else:
                greater.append(i)        
        print "pivot=",pivot,"less",less,"greater",greater
        print "out...",less+[pivot]+greater
        return quick_sort(less)+[pivot]+quick_sort(greater)

xList=[]
for i in range(0,10):
    xList.append(random.randint(1,100))
quick_sort(xList)    
in... [44, 35, 79, 61, 37, 68, 64, 7, 89, 79]
pivot= 44 less [35, 37, 7] greater [79, 61, 68, 64, 89, 79]
out... [35, 37, 7, 44, 79, 61, 68, 64, 89, 79]
in... [35, 37, 7]
pivot= 35 less [7] greater [37]
out... [7, 35, 37]
in... [79, 61, 68, 64, 89, 79]
pivot= 79 less [61, 68, 64, 79] greater [89]
out... [61, 68, 64, 79, 79, 89]
in... [61, 68, 64, 79]
pivot= 61 less [] greater [68, 64, 79]
out... [61, 68, 64, 79]
in... [68, 64, 79]
pivot= 68 less [64] greater [79]
out... [64, 68, 79]

2.廣度優先算法

廣度優先算法可回答兩類問題:

1.從節點A觸發,有前往節點B的路徑嗎?

2.從節點A出發,前往節點B的那條路徑最短?

例子1:需找芒果銷售商

from collections import deque

def person_is_seller(name):
    return name[-1]=='m'

def test_1():
    graph={}
    graph["you"]=["alice","bob","claire"]
    graph["bob"]=["anuj","peggy"]
    graph["alice"]=["peggy"]
    graph["claire"]=["thom","jonny"]
    graph["anuj"]=[]
    graph["peggy"]=[]
    graph["thom"]=[]
    graph["jonny"]=[]
    search_queue=deque()
    search_queue+=graph["you"]
    while search_queue:                 #只要隊列不爲空
        person=search_queue.popleft()   #就取出其中的第一個人
        if person_is_seller(person):    #檢查這個人是否是芒果銷售商
            print person+"is a mango seller!";#是芒果銷售商
            return True;
        else:
            search_queue+=graph[person] #不是芒果銷售商。將這個人的朋友都加入搜索列表
    return False  #如果到了這裏,就說明隊伍中沒有芒果銷售商
test_1()

例子1中有人("peggy")檢查了兩次,做了無用功。因此應該優化一下:

from collections import deque

def person_is_seller(name):
    return name[-1]=='m'

def test_1():
    graph={}
    graph["you"]=["alice","bob","claire"]
    graph["bob"]=["anuj","peggy"]
    graph["alice"]=["peggy"]
    graph["claire"]=["thom","jonny"]
    graph["anuj"]=[]
    graph["peggy"]=[]
    graph["thom"]=[]
    graph["jonny"]=[]
    search_queue=deque()
    search_queue+=graph["you"]
    while search_queue:                 #只要隊列不爲空
        person=search_queue.popleft()   #就取出其中的第一個人
        if person_is_seller(person):    #檢查這個人是否是芒果銷售商
            print person+"is a mango seller!";#是芒果銷售商
            return True;
        else:
            search_queue+=graph[person] #不是芒果銷售商。將這個人的朋友都加入搜索列表
    return False  #如果到了這裏,就說明隊伍中沒有芒果銷售商

def test_2():
    graph={}
    graph["you"]=["alice","bob","claire"]
    graph["bob"]=["anuj","peggy"]
    graph["alice"]=["peggy"]
    graph["claire"]=["thom","jonny"]
    graph["anuj"]=[]
    graph["peggy"]=[]
    graph["thom"]=[]
    graph["jonny"]=[]
    search_queue=deque()
    search_queue+=graph["you"]
    searched=[]                         #這個數組用於檢測記錄過的人
    while search_queue:                 #只要隊列不爲空
        person=search_queue.popleft()   #就取出其中的第一個人
        if not person in searched:      #僅當這個人沒檢查過才檢查
            if person_is_seller(person):    #檢查這個人是否是芒果銷售商
                print person+"is a mango seller!";#是芒果銷售商
                return True;
            else:
                searched.append(person)   #標記檢查過的人
                search_queue+=graph[person] #不是芒果銷售商。將這個人的朋友都加入搜索列表
    return False  #如果到了這裏,就說明隊伍中沒有芒果銷售商


test_2()

3.狄克斯特拉算法 

下圖中,從起點到終點的最短路徑的總權重分別是多少?

 

processed=[]                         #這個數組用於檢測記錄過的人

def find_lowest_cost_node(costs):
    lowest_cost=float("inf")
    lowest_cost_node=None
    for node in costs:
        cost=costs[node]
        if cost<lowest_cost and node not in processed:
            lowest_cost=cost
            lowest_cost_node=node
    return lowest_cost_node

def test_3():
    global processed
    graph={}
    graph["start"]={}
    graph["start"]["a"]=5
    graph["start"]["b"]=2
    graph["a"]={}
    graph["a"]["c"]=4
    graph["a"]["d"]=2
    graph["b"]={}
    graph["b"]["a"]=8
    graph["b"]["d"]=7
    graph["c"]={}
    graph["c"]["d"]=6
    graph["c"]["fin"]=3
    graph["d"]={}
    graph["d"]["fin"]=1
    graph["fin"]={}
    infinity=float("inf")
    costs={}
    costs["a"]=5
    costs["b"]=2
    costs["c"]=infinity
    costs["d"]=infinity
    costs["fin"]=infinity
    parents={}
    parents["a"]="start"
    parents["b"]="start"
    parents["c"]=None
    parents["d"]=None
    parents["fin"]=None
    print "graph",graph
    print "costs",costs
    print "parents",parents
    node=find_lowest_cost_node(costs)
    while node is not None:
        cost=costs[node]
        neighbors=graph[node]
        for n in neighbors.keys():
            new_cost=cost+neighbors[n]
            if costs[n]>new_cost:
                costs[n]=new_cost
                parents[n]=node
        processed.append(node)
        node=find_lowest_cost_node(costs)
    print "graph",graph
    print "costs",costs
    print "parents",parents


test_3()

//開始

graph {'a': {'c': 4, 'd': 2}, 'c': {'fin': 3, 'd': 6}, 'b': {'a': 8, 'd': 7}, 'd': {'fin': 1}, 'start': {'a': 5, 'b': 2}, 'fin': {}}
costs {'a': 5, 'c': inf, 'b': 2, 'fin': inf, 'd': inf}
parents {'a': 'start', 'c': None, 'b': 'start', 'fin': None, 'd': None}

//運行結束
graph {'a': {'c': 4, 'd': 2}, 'c': {'fin': 3, 'd': 6}, 'b': {'a': 8, 'd': 7}, 'd': {'fin': 1}, 'start': {'a': 5, 'b': 2}, 'fin': {}}
costs {'a': 5, 'c': 9, 'b': 2, 'fin': 8, 'd': 7}
parents {'a': 'start', 'c': 'a', 'b': 'start', 'fin': 'd', 'd': 'a'}

path= fin -> d -> a -> start 
cost: 8

4.貪婪算法 廣播臺

states_needed=set(["mt","wa","or","id","nv","ut","ca","az"])
stations={}
stations["kone"]=set(["id","nv","ut"])
stations["ktwo"]=set(["wa","id","mt"])
stations["kthree"]=set(["or","nv","ca"])
stations["kfour"]=set(["nv","ut"])
stations["kfive"]=set(["ca","az"])
final_stations=set()
best_station=None
states_covered=set()
#第一步,找到最好的
for station,states_for_station in stations.items():
    covered=states_needed & states_for_station
    #print station
    if len(covered) > len(states_covered):
        best_station=station
        states_covered=covered
        #print best_station,states_covered
#字典是無序的,遍歷順序爲 kfive ktwo kthree kone kfour
#所以結果是:ktwo set(['mt', 'id', 'wa'])
print "best_station=",best_station,"states_covered=",states_covered
#第二部,找到全覆蓋的
final_stations.add(best_station)
states_needed-=states_covered
while states_needed:
    best_station=None
    states_covered=set()
    for station,states in stations.items():
        covered=states_needed & states
        if len(covered) > len(states_covered):
            best_station=station
            states_covered=covered
            states_needed-=states_covered
            final_stations.add(best_station)
print final_stations

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章