簡體   English   中英

如何在 Python 中高效地創建隨機動態圖?

[英]How can I efficiently create a random dynamic graph in Python?

TL;DR:生成 static 網絡列表比將這些 static 網絡合並為單個動態網絡快十倍。 為什么會這樣?

按照這個答案,我嘗試使用 NetworkX 和 DyNetx 生成一個隨機動態圖。

處理中型網絡(大約 1000 個節點和 1000 個時間戳)時會出現問題 - memory 崩潰。 同樣在較小的規模(大約 100 個節點和 300 個時間戳)上,該過程非常緩慢。 我相信我已經確定了障礙,但我不知道如何處理它。

以下是生成隨機時間網絡的簡單代碼示例:

import dynetx as dnx
import networkx as nx
import itertools
from random import random

def dynamic_random_graph(n, steps, up_rate, seed=42):
    # Create list of static graphs
    list_of_snapshots = list()
    for t in range(0, steps):
        G_t = nx.Graph()
        edges = itertools.combinations(range(n), 2)
        G_t.add_nodes_from(range(n))

        for e in edges:
           if random() < up_rate:
            G_t.add_edge(*e)

        list_of_snapshots.append(G_t)

    # Merge the static graphs into dynamic one
    dynamic_graph = dnx.DynGraph()
    for t, graph in enumerate(list_of_snapshots):
        dynamic_graph.add_interactions_from(graph.edges(data=False), t=t)
    
    return dynamic_graph

如果我們運行以下命令:

%timeit dynamic_random_graph(300, 100, 0.5) # Memory was crahsed on larger networks.
>> 1 loop, best of 5: 15.1 s per loop

相反,如果我們在沒有網絡合並的情況下運行代碼,我們將獲得明顯更好的結果:

%timeit dynamic_random_graph_without_merge(300, 100, 0.5) # Ignore the merge part in the function
>> 1 loop, best of 5: 15.1 s per loop

如果我們在沒有合並部分的情況下運行 function,我們可以在沒有 memory 崩潰的情況下處理具有 1000 個節點的網絡。

因此,我想查看DyNetx 源代碼並嘗試找出add_interactions_from方法有什么問題。

function 又短又簡單,但我很好奇為什么要花這么多時間和 memory,以及如何改進它。 你覺得呢?你有沒有什么想法?


這是源代碼

def add_interactions_from(self, ebunch, t=None, e=None):
        """Add all the interaction in ebunch at time t.
        Parameters
        ----------
        ebunch : container of interaction
            Each interaction given in the container will be added to the
            graph. The interaction must be given as as 2-tuples (u,v) or
            3-tuples (u,v,d) where d is a dictionary containing interaction
            data.
        t : appearance snapshot id, mandatory
        e : vanishing snapshot id, optional
        See Also
        --------
        add_edge : add a single interaction
        Examples
        --------
        >>> import dynetx as dn
        >>> G = dn.DynGraph()
        >>> G.add_edges_from([(0,1),(1,2)], t=0)
        """
        # set up attribute dict
        if t is None:
            raise nx.NetworkXError(
                "The t argument must be a specified.")
        # process ebunch
        for ed in ebunch:
            self.add_interaction(ed[0], ed[1], t, e)

我想最后的循環是所有問題的根源。 鏈接add_interaction實現。

只是一些考慮:

  • 在沒有合並階段的情況下創建快照列表的成本低於在 DynGraph 中合並它們的成本是完全正常的:這主要是因為必須將復制邊的時間信息壓縮為邊的屬性;

  • 您生成的隨機圖很密集(存在 50% 的邊,這在大多數實際情況下是不現實的),這需要不斷更新邊的屬性。 通過減少邊緣的數量,您將能夠擴展到更大的網絡。 舉個例子,考慮一下對於 ER model,您正在模擬它足以保證 ap=1/N(其中 N 是圖中的節點數)以保證超臨界狀態(即單個連接組件);

  • dynetx 是為擴展 networkx 而構建的,它不是特別可擴展(在 memory 消耗和執行時間方面):在處理密集的、高度邊緣屬性的圖形時,這種限制比以往任何時候都更加明顯;

  • 您構建動態圖的方式可能是最耗時的一種。 您正在添加每對節點之間的交互,而沒有利用其有效持續時間的知識。 如果交互 (u,v) 從 t 到 t+k 發生 k 次,您可以只插入一次這樣的邊,指定它的消失時間,從而減少圖形操作操作。

事實上,DyNetx 並不是為處理特別大的圖而設計的,但是,我們利用它來分析建立在在線社交網絡數據之上的交互網絡,該數據比報告的示例大幾個數量級(就節點而言)。

正如我之前所說:真實網絡比您模擬的網絡更稀疏。 此外,(社會)互動通常發生在“爆發”中。 這兩個數據特征通常會減輕庫的限制。

無論如何,我們歡迎對圖書館的每一份貢獻:如果有人想研究它的可擴展性,他將得到我們的全力支持!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM