Havel-Hakimi 算法與圖的可視化

判斷一個非負序列是否爲某簡單圖的度序列有兩種方法

import numpy as np
import networkx as nx
import matplotlib.pyplot as plt


def hh_algorithm(graph_list):
    """
    Havel-Hakimi algorithm
    :param graph_list: 非負序列
    :return: 是否可圖True or False
    """
    while True:
        # 排序從大到小
        graph_list.sort()
        graph_list = graph_list[::-1]

        # 求和
        sum = 0
        for j in range(len(graph_list)):
            sum += graph_list[j]

        # 度和爲奇數
        if sum % 2 != 0:
            print("不可圖序列")
            return False
        # 度序列全爲零
        elif np.linalg.norm(graph_list) == 0:
            print("可圖序列")
            return True

        d1 = graph_list[0]
        pi_list = np.zeros(len(graph_list) - 1)

        if len(graph_list) <= d1 + 1:
            for j in range(len(pi_list)):
                if graph_list[j + 1] - 1 >= 0:
                    pi_list[j] = graph_list[j + 1] - 1
        else:
            for j in range(len(pi_list)):
                if j <= d1 - 1:
                    if graph_list[j + 1] - 1 >= 0:
                        pi_list[j] = graph_list[j + 1] - 1
                else:
                    pi_list[j] = graph_list[j + 1]

        graph_list = pi_list


def draw_graph(graph_list):
    """
    由可圖度序列生成點集與邊集並畫圖
    :param graph_list: 可圖度序列
    :return: None
    """
    node_list = np.arange(1, len(graph_list) + 1)
    edge_list = []
    mix_matrix = np.array([node_list, graph_list])
    # 按最後一行(度序列)從大到小排序
    mix_matrix = mix_matrix.T[np.lexsort(-mix_matrix)].T

    while True:

        # 最後一行全爲0
        if np.linalg.norm(mix_matrix[1]) == 0:
            break
        # 從1號點開始往後連d(1)次線
        for j in range(1, int(mix_matrix[1, 0] + 1)):
            # 當j號點的度不爲0才連線
            if mix_matrix[1, 0] != 0:
                mix_matrix[1, 0] -= 1  # 1號點的度-1
                mix_matrix[1, j] -= 1  # j號點的度-1
                edge_list.append((mix_matrix[0, 0], mix_matrix[0, j]))  # 將邊(1,j)添加到邊集合
        # 刪去第一列
        mix_matrix = np.delete(mix_matrix, 0, axis=1)
        # 按最後一行從大到小排序
        mix_matrix = mix_matrix.T[np.lexsort(-mix_matrix)].T

    print("頂點集合爲:", node_list)
    print("邊集合爲:", edge_list)

    draw(node_list, edge_list)


def draw(node_list, edge_list):
    """
    由頂點集和邊集畫圖
    :param node_list: 頂點集
    :param edge_list: 邊集
    :return: None
    """
    g = nx.Graph()
    g.add_nodes_from(node_list)
    g.add_edges_from(edge_list)
    nx.draw(g)
    plt.show()


if __name__ == '__main__':

    input_list = input("請輸入非負序列(以空格分隔):")
    input_list = input_list.split(" ")

    GList = np.zeros(len(input_list), dtype=int)

    for i in range(len(input_list)):
        GList[i] = int(input_list[i])

    if hh_algorithm(GList):

        draw_graph(GList)

 

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