Python廣度遍歷有向圖生成樹及可視化(treelib)

首先需求是提供一個圖字典,然後用算法遍歷構造樹
treelib構造樹要求節點id的唯一性,因此我先試了一下
treelib官方文檔 https://treelib.readthedocs.io/en/latest/
圖字典:

pog_dic = {
        "AddNewPetPage": {
            "add_new_pet": "DetailPage"
        },
        "AddNewVisitPage": {
            "add_visit": "DetailPage"
        },
        "DetailPage": {
            "goto_add_pet": "AddNewPetPage",
            "goto_edit": "EditOwnerPage",
            "goto_edit_pet": "PetPage",
            "goto_pet": "PetPage",
            "goto_visit": "AddNewVisitPage"
        },
        "EditOwnerPage": {
            "edit_info": "DetailPage"
        },
        "FindPage": {
            "goto_detail_page": "DetailPage"
        },
        "HomePage": {
            "goto_Veter": "VeterPage",
            "goto_register": "RegisterPage",
            "goto_search": "FindPage"
        },
        "PetPage": {
            "edit_pet": "DetailPage"
        },
        "RegisterPage": {
            "regist_owner": "FindPage"
        },
        "VeterPage": {}
    }
# -*- encoding: utf-8 -*-
"""
@File    : generate_tree.py
@Time    : 2020/3/2 9:57 AM
@Author  : zhengjiani
@Email   : [email protected]
@Software: PyCharm
"""
from treelib import Node,Tree
from random import choice,random
from collections import deque, Counter
import numpy as np


def bfs_search(root):
    po_queue = deque()
    po_queue.append(root)
    childrens = list(pog_dic[root].values()) # 初始化孩子節點
    for index,item in enumerate(childrens):
        po_queue.append(item)
        tree.create_node(item, index, parent=root.upper())
    print("總節點集合", po_queue)
    print('根節點的孩子節點',childrens)
    for index_1,child in enumerate(childrens):
        childrens_1 = list(pog_dic[child].values())
        print(child,childrens_1)
        for index,item in enumerate(childrens_1):
            po_queue.append(item)
            ans = np.where(np.array(po_queue) == child)
            print(ans[0])
            # 含有重複元素
            if len(ans[0]) == 1:
                # 無重複元素
                tree.create_node(item,len(po_queue)+index+1,parent=index_1)





if __name__ == "__main__":
    tree = Tree()
    # 圖字典
    pog_dic = {...} # 表示縮進
    # 隨機選擇根節點
    nodes = set(pog_dic.keys())
    root = choice(list(nodes))
    print("根節點",root)
    tree.create_node(root, root.upper())
    # print(root)
    bfs_search(root)
    tree.show()

控制檯輸出如下:

根節點 PetPage
總節點集合 deque(['PetPage', 'DetailPage'])
根節點的孩子節點 ['DetailPage']
DetailPage ['AddNewPetPage', 'EditOwnerPage', 'PetPage', 'PetPage', 'AddNewVisitPage']
PetPage
└── DetailPage
    ├── AddNewPetPage
    ├── AddNewVisitPage
    ├── EditOwnerPage
    ├── PetPage
    └── PetPage
---------------------------------------------------------------------------------------

總節點集合 deque(['DetailPage', 'AddNewPetPage', 'EditOwnerPage', 'PetPage', 'PetPage', 'AddNewVisitPage'])
根節點的孩子節點 ['AddNewPetPage', 'EditOwnerPage', 'PetPage', 'PetPage', 'AddNewVisitPage']
DetailPage
├── AddNewPetPage
│   └── DetailPage
├── AddNewVisitPage
│   └── DetailPage
├── EditOwnerPage
│   └── DetailPage
├── PetPage
└── PetPage

對比原圖來說是正確的,現在需要把每次遍歷孩子的過程放到循環中,參考一般的廣度優先遍歷算法的寫法

def bfs_create_tree(root):
    po_queue = deque()
    po_queue.append(root)
    visited = []
    tree_dic = {}
    i = 0
    while len(po_queue) > 0:
        node = po_queue.popleft()
        print("父節點",node)
        if node not in visited:
            visited.append(node)
            tree_dic[node] = list(pog_dic[node].values())
            for index,child in enumerate(list(pog_dic[node].values())):
            	i= i + 1
                tree.create_node(child, i, parent= i-(index+1))
                po_queue.append(child)
    return tree_dic
if __name__ == "__main__":
    tree = Tree()
    pog_dic = {...)
    # 隨機選擇根節點
    nodes = set(pog_dic.keys())
    root = choice(list(nodes))
    tree.create_node(root, 0)
    tree_dic = bfs_create_tree(root)
    tree.show()

控制檯輸出

EditOwnerPage
└── DetailPage
    ├── AddNewPetPage
    ├── AddNewVisitPage
    │   └── DetailPage
    │       └── DetailPage
    │           └── DetailPage
    ├── EditOwnerPage
    ├── PetPage
    └── PetPage
---------------------------------------------------------------------------------------------------------
DetailPage
├── AddNewPetPage
├── AddNewVisitPage
│   └── DetailPage
│       └── DetailPage
│           └── DetailPage
│               └── DetailPage
├── EditOwnerPage
├── PetPage
└── PetPage

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