从如何最快找到男(女)朋友说起 (BFS 最短路径,几度人脉问题

2020-05-20  本文已影响0人  SpringAlways

题目

520了,假如你还是单身,想利用自己的人脉关系,最快找到最心仪、一见钟情的他(她)。该怎么努力找到他(她)呢?

算法选定

最短路径问题的解法,最常见的办法就是BFS(广度优先搜索)

抽象模型
image.png

假设thon和jam都是你心仪的,并且和你一见钟情的。

代码关键逻辑
代码实现
# coding=UTF-8
from collections import deque

graph   = {}
graph["you"]        = ["alice", "bob", "Claire"]
graph["bob"]        = ["anuj", "peggy"]
graph["alice"]      = ["peggy"]
graph["claire"]     = ["thon", "jonny"]
graph["anuj"]       = []
graph["peggy"]      = []
graph["thon"]       = ["jam"]
graph["jonny"]      = ["jam"]
graph["jam"]        = []

print(graph)

parents             = {}

def isLove(name):
    if len(name) < 1:
        return False
    return name[-1] == 'n' or name[-1] == 'm'

def relations(name):
    num             = 0
    chain           = name
    while parents[name] != None:
        num         += 1
        name        = parents[name]
        chain       = name + "->" + chain
    return (str(num), chain)

def addParent(neighbors, parent):
    for n in neighbors:
        parents[n]      = parent

def search(name):
    parents[name]       = None
    search_queue        = deque()
    searched            = []
    neighbors           = graph[name]
    search_queue        += neighbors
    addParent(neighbors, name)

    while search_queue:
        top             = search_queue.popleft()
        if not top in searched:
            if isLove(top):
                relation = relations(top)
                print '我亲爱的他(她),名叫' + top + ", 他(她)是我的" + relation[0] + "度人脉。" + "关系链条为:" + relation[1]
                return True
            else:
                neighbors    = graph[top]
                search_queue += neighbors
                searched.append(top)
                addParent(neighbors, top)
    return False


search("you")


运行结果 我亲爱的他(她),名叫thon, 她是我的2度人脉。关系链条为:you->claire->thon

520,祝大家有情人终成眷属~


520分割线,以下已归正传

image.png

BFS

graph   = {}
graph["A"]        = ["B", "C"]
graph["B"]        = ["A", "C"]
graph["C"]        = ["A", "B", "E"]
graph["D"]        = ["B","E","F"]
graph["E"]        = ["C", "D", "G"]
graph["G"]        = ["E"]
graph["F"]        = ["D", "H"]
graph["H"]        = ["F"]
queue       = deque()
queue.append(vertex)

出:

v       = queue.popleft()

依次出,在出的时候执行搜索的任务就行了,我们这里的任务是print()

第五步:循环搜索就可以了

    while queue:
        v       = queue.popleft()
        neibs   = graph[v]
        for n in neibs:
            if n not in searched:
                queue.append(n)
                searched.add(n)
        print("bfs-> " + v)

DFS

dfs其实只需要改一行即可。把先进先出,改为先进后出,每次取队列的尾部就可以了。v = queue.popleft()改为 v = queue.pop()

完整的代码贴给大家

# coding=UTF-8
from collections import deque

graph   = {}
graph["A"]        = ["B", "C"]
graph["B"]        = ["A", "C"]
graph["C"]        = ["A", "B", "E"]
graph["D"]        = ["B","E","F"]
graph["E"]        = ["C", "D", "G"]
graph["G"]        = ["E"]
graph["F"]        = ["D", "H"]
graph["H"]        = ["F"]




def bfs(graph, vertex):
    searched    = set()
    queue       = deque()
    queue.append(vertex)
    searched.add(vertex)
    while queue:
        v       = queue.popleft()
        neibs   = graph[v]
        for n in neibs:
            if n not in searched:
                queue.append(n)
                searched.add(n)
        print("bfs-> " + v)




def dfs(graph, vertex):
    searched    = set()
    stack       = deque()
    stack.append(vertex)
    searched.add(vertex)

    while stack:
        v       = stack.pop()
        neibs   = graph[v]
        for n in neibs:
            if n not in searched:
                stack.append(n)
                searched.add(n)
        print("dfs-> " + v)


def compareDBFS(graph, vertex):
    bfs(graph, vertex)
    print("-----------------------------")
    dfs(graph, vertex)



compareDBFS(graph, "E")
运行结果
bfs-> E
bfs-> C
bfs-> D
bfs-> G
bfs-> A
bfs-> B
bfs-> F
bfs-> H
-----------------------------
dfs-> E
dfs-> G
dfs-> D
dfs-> F
dfs-> H
dfs-> B
dfs-> A
dfs-> C
上一篇 下一篇

猜你喜欢

热点阅读