آرین سلیمان‌زاده
  • خانه
  • وبلاگ
  • پادکست‌ها
  • ویدیوها
  • کتابخانه
  • تماس با من
العربيةArabic
DeutschGerman
EnglishEnglish
فارسیPersian
한국어Korean
中文Chinese
پنل•تماس سریع

Languages

Choose your interface locale

ar

العربية

Arabic

de

Deutsch

German

en

English

English

fa

فارسی

Persian

ko

한국어

Korean

zh

中文

Chinese

درخواست همکاری یا مشاوره

پیام خود را درباره همکاری، مشاوره، توسعه محصول یا پروژه نرم‌افزاری ارسال کنید.

LinkedInپاسخ سریع
خانه/مقاله‌ها/Articulation Point چیست؟ پیدا کردن نقاط بحرانی شبکه
AlgorithmsGraph Algorithmsمقاله

Articulation Point چیست؟ پیدا کردن نقاط بحرانی شبکه

Articulation Point یا Cut Vertex رأسی است که حذف آن Connectivity گراف را می‌شکند؛ مفهومی کلیدی برای Single Point of Failure، Network Reliability و تحلیل زیرساخت.

۳۰ مرداد ۱۴۰۵18 دقیقه مطالعه23 بازدید
#Graph#Algorithms#Articulation Points#Cut Vertex#Tarjan#DFS#Low Link#JavaScript#TypeScript

Arian Soleimanzadeh

Software Engineer & Researcher

راهنمای تصویری Articulation Point و نقاط بحرانی شبکه

Arian Soleimanzadeh

هوش مصنوعی · کد · محصول

پژوهش + مهندسی
در این صفحه
Articulation PointBridgeTree EdgeBack EdgeBridgeArticulation Point1. استفاده از شرط Bridge2. فراموش کردن Root Rule3. استفاده روی Directed Graph بدون تغییر4. فقط یک Component را DFS کردن5. اشتباه گرفتن Parent Edge با Back Edge6. فرض کردن Degree بالا یعنی Critical7. فراموش کردن Nodeهایی که فقط در Neighbor List آمده‌اند

Articulation Point یا Cut Vertex رأسی در یک گراف بدون‌جهت است که اگر آن را همراه با یال‌های متصل به آن حذف کنیم، تعداد Connected Componentهای گراف افزایش پیدا می‌کند.

به زبان ساده:

Articulation Point یک نقطه‌ی شکست مهم در شبکه است.

اگر این Node از کار بیفتد، بخش‌هایی از Graph ممکن است دیگر نتوانند با یکدیگر ارتباط داشته باشند.

این مفهوم در تحلیل پایداری شبکه، طراحی زیرساخت، ارتباطات، حمل‌ونقل، معماری سرویس‌ها و بسیاری از مسائل Graph Theory بسیار مهم است.

در این مقاله Articulation Point را از پایه بررسی می‌کنیم، تفاوت آن را با Bridge می‌فهمیم، مفهوم‌های discovery time و low-link را یاد می‌گیریم و الگوریتم Tarjan را با JavaScript و TypeScript پیاده‌سازی می‌کنیم.


یک مثال ساده

Graph زیر را در نظر بگیرید:

Code
123
A -- B -- C
     |
     D

اگر B را حذف کنیم:

Code
123
A    C

     D

سه بخش جدا داریم.

پس:

Code
1
B = Articulation Point

اما اگر A را حذف کنیم:

Code
123
B -- C
|
D

بخش باقی‌مانده هنوز Connected است.

پس A Articulation Point نیست.


تعریف دقیق

در یک گراف بدون‌جهت:

Code
1
G = (V, E)

رأس u یک Articulation Point است اگر حذف u باعث افزایش تعداد Connected Componentها شود.

یعنی:

Code
123
components(G - u)
>
components(G)

چرا Articulation Point مهم است؟

فرض کنید Graph یک Network واقعی است.

مثلاً:

Code
12
Router = Vertex
Link = Edge

اگر یک Router خاص تنها مسیر ارتباط بین دو بخش شبکه باشد، خرابی آن Router کل ارتباط را قطع می‌کند.

پس آن Router:

Code
1
Single Point of Failure

است.

Articulation Point دقیقاً چنین Nodeهایی را از نظر Graph Connectivity پیدا می‌کند.


تفاوت Articulation Point با Bridge

این تفاوت بسیار مهم است.

Articulation Point

یک Vertex بحرانی است.

اگر حذف شود، Graph disconnectedتر می‌شود.

Bridge

یک Edge بحرانی است.

اگر حذف شود، تعداد Connected Componentها افزایش پیدا می‌کند.

پس:

Code
12
Articulation Point = critical vertex
Bridge = critical edge

مثال

Graph:

Code
1
A -- B -- C

در این Graph:

Code
1
B

Articulation Point است.

و هر دو Edge:

Code
12
A -- B
B -- C

Bridge هستند.


روش ساده Brute Force

یک روش ساده برای پیدا کردن Articulation Pointها:

برای هر Vertex:

  1. آن Vertex را موقتاً حذف کن.
  2. تعداد Connected Componentها را حساب کن.
  3. Vertex را برگردان.
  4. اگر تعداد Componentها بیشتر شد، Articulation Point است.

مشکل Brute Force

اگر برای هر Vertex یک DFS کامل اجرا کنیم:

Code
1
V بار

و هر DFS:

Code
1
O(V + E)

باشد، Complexity تقریباً:

Code
1
O(V × (V + E))

می‌شود.

برای Graph بزرگ مناسب نیست.


الگوریتم بهتر: Tarjan

با یک DFS می‌توان تمام Articulation Pointها را پیدا کرد.

Complexity:

Code
1
O(V + E)

کل ایده بر دو مقدار مهم بنا شده است:

Code
12
disc[u]
low[u]

discovery time چیست؟

disc[u] زمان اولین ورود DFS به رأس u است.

مثلاً اگر DFS ترتیب زیر را داشته باشد:

Code
1
A → B → C → D

ممکن است:

Code
1234
disc[A] = 1
disc[B] = 2
disc[C] = 3
disc[D] = 4

باشد.

این عدد فقط ترتیب Discovery را نشان می‌دهد.


low-link value چیست؟

low[u] کمترین discovery time رأسی است که از Subtree مربوط به u می‌توان با:

  • Tree Edgeهای DFS
  • و حداکثر یک Back Edge

به آن رسید.

به زبان ساده‌تر:

low می‌گوید Subtree این Node تا چه Ancestor بالاتری می‌تواند بدون عبور دوباره از Parent اصلی فرار کند.


مثال ساده برای low

فرض کنید:

Code
1234567
A
|
B
|
C
|
D

و یک Back Edge داریم:

Code
1
D -- A

پس از Subtree D می‌توان دوباره به A رسید.

بنابراین:

Code
1
low[D] = disc[A]

و این مقدار به بالا propagate می‌شود.


چرا low مهم است؟

فرض کنید DFS Tree:

Code
123
u
|
v

باشد.

اگر Subtree مربوط به v هیچ راهی برای رسیدن به Ancestorهای u نداشته باشد، حذف u باعث جدا شدن Subtree v می‌شود.

شرط این حالت:

Code
1
low[v] >= disc[u]

است.


شرط Articulation Point برای Node غیرریشه

اگر u Root نباشد و یک DFS Child مثل v داشته باشد که:

Code
1
low[v] >= disc[u]

آنگاه:

Code
1
u = Articulation Point

چرا؟

چون Subtree v نمی‌تواند به هیچ Ancestor بالاتر از u وصل شود.

پس اگر u حذف شود، آن Subtree جدا می‌شود.


چرا >= و نه > ؟

برای Bridge شرط معروف:

Code
1
low[v] > disc[u]

است.

اما برای Articulation Point:

Code
1
low[v] >= disc[u]

چون اگر Subtree فقط بتواند به خود u برگردد، حذف u همچنان اتصال را از بین می‌برد.

این تفاوت بسیار مهم است:

Code
12345
Bridge:
low[v] > disc[u]

Articulation Point:
low[v] >= disc[u]

شرط Root

Root در DFS Tree قانون متفاوتی دارد.

Root زمانی Articulation Point است که:

Code
1
بیش از یک DFS child

داشته باشد.

یعنی:

Code
1
children > 1

چرا Root قانون جدا دارد؟

برای Nodeهای معمولی Parent و Ancestor داریم.

اما Root Ancestor ندارد.

اگر Root فقط یک DFS Child داشته باشد، تمام Graph reachable آن در همان Subtree است.

حذف Root لزوماً تعداد Componentها را افزایش نمی‌دهد.

اما اگر Root دو یا چند Child مستقل داشته باشد:

Code
123
       R
      / \
     A   B

DFS Subtreeهای A و B بدون Root راهی به یکدیگر ندارند.

پس حذف R آن‌ها را جدا می‌کند.


الگوریتم مرحله‌به‌مرحله

برای هر Component از Graph:

  1. DFS را شروع کن.
  2. disc[u] را ثبت کن.
  3. مقدار اولیه:
    Code
    1
    low[u] = disc[u]
  4. برای هر Neighbor:
    • اگر unvisited است، DFS اجرا کن.
    • بعد:
      Code
      1
      low[u] = min(low[u], low[v])
    • شرط Articulation را بررسی کن.
  5. اگر Neighbor قبلاً visited شده و Parent نیست:
    Code
    1
    low[u] = min(low[u], disc[v])

پیاده‌سازی کامل JavaScript

JavaScript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
function findArticulationPoints(graph) {
  const nodes = new Set();

  for (const [u, neighbors] of Object.entries(graph)) {
    nodes.add(u);

    for (const v of neighbors) {
      nodes.add(v);
    }
  }

  const visited = new Set();
  const disc = new Map();
  const low = new Map();
  const parent = new Map();
  const articulation = new Set();

  let time = 0;

  function dfs(u) {
    visited.add(u);

    disc.set(u, ++time);
    low.set(u, disc.get(u));

    let children = 0;

    for (const v of graph[u] ?? []) {
      if (!visited.has(v)) {
        children++;
        parent.set(v, u);

        dfs(v);

        low.set(
          u,
          Math.min(
            low.get(u),
            low.get(v)
          )
        );

        const isRoot =
          !parent.has(u);

        if (
          isRoot &&
          children > 1
        ) {
          articulation.add(u);
        }

        if (
          !isRoot &&
          low.get(v) >= disc.get(u)
        ) {
          articulation.add(u);
        }
      } else if (
        v !== parent.get(u)
      ) {
        low.set(
          u,
          Math.min(
            low.get(u),
            disc.get(v)
          )
        );
      }
    }
  }

  for (const node of nodes) {
    if (!visited.has(node)) {
      dfs(node);
    }
  }

  return [...articulation];
}

مثال اجرا

JavaScript
123456789101112
const graph = {
  A: ["B"],
  B: ["A", "C", "D"],
  C: ["B"],
  D: ["B", "E", "F"],
  E: ["D", "F"],
  F: ["D", "E"]
};

console.log(
  findArticulationPoints(graph)
);

در این Graph ممکن است:

Code
12
B
D

Articulation Point باشند.


بررسی شهودی مثال

Graph:

Code
12345
A -- B -- C
     |
     D
    / \
   E---F

اگر B حذف شود:

Code
123
A
C
D-E-F

قسمت‌ها جدا می‌شوند.

پس B بحرانی است.

اگر D حذف شود، مثلث E-F از B جدا می‌شود.

پس D نیز بحرانی است.


محاسبه disc و low روی DFS

فرض کنید DFS:

Code
12345
A → B → C
    |
    D → E → F
        ↑   |
        └───┘

ممکن است discovery timeها:

Code
123456
A = 1
B = 2
C = 3
D = 4
E = 5
F = 6

باشند.

به دلیل Back Edge بین F و E یا سایر Connectionها، lowهای Subtree می‌توانند کاهش پیدا کنند.

تحلیل low نشان می‌دهد کدام Subtree راه جایگزین به بالا دارد.


Tree Edge و Back Edge

در DFS دو نوع Edge در این بحث مهم‌اند.

Tree Edge

Edgeای که با آن برای اولین بار وارد یک Node جدید می‌شویم.

مثلاً:

Code
1
u → v

و v unvisited بوده.

Back Edge

Edgeای که از Node یا Subtree به Ancestor قبلی برمی‌گردد.

Back Edge باعث کاهش:

Code
1
low[u]

می‌شود.

وجود Back Edge یعنی مسیر جایگزین برای اتصال وجود دارد.


چرا low-link مفهوم «راه فرار» است؟

اگر Subtree یک Node بتواند با Back Edge به Ancestor بالاتر برگردد، حذف Parent اصلی لزوماً آن Subtree را جدا نمی‌کند.

مثلاً:

Code
12345
A
| \
B  |
|  |
C--+

اگر B حذف شود، C هنوز شاید از طریق Back Edge به A برسد.

پس B لزوماً Articulation نیست.


Articulation Point در Graph دارای Cycle

وجود Cycle معمولاً Redundancy ایجاد می‌کند.

مثلاً Triangle:

Code
1234
A
|\
| \
B--C

هیچ رأس Articulation نیست.

اگر یکی حذف شود، دو رأس دیگر هنوز مستقیم Connected هستند.


Graph زنجیره‌ای

Code
1
A -- B -- C -- D -- E

در این Graph:

Code
123
B
C
D

Articulation Point هستند.

چون حذف هرکدام Chain را به دو بخش تقسیم می‌کند.


Star Graph

Code
12345
    B
    |
C -- A -- D
    |
    E

رأس:

Code
1
A

Articulation Point بسیار واضح است.

حذف A باعث می‌شود B، C، D و E کاملاً جدا شوند.


Complete Graph

در Complete Graph با حداقل سه رأس:

Code
1
K_n

هیچ Articulation Pointی وجود ندارد.

چون بین رأس‌ها مسیرهای جایگزین زیادی وجود دارد.


Graph Disconnected

الگوریتم باید تمام Componentها را بررسی کند.

یک DFS از یک Start کافی نیست.

برای همین در کد:

JavaScript
12345
for (const node of nodes) {
  if (!visited.has(node)) {
    dfs(node);
  }
}

داریم.


تفاوت Articulation Point با Degree بالا

Degree بالا الزاماً به معنی بحرانی بودن نیست.

مثلاً در Complete Graph هر Node Degree بالایی دارد، ولی هیچ Articulation Pointی نیست.

همچنین Node با Degree کم هم ممکن است بحرانی باشد.

پس:

Code
1
degree ≠ articulation status

Single Point of Failure

در طراحی سیستم‌ها Articulation Point یک مدل ساده برای پیدا کردن:

Code
1
Single Point of Failure

است.

مثلاً اگر Service یا Router خاصی تنها مسیر اتصال بین دو بخش باشد، Failure آن Connectivity را از بین می‌برد.

اما باید توجه کرد که Graph Model دقیق باشد.

مثلاً اگر Failover، Load Balancer یا مسیر پشتیبان وجود دارد باید در Graph هم Edge/Node مناسب مدل شود.


کاربرد در Computer Networks

مدل:

Code
12
Router / Switch = Vertex
Link = Edge

Articulation Point می‌تواند Router یا Switchی باشد که خرابی آن Network را Partition می‌کند.

کاربرد:

  • redundancy analysis
  • fault tolerance
  • network redesign
  • disaster planning

کاربرد در Data Center

فرض کنید چند Cluster از Serverها فقط از طریق یک Gateway خاص به هم متصل‌اند.

اگر آن Gateway Articulation Point باشد، Failure آن بخش‌هایی از Data Center را Isolate می‌کند.

این اطلاعات می‌تواند برای:

  • redundancy
  • secondary gateway
  • topology redesign

استفاده شود.


کاربرد در حمل‌ونقل

مدل:

Code
12
Station / Intersection = Vertex
Road / Rail Connection = Edge

اگر Station خاصی حذف شود و شبکه به چند بخش جدا تقسیم شود، آن Station از نظر Connectivity بحرانی است.


کاربرد در شبکه‌های برق

مدل ساده:

Code
12
Substation = Vertex
Transmission connection = Edge

Articulation Point می‌تواند یک Substation حساس را نشان دهد.

البته Power Grid واقعی Constraintهای فیزیکی بسیار پیچیده‌تری دارد و Graph Connectivity فقط یک Approximation ساختاری است.


کاربرد در Social Network

در یک Graph ارتباطی، ممکن است یک User یا Organization تنها Bridge انسانی بین دو گروه باشد.

اگر آن Node حذف شود، Network به چند Component تبدیل شود.

این نوع Node می‌تواند نقش:

Code
123
broker
connector
gatekeeper

داشته باشد.

اما Articulation Point با مفاهیمی مثل Betweenness Centrality یکی نیست.


تفاوت با Betweenness Centrality

Articulation Point یک ویژگی Binary است:

Code
1
critical / not critical

اما Betweenness Centrality می‌سنجد یک Node چه مقدار روی Shortest Pathهای بین سایر Nodeها قرار دارد.

ممکن است Node:

  • Articulation نباشد
  • ولی Betweenness بسیار بالایی داشته باشد.

و بالعکس.


کاربرد در Microservice Architecture

اگر Service Dependency را به شکل Undirected Connectivity مدل کنیم، Articulation Point می‌تواند سرویس مرکزی با ریسک Failure را نشان دهد.

اما Dependency واقعی معمولاً Directed است.

پس استفاده مستقیم از Articulation Point نیاز به مدل‌سازی دقیق دارد.

برای Directed Graph مفاهیم متفاوتی ممکن است مناسب‌تر باشند.


Articulation Point معمولاً برای Undirected Graph است

الگوریتم کلاسیک Tarjan که اینجا بررسی می‌کنیم برای:

Code
1
Undirected Graph

است.

برای Directed Graph، مفهوم Cut Vertex و Connectivity شرایط متفاوت و پیچیده‌تری دارد.

پس نباید همین شرط:

Code
1
low[child] >= disc[u]

را بدون تغییر روی Directed Graph استفاده کنیم.


Biconnected Graph چیست؟

یک Graph بدون‌جهت Biconnected یا 2-vertex-connected است اگر:

  • Connected باشد.
  • هیچ Articulation Pointی نداشته باشد.

یعنی حذف هر یک Vertex، Graph باقی‌مانده را disconnected نمی‌کند.

این مفهوم معیار مهمی برای Redundancy است.


Biconnected Components

Articulation Pointها Graph را به بخش‌هایی تقسیم می‌کنند که داخل هرکدام Connectivity مقاوم‌تری وجود دارد.

این بخش‌ها:

Code
1
Biconnected Components

نامیده می‌شوند.

Articulation Point می‌تواند عضو چند Biconnected Component باشد.


Block-Cut Tree چیست؟

می‌توان ساختار Graph را به یک Tree تبدیل کرد که در آن:

  • یک نوع Node = Articulation Point
  • نوع دیگر Node = Biconnected Component

باشد.

این ساختار:

Code
1
Block-Cut Tree

نام دارد.

برای Queryهای ساختاری و تحلیل Connectivity بسیار مفید است.


تفاوت Bridge و Articulation Point از نظر low

برای DFS Edge:

Code
1
u → v

Bridge

اگر:

Code
1
low[v] > disc[u]

Edge (u,v) Bridge است.

Articulation Point

اگر u Root نباشد و:

Code
1
low[v] >= disc[u]

آنگاه u Articulation Point است.

این دو فرمول باید از هم تفکیک شوند.


آیا هر Endpoint یک Bridge، Articulation Point است؟

خیر.

مثلاً:

Code
1
A -- B

Edge یک Bridge است.

اما اگر فقط دو Node داشته باشیم، حذف A باعث می‌شود فقط B باقی بماند و بسته به تعریف component count، A الزاماً Articulation Point به مفهوم کلاسیک نیست.

پس Bridge و Articulation Point رابطه یک‌به‌یک ندارند.


Edge Case: یک Node

Graph:

Code
1
A

هیچ Articulation Pointی ندارد.


Edge Case: دو Node

Code
1
A -- B

هیچ‌کدام Articulation Point نیستند.


Edge Case: Root با یک Child

Root اگر فقط یک DFS Child داشته باشد:

Code
1
children = 1

Articulation Point محسوب نمی‌شود.

این یکی از رایج‌ترین اشتباهات پیاده‌سازی است.


Edge Case: Root با دو Child

Code
1
children > 1

Root Articulation Point است.


Edge Case: Self-loop

Self-loop معمولاً Connectivity بین Componentهای مختلف ایجاد نمی‌کند.

نباید باعث شود Node اشتباهاً Articulation Point تشخیص داده شود.


Edge Case: Parallel Edge

در MultiGraph اگر بین Parent و Child چند Edge موازی داشته باشیم، Parent-edge tracking فقط با Vertex ممکن است کافی نباشد.

بهتر است Edge ID مستقل Track شود.

این موضوع مشابه الگوریتم Bridge است.


نسخه TypeScript

TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
type Graph = Record<string, string[]>;

function findArticulationPoints(
  graph: Graph
): string[] {
  const nodes = new Set<string>();

  for (const [u, neighbors] of Object.entries(graph)) {
    nodes.add(u);

    for (const v of neighbors) {
      nodes.add(v);
    }
  }

  const visited = new Set<string>();
  const disc = new Map<string, number>();
  const low = new Map<string, number>();
  const parent = new Map<string, string>();
  const result = new Set<string>();

  let time = 0;

  function dfs(u: string): void {
    visited.add(u);

    disc.set(u, ++time);
    low.set(u, disc.get(u)!);

    let children = 0;

    for (const v of graph[u] ?? []) {
      if (!visited.has(v)) {
        children++;
        parent.set(v, u);

        dfs(v);

        low.set(
          u,
          Math.min(
            low.get(u)!,
            low.get(v)!
          )
        );

        const isRoot =
          !parent.has(u);

        if (
          isRoot &&
          children > 1
        ) {
          result.add(u);
        }

        if (
          !isRoot &&
          low.get(v)! >= disc.get(u)!
        ) {
          result.add(u);
        }
      } else if (
        v !== parent.get(u)
      ) {
        low.set(
          u,
          Math.min(
            low.get(u)!,
            disc.get(v)!
          )
        );
      }
    }
  }

  for (const node of nodes) {
    if (!visited.has(node)) {
      dfs(node);
    }
  }

  return [...result];
}

پیچیدگی زمانی

Tarjan DFS هر Vertex را یک بار Visit می‌کند.

هر Edge نیز تعداد محدودی بررسی می‌شود.

پس:

Code
1
Time = O(V + E)

پیچیدگی فضایی

ساختارهای:

  • visited
  • disc
  • low
  • parent
  • recursion stack

تقریباً:

Code
1
O(V)

فضای کمکی می‌خواهند.


چرا Brute Force معمولاً انتخاب خوبی نیست؟

Brute Force از نظر مفهومی ساده است و برای تست کوچک مفید است، اما برای Graph بزرگ:

Code
1
O(V × (V + E))

بسیار گران‌تر از Tarjan است.

Tarjan تمام اطلاعات مورد نیاز را در یک DFS جمع می‌کند.


Recursive DFS و Stack Overflow

اگر Graph بسیار عمیق باشد:

Code
1
1 -- 2 -- 3 -- ... -- 100000

Recursive DFS در JavaScript ممکن است Stack Overflow بدهد.

در Production می‌توان:

  • DFS Iterative پیچیده‌تر
  • Stack دستی
  • یا Environment مناسب

را در نظر گرفت.


خطاهای رایج

1. استفاده از شرط Bridge

اشتباه:

Code
1
low[v] > disc[u]

برای Articulation Point.

درست:

Code
1
low[v] >= disc[u]

برای Non-root.

2. فراموش کردن Root Rule

Root فقط زمانی بحرانی است که:

Code
1
children > 1

3. استفاده روی Directed Graph بدون تغییر

الگوریتم کلاسیک این مقاله برای Undirected Graph است.

4. فقط یک Component را DFS کردن

Graph ممکن است disconnected باشد.

5. اشتباه گرفتن Parent Edge با Back Edge

Edge برگشت مستقیم به Parent نباید low را مثل Back Edge عمومی Update کند.

6. فرض کردن Degree بالا یعنی Critical

Degree به‌تنهایی کافی نیست.

7. فراموش کردن Nodeهایی که فقط در Neighbor List آمده‌اند

باید مجموعه کامل Vertexها را بسازیم.


چه زمانی از Articulation Points استفاده کنیم؟

وقتی:

  • Single Point of Failure می‌خواهیم.
  • Network Reliability تحلیل می‌کنیم.
  • Router یا Gateway بحرانی می‌خواهیم.
  • Transportation Network تحلیل می‌کنیم.
  • Infrastructure Connectivity مهم است.
  • Graph Robustness بررسی می‌کنیم.
  • Biconnected Components می‌خواهیم.
  • Critical Vertex Analysis داریم.

چه زمانی مناسب نیست؟

اگر Edge بحرانی می‌خواهیم:

Code
1
Bridges

اگر Shortest Path می‌خواهیم:

Code
1
BFS / Dijkstra

اگر Directed Graph و Mutual Reachability مهم است:

Code
1
SCC

یا الگوریتم‌های مخصوص Directed Connectivity مناسب‌ترند.

اگر می‌خواهیم اهمیت آماری Node در مسیرها را بسنجیم:

Code
1
Centrality Metrics

ممکن است مفیدتر باشند.


جدول مقایسه

مفهومچه چیزی بحرانی است؟شرط اصلی
Articulation PointVertexحذف Vertex Componentها را زیاد کند
BridgeEdgeحذف Edge Componentها را زیاد کند
SCCگروه Vertex در Directed GraphMutual Reachability
Connected Componentگروه VertexReachability در Undirected Graph
Betweenness Centralityاهمیت Nodeحضور روی Shortest Paths

جمع‌بندی

Articulation Point رأسی است که حذف آن Connectivity Graph را ضعیف می‌کند و تعداد Connected Componentها را افزایش می‌دهد.

روش بهینه کلاسیک با DFS و دو مقدار انجام می‌شود:

Code
12
disc[u]
low[u]

برای Node غیرریشه:

Code
12
low[child] >= disc[u]
→ u is articulation

و برای Root:

Code
12
DFS children > 1
→ root is articulation

پیچیدگی:

Code
1
O(V + E)

است.

مهم‌ترین تفاوت با Bridge:

Code
12345
Articulation Point
→ critical vertex

Bridge
→ critical edge

Pattern تشخیص مسئله نیز روشن است:

Code
1234
اگر یک Node از شبکه حذف شود،
آیا بخشی از Graph از بخش دیگر جدا می‌شود؟

→ Articulation Point

در سیستم‌های واقعی، این مفهوم می‌تواند اولین قدم برای پیدا کردن Single Point of Failure و طراحی Redundancy بهتر باشد.

در این صفحه
Articulation PointBridgeTree EdgeBack EdgeBridgeArticulation Point1. استفاده از شرط Bridge2. فراموش کردن Root Rule3. استفاده روی Directed Graph بدون تغییر4. فقط یک Component را DFS کردن5. اشتباه گرفتن Parent Edge با Back Edge6. فرض کردن Degree بالا یعنی Critical7. فراموش کردن Nodeهایی که فقط در Neighbor List آمده‌اند

جزئیات مقاله

اطلاعات انتشار، زمان مطالعه و تعداد بازدید این محتوا.

انتشار

۳۰ مرداد ۱۴۰۵

آخرین ویرایش

۷ آبان ۱۴۰۵

زمان مطالعه

18 دقیقه مطالعه

بازدید

23

نویسنده

Arian Soleimanzadeh

مقاله قبلی

Topological Sort چیست؟ مرتب‌سازی وابستگی‌ها از صفر تا صد

مقاله بعدی

Bridge در گراف چیست؟ پیدا کردن یال‌های بحرانی شبکه

آرین سلیمان‌زاده

پورتفولیوی شخصی با تمرکز بر Agentic CRM، سامانه‌های هوشمند کسب‌وکار، مهندسی مدرن وب، طراحی سیستم‌های رابط کاربری و توسعه محصولات نرم‌افزاری کاربردی.

لینک‌های سریع

  • درباره من
  • وبلاگ
  • کتابخانه
  • تماس

ارتباط

  • soleimanzadeh.a.work@gmail.com
  • soleimanzadeh.uni@gmail.com

در دسترس: روزهای کاری

معمولاً پاسخ در ۲۴ ساعت

خبرنامه

به‌روزرسانی‌های مربوط به نوشته‌ها، پروژه‌ها و انتشارهای جدید را دریافت کنید.

© 2026 ariansoleimanzadeh.dev — تمامی حقوق محفوظ است.

لینکدین