f_
frhyme.code
•python-libs•โฑ ์•ฝ 7๋ถ„ ์†Œ์š”

NetworkX: Node Connectivity.

networkx - approximation for NODE connectivity

  • Graph๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ํ…Œ์ด๋ธ”๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋ผ๋ฉด, ๋น„๊ต์  ์–ด๋А ์ •๋„ ๋ณ‘๋ ฌ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ(์„œ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ๋…๋ฆฝ์ ์ด๊ธฐ ๋•Œ๋ฌธ), Graph๋Š” ๋ชจ๋‘ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ๊ทธ๋ ‡์ง€ ์•Š์ฃ . ๋”ฐ๋ผ์„œ, ํ•„์š”์— ๋”ฐ๋ผ์„œ, approximation์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ์™ธ๋กœ, graph2vec, node2vec ๋“ฑ์˜ ๋ฐฉ๋ฒ•๋ก  ๋˜ํ•œ approximation์˜ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ฃ (๋ฌผ๋ก , ์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ ์ด ๋ฐฉ๋ฒ•์€ approximation์ด ์•„๋‹ˆ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค๋งŒ, ์ €๋Š” ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ•ด์š”.)
  • ๋ณธ ํฌ์ŠคํŠธ์—์„œ๋Š” local node connectivity๋ฅผ ๋Œ€๋žต์ ์œผ๋กœ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด networkx์— ๋‚ด์žฌ๋œ approximation method๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

local node connectivity

  • pairwise node connectivity ๋ผ๊ณ  ๋งํ•˜๊ธฐ๋„ ํ•˜๋Š”๋ฐ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด์„œ ์„ค๋ช…ํ•˜๋Š” ๊ฒŒ ๋” ์‰ฌ์›Œ์š”.
    • ๊ฐ€๋ น node_A, node_B๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ฉ์‹œ๋‹ค(๊ธฐ๋ณธ์ ์œผ๋กœ๋Š”, ๋‘ ๋…ธ๋“œ๊ฐ€ ์ธ์ ‘ํ•˜์ง€ ์•Š๊ณ (non-adjacent), ์„œ๋กœ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ์„ ์ „์ œํ•ฉ๋‹ˆ๋‹ค).
    • ์ด ๋•Œ, ๋‘ ๋…ธ๋“œ ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ disconnected๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ตœ์†Œํ•œ n๊ฐœ์˜ ๋…ธ๋“œ๋ฅผ ์ œ๊ฑฐํ•ด์•ผ, ํ•œ๋‹ค๊ณ  ํ•ฉ์‹œ๋‹ค.
    • ์ด ๋•Œ, n์ด ๋ฐ”๋กœ ์ด ๋‘ ๋…ธ๋“œ๊ฐ„์˜ connectivity๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. minimum separating cutset์ด๋ผ๊ณ  ํ•˜๊ธฐ๋„ ํ•˜์ฃ .
  • ๋˜ํ•œ, ์ด ๊ฐ’์€ ๋ฉ”์šฐ ์ •ํ™•ํ•˜๊ฒŒ, Mengerโ€™s theorem์— ์˜ํ•ด์„œ, โ€œpath ๋“ค๊ฐ„์— ๊ณตํ†ต์ธ ๋…ธ๋“œ๊ฐ€ ์—†์€ source์™€ target๊ฐ„์˜ ๋ชจ๋“  pathโ€, ์ฆ‰ node_disjoint_path์˜ ์ˆ˜์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฑด ์กฐ๊ธˆ ์ƒ๊ฐํ•ด๋ณด๋ฉด ๋งค์šฐ ๋‹น์—ฐํ•ด์„œ, ํ—ท๊ฐˆ๋ฆด ๊ฒฝ์šฐ ํ•œ๋ฒˆ ๊ทธ๋ฆผ์„ ๊ทธ๋ ค๋ณด์‹œ๋ฉด ๋ช…ํ™•ํ•ด์งˆ ๊ฑฐ์—์š”.
  • ๊ทธ๋ฆฌ๊ณ , ๋ชจ๋“  node pair ๋“ค๊ฐ„์˜ connectivity๋“ค ์ค‘์—์„œ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์€, ๋‹น์—ฐํ•˜์ง€๋งŒ, (global) node connectivity๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ƒฅ node connectivity๋Š” โ€œํ•ด๋‹น Graph๊ฐ€ ๋ถ„๋ฆฌ๋˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๊ฐ€์žฅ ์ ์€ ์ˆ˜์˜ ๋…ธ๋“œ๋ฅผ ๋งํ•˜๋‹ˆ๊นŒ์š”โ€.

do it.

  • ๋˜ ์„œ๋ก ์ด ๊ธธ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ƒฅ ํ•ด๋ณด๋ฉด ์‰ฝ์ฃ  ๋Š˜ ๋งํ•˜์ง€๋งŒ ์‰ฌ์›Œ์š”.
import networkx as nx
from networkx.algorithms.approximation import connectivity
import time

N = 40  # node size
p = 0.6 # edge proportion of Complete graph
G = nx.fast_gnp_random_graph(N, p, seed=0)

print("=="*30)
print(f"Node size: {N}, Edge size: {len(G.edges())}")
print("--" * 30)
print("== Start")
start_time = time.time()

MIN_global_node_connectivity = len(G)
WRONG_connectivity_count = 0

# G:nx.Graph ์˜ ๋ชจ๋“  node pair๋“ค์˜ local connnectivity๋ฅผ approximationํ•œ๋‹ค.
for n1, d1 in connectivity.all_pairs_node_connectivity(G).items():
    for n2, approx_c in d1.items():
        if MIN_global_node_connectivity>=approx_c:
            MIN_global_node_connectivity = approx_c
        # `local_node_connectivity`๋Š” ํŠน์ • source, target์— ๋Œ€ํ•ด์„œ๋งŒ ๊ณ„์‚ฐํ•ด์ฃผ๋Š” ํ•จ์ˆ˜
        # ์žฅ๋‚œ ์‚ผ์•„ assert๋ฅผ ๋„ฃ๊ธฐ๋Š” ํ–ˆ์ง€๋งŒ, ํ‹€๋ฆด ๋ฆฌ๊ฐ€ ์—†๋‹ค.
        assert approx_c == connectivity.local_node_connectivity(G, n1, n2)
        # ์•ž์„œ ๋งํ•œ ๊ฒƒ๊ณผ ๊ฐ™์ด, local_node_connectivity๋Š” ๋‘ ๋…ธ๋“œ๊ฐ„์˜ disjoint_path์˜ ์ˆ˜์™€ ๋™์ผํ•ด์•ผ ํ•œ๋‹ค.
        disjoint_paths = nx.algorithms.connectivity.node_disjoint_paths(G, n1, n2)
        disjoint_path_count = 0
        for _ in disjoint_paths:
            disjoint_path_count+=1
        # `disjoint_path_count`๊ฐ€ ์ •ํ™•ํ•œ node connectivity์ด๋ฏ€๋กœ ์ถœ๋ ฅํ•จ.
        if approx_c!=disjoint_path_count:# Wrong
            print(
                f"WRONG - {n1:3d} => {n2:3d} - approx: {approx_c:3d} - disjoint_path_count: {disjoint_path_count:3d}"
            )
            WRONG_connectivity_count+=1
# graph์˜ node connectivity์™€ all_pairs_node_connectivity์˜ ์ตœ์†Œ๊ฐ’์€ ๋‹น์—ฐํžˆ ๊ฐ™์•„์•ผ ํ•จ.
assert connectivity.node_connectivity(G) == MIN_global_node_connectivity
print("--" * 30)
print(f"Accuracy: {1-WRONG_connectivity_count/(N*(N-1)):%}")
print(f"== complete with comp. time: {time.time()-start_time:6.2f} sec")
print("==" * 30)
  • ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ฆ‰, approximation์ด๊ธฐ๋Š” ํ•œ๋ฐ, ์กฐ๊ธˆ ์†Œ๋ฆ„ ๋‹์„ ์ •๋„๋กœ ์ •ํ™•ํ•ฉ๋‹ˆ๋‹ค.
============================================================
Node size: 40, Edge size: 456
------------------------------------------------------------
== Start
WRONG -   7 =>  14 - approx:  21 - disjoint_path_count:  22
WRONG -  14 =>   7 - approx:  21 - disjoint_path_count:  22
------------------------------------------------------------
Accuracy: 99.871795%
== complete with comp. time:  20.81 sec
============================================================

wrap-up

  • local connectivity๊ฐ€ ๋‹ค๋ฅธ ๋…ธ๋“œ๋“ค์— ๋น„ํ•ด์„œ ๋†’๋‹ค๋ฉด, ๊ทธ ๋‘ ๋…ธ๋“œ๋Š” ์•„๋งˆ๋„ ์ข€ ๋” ๋ฐ€์ง‘๋œ ๊ด€๊ณ„๋ผ๊ณ , ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ . ๊ทธ ๋‘ ๊ด€๊ณ„๋ฅผ ๋–จ์–ด๋œจ๋ฆฌ๋ ค๋ฉด ์ œ๊ฑฐํ•ด์•ผ ํ•˜๋Š” ๋…ธ๋“œ์˜ ์ˆ˜๊ฐ€ ๋งŽ์œผ๋‹ˆ๊นŒ์š”. ๊ทธ๋ฆฌ๊ณ , ์ด๋Š” betweenness centrality์™€๋„ ์œ ์‚ฌํ•œ ๊ฐœ๋…์œผ๋กœ, ๋А๊ปด์ง€๊ธฐ๋„ ํ•ด์š”.

๐Ÿ’กRELATED ARTICLES ยท ํ•จ๊ป˜ ์ฝ์œผ๋ฉด ์ข‹์€ ์—ฐ๊ด€ ํฌ์ŠคํŠธ

๊ธ€ ์ฃผ์†Œ๊ฐ€ ํด๋ฆฝ๋ณด๋“œ์— ๋ณต์‚ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.