zoukankan      html  css  js  c++  java
  • 2D-StruInforEntropy(Graph 二维结构信息熵)-- 记录

    import numpy as np
    import networkx as nx
    import infomap
    import community
    import matplotlib.pyplot as plt
    import matplotlib.colors as colors
    
    # 无权重图 or all weights == 1.0
    G = nx.Graph()
    edges_list = [(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (2, 3),
                  (4, 5), (4, 6), (4, 7), (4, 8), (5, 6), (5, 7), (5, 8), (6, 7), (6, 8), (7, 8), (7, 10),
                  (9, 10), (9, 12), (9, 13), (10, 11), (10, 12), (11, 12), (11, 13), (12, 13)]
    G.add_edges_from(edges_list)
    
    G = nx.truncated_cube_graph()# eq
    G = nx.truncated_tetrahedron_graph()# less
    G = nx.tutte_graph()# better
    G = nx.karate_club_graph()
    G = nx.krackhardt_kite_graph()# less
    G = nx.icosahedral_graph()# less
    G = nx.house_x_graph()# better
    G = nx.frucht_graph()# eq
    G = nx.chvatal_graph()# # eq
    G = nx.generators.barabasi_albert_graph(n=30, m=15)# less
    G = nx.random_regular_graph(d=6, n=30)# less
    G = nx.connected_watts_strogatz_graph(n=30, k=5, p=0.15)# better
    # G = nx.grid_2d_graph(6, 6)# less
    # G = nx.generators.barabasi_albert_graph(n=80, m=60)# less
    
    nx.draw(G, node_size=500, with_labels=True, node_color='red')
    plt.show()
    
    nodes = [node for node in G.nodes()]
    # G_du = G.degree()
    # G_volume = sum(G_du[index_node] for index_node in G.nodes)
    # G_pu_dic = {index_node: G_du[index_node]*1.0/(1.0*G_volume) for index_node in G.nodes}
    # G_pu = [G_pu_dic[index_node] for index_node in G.nodes]
    
    def pLog2p(p_i, eps = 1e-10):
        ind = np.where(p_i < eps)
        if len(ind) > 0:
            p_i[p_i < eps] = 1.0
            return p_i*np.log2(p_i)
        else:
            return p_i*np.log2(p_i)
    
    def Log2p(p_i, eps = 1e-10):
        ind = np.where(p_i < eps)
        if len(ind) > 0:
            p_i[p_i < eps] = 1.0
            return np.log2(p_i)
        else:
            return np.log2(p_i)
    
    def getGraphFractalDimension(G, plotFlg=False):
        from box_cover import GC
        X, Y = GC(G)
        LogXI = [np.log10(x) for x in X]
        LogYI = [np.log10(y) for y in Y]
        z1 = np.polyfit(LogXI, LogYI, 1)# 最小二乘多项式拟合
        fractal_dimension = z1[0]# The fractal dimension is the slope of the fitting line z1. 拟合线的斜率
    
        if plotFlg:
            import matplotlib.pyplot as plt
            p1 = np.poly1d(z1)  # 生成一个多项式
            yvals = p1(LogXI)
            plt.plot(LogXI, LogYI, 'o', markersize=15)
            plt.plot(LogXI, yvals, '-', markersize=15, linewidth=3)
            plt.show()
    
        return fractal_dimension
    
    def get_oneStruInforEntropy(G, weight=None):
        G_du = G.degree(weight=weight)
        G_volume = sum(G_du[index_node] for index_node in G.nodes)
        G_pu_dic = {index_node: G_du[index_node]*1.0/(1.0*G_volume) for index_node in G.nodes}
        G_pu = [G_pu_dic[index_node] for index_node in G.nodes]
        # Shonnon Entropy
        HP_G_Shonnon = sum(pLog2p(np.array(G_pu)))*(-1.0)
        return HP_G_Shonnon
    
    # StruInforEntropy
    def StruInforEntropy(G, partition):
        # nodes = G.nodes
        # n = G.number_of_nodes()
        sub_set = partition.copy()
        m = G.number_of_edges()
        degree = G.degree()
        Vij, gij, deg_ij = [], [], []
        for ind in range(len(sub_set)):
            sub_degree = 0
            dij = []
            for node in sub_set[ind]:
                sub_degree += degree[node]
                dij.append(degree[node])
            gj_c = nx.cut_size(G, sub_set[ind])
            Vij.append(sub_degree)
            gij.append(gj_c)
            deg_ij.append(np.array(dij))
        gij = np.array(gij, dtype=np.float)
        Vij = np.array(Vij, dtype=np.float)
        # print('Vi:', Vij)
        # print('gi:', gij)
        deg_ij = np.array(deg_ij)
        p_i = np.array([deg_ij[i] / Vij[i] for i in range(len(Vij))])
        pLogp = np.array([pLog2p(pi, eps=1e-10) for pi in p_i])
        sum_pLogp = np.array([np.sum(plp) for plp in pLogp])
        first = np.sum((-1.0) * Vij / (2.0 * m) * sum_pLogp)
        second = np.sum((-1.0) * gij / (2.0 * m) * Log2p(Vij / (2.0 * m)))
        HG = first + second
    
        return HG, Vij, gij, deg_ij
    
    # # test: 2D-StruInforEntropy
    # partition = [{0, 1, 2, 3}, {4, 5, 6, 7, 8}, {9, 10, 11, 12, 13}]
    # HP_G, Vj, g_j, Gj_deg = StruInforEntropy(G, partition)
    
    def delt_Xij(Xi, Xj, G):
        Xij = Xi + Xj
        sub_set = [Xi, Xj, list(set(Xij))]
        # sub_set = [[0, 1], [2, 3], [0, 1, 2, 3]]
        # n = G.number_of_nodes()
        m = G.number_of_edges()
        degree = G.degree()
        Vij, gij = [], []
        for ind in range(len(sub_set)):
            sub_degree = 0
            for node in sub_set[ind]:
                sub_degree += degree[node]
            gj_c = nx.cut_size(G, sub_set[ind])
            Vij.append(sub_degree)
            gij.append(gj_c)
        gij = np.array(gij)
        Vij = np.array(Vij)
        g_i, g_j, g_ij = gij[0], gij[1], gij[2]
        V_i, V_j, V_ij = Vij[0], Vij[1], Vij[2]
        log_Vij = Log2p(Vij, eps=1e-10)
        delt_G_Pij = 1.0 / (2.0 * m) * ((V_i - g_i) * log_Vij[0] +
                                      (V_j - g_j) * log_Vij[1] -
                                      (V_ij - g_ij) * log_Vij[2] +
                                      (g_i + g_j - g_ij) * np.log2(2.0 * m))
        return delt_G_Pij
    
    def doWhile(NodeA):
        NodeB = NodeA.copy()
        count = 0
        L = len(NodeA)
        for Xi in NodeB:
            for Xj in NodeB:
                if Xi != Xj:
                    delt_ij = delt_Xij(Xi, Xj, G)# 函数
                    if delt_ij <= 0:
                        count += 1
        if count - L*(L-1) != 0:
            return True
        return False
    
    # Input 算法主体 -- 开始
    print("Partition by min2DHG ..........")
    global NodeA
    nodes = list(G.nodes())
    nodes.sort()
    NodeA = [[node] for node in nodes]
    print("Init-Input:", NodeA)
    doWhileFlg = True
    NodeA.reverse()
    while doWhileFlg:
        Xi = NodeA.pop()
        Nj = NodeA.copy()
        delt_max = 0
        Xj_m = None
        for Xj in Nj:
            delt_ij = delt_Xij(Xi, Xj, G)# 函数
            if delt_ij > 0 and delt_ij > delt_max:
                Xj_m = Xj
                delt_max = delt_ij
        if Xj_m in Nj and Xj_m is not None:
            Nj.remove(Xj_m)
            Xij = Xi + Xj_m
            Nj.insert(0, Xij)
            # print('Xi:', Xi, '+ Xj:', Xj_m, '-->', Xij, ' delt_ij_HG:', delt_max)
        elif Xj_m is None:
            Nj.insert(0, Xi)
        NodeA = Nj
        doWhileFlg = doWhile(NodeA)
        # print(NodeA)
    print('Output:', NodeA)
    sub_set = NodeA.copy()
    # Output: NodeA 算法主体 -- 结束
    
    # m = G.number_of_edges()
    # degree = G.degree()
    # Vij, gij, deg_ij = [], [], []
    # for ind in range(len(sub_set)):
    #     sub_degree = 0
    #     dij = []
    #     for node in sub_set[ind]:
    #         sub_degree += degree[node]
    #         dij.append(degree[node])
    #     gj_c = nx.cut_size(G, sub_set[ind])
    #     Vij.append(sub_degree)
    #     gij.append(gj_c)
    #     deg_ij.append(np.array(dij))
    # gij = np.array(gij, dtype=np.float)
    # Vij = np.array(Vij, dtype=np.float)
    # print('Vi:', Vij)
    # print('gi:', gij)
    # deg_ij = np.array(deg_ij, dtype=object)
    # p_i = np.array([deg_ij[i]/Vij[i] for i in range(len(Vij))], dtype=object)
    # pLogp = np.array([pLog2p(pi, eps=1e-10) for pi in p_i], dtype=object)
    # sum_pLogp = np.array([np.sum(plp) for plp in pLogp])
    # first = np.sum((-1.0) * Vij / (2.0 * m) * sum_pLogp)
    # second = np.sum((-1.0) * gij / (2.0 * m) * Log2p(Vij / (2.0 * m)))
    # HG = first + second
    # print("Partition:", NodeA)
    # print("StruInforEntropy:", HG)
    
    # 2D-StruInforEntropy
    HG, Vj, g_j, Gj_deg = StruInforEntropy(G, partition=sub_set)
    print("Partition-Size(min2DHG):", len(sub_set))
    print("Partition(min2DHG):", sub_set)
    print("StruInforEntropy:", HG)
    
    print("Partition by community ..........")
    partition = community.best_partition(G)
    size = float(len(set(partition.values())))
    result = []
    count = 0.
    for com in set(partition.values()):
        count = count + 1.
        list_nodes = [nodes for nodes in partition.keys() if partition[nodes] == com]
        result.append(list_nodes)
    print("Partition-Size(louvain):", len(result))
    print("Partition(louvain):", result)
    HG, Vj, g_j, Gj_deg = StruInforEntropy(G, partition=result)
    print("StruInforEntropy:", HG)
    
    print("Partition by pymetis ..........")
    import pymetis
    adjacency_list = [np.array([nei for nei in G.neighbors(n=node)]) for node in G.nodes()]
    # adjacency_list = [np.array([4, 2, 1]),
    #                   np.array([0, 2, 3]),
    #                   np.array([4, 3, 1, 0]),
    #                   np.array([1, 2, 5, 6]),
    #                   np.array([0, 2, 5]),
    #                   np.array([4, 3, 6]),
    #                   np.array([5, 3])]
    nparts = len(sub_set)
    n_cuts, membership = pymetis.part_graph(nparts=nparts, adjacency=adjacency_list)
    result = []
    for npa in range(nparts):
        nodes_part = list(np.argwhere(np.array(membership) == npa).ravel())
        result.append(nodes_part)
    print("Partition-Size(pymetis):", len(result))
    print("Partition(pymetis):", result)
    HG, Vj, g_j, Gj_deg = StruInforEntropy(G, partition=result)
    print("StruInforEntropy:", HG)
    
    print(infomap.Infomap().version)
    def findCommunities(G):
        """
        Partition network with the Infomap algorithm.
        Annotates nodes with 'community' id and return number of communities found.
        """
        infomapX = infomap.Infomap("--two-level")
        # print("Building Infomap network from a NetworkX graph...")
        for e in G.edges():
            infomapX.addLink(*e)
        print("Find communities with Infomap...")
        infomapX.run()
        print("Found {} modules with codelength: {}".format(infomapX.numTopModules(), infomapX.codelength))
        communities = {}
        for node in infomapX.iterLeafNodes():
            communities[node.physicalId] = node.moduleIndex()
        nx.set_node_attributes(G, values=communities, name='community')
        return infomapX.numTopModules(), communities
    
    def drawNetwork(G):
        # position map
        pos = nx.spring_layout(G)
        # community ids
        communities = [v for k, v in nx.get_node_attributes(G, 'community').items()]
        numCommunities = max(communities) + 1
        # color map from http://colorbrewer2.org/
        cmapLight = colors.ListedColormap(['#a6cee3', '#b2df8a', '#fb9a99', '#fdbf6f', '#cab2d6'], 'indexed', numCommunities)
        cmapDark = colors.ListedColormap(['#1f78b4', '#33a02c', '#e31a1c', '#ff7f00', '#6a3d9a'], 'indexed', numCommunities)
        # Draw edges
        nx.draw_networkx_edges(G, pos)
        # Draw nodes
        nodeCollection = nx.draw_networkx_nodes(G,
            pos = pos,
            node_color = communities,
            cmap = cmapLight)
        # Set node border color to the darker shade
        darkColors = [cmapDark(v) for v in communities]
        nodeCollection.set_edgecolor(darkColors)
        # Draw node labels
        for n in G.nodes():
            plt.annotate(n,
                xy = pos[n],
                textcoords = 'offset points',
                horizontalalignment = 'center',
                verticalalignment = 'center',
                xytext = [0, 0],
                color = cmapDark(communities[n]))
        plt.axis('off')
        # plt.savefig("karate.png")
        plt.show()
    
    numModules, communities = findCommunities(G)
    drawNetwork(G)
    list_values = [val for val in communities.values()]
    list_nodes = [node for node in communities.keys()]
    result = []
    for ndpa in range(numModules):
        nodes_part_index = np.argwhere(np.array(list_values) == ndpa).ravel()
        nodes_part = list(np.array(list_nodes)[nodes_part_index])
        result.append(nodes_part)
    print("Partition-Size(Infomap):", len(result))
    print("Partition(Infomap):", result)
    HG, Vj, g_j, Gj_deg = StruInforEntropy(G, partition=result)
    print("StruInforEntropy:", HG)
    个人学习记录
  • 相关阅读:
    洛谷 P1725 琪露诺 题解
    洛谷 P1714 切蛋糕 题解
    洛谷 P1352 没有上司的舞会 题解
    洛谷 P1194 买礼物 题解
    洛谷 P2872 [USACO07DEC]道路建设Building Roads 题解
    OpenCV之头文件分析
    电路学习之二极管(一)
    二极管学习(一)
    STL之vetor 排序
    小波分析(二)
  • 原文地址:https://www.cnblogs.com/jeshy/p/14797216.html
Copyright © 2011-2022 走看看