檢查圖中每個頂點三元組是否包含兩個連線到第三個頂點的頂點


檢查圖中每個頂點三元組,以檢視其中兩個頂點是否直接連線到第三個頂點。此屬性很重要,因為它表明頂點之間緊密互連,從而形成一個連線豐富的網路。需要實體之間有效且直接連線的應用,例如社交網路、交通網路和通訊網路,都依賴於這種連線性。透過針對每個頂點三元組確認此條件,可以評估圖的整體結構的連通性和其對所代表系統的潛在影響。這有助於分析和最佳化網路的效能和功能。

使用的方法

  • 蠻力法

  • 深度優先搜尋 (DFS) 方法

蠻力法

在蠻力法中,會徹底檢查圖中每個頂點三元組,以檢視其中兩個頂點是否連線到第三個頂點。此方法迭代遍歷所有可能的三個頂點組合,檢查每個三元組以檢視是否存在必要的連線。此方法的時間複雜度為 O(V3),其中 V 是頂點數,但對於大型圖,它可能會變得效率低下。儘管它很簡單,但對於非常大的圖可能並不實用。因此,對於大型圖的更快、更有效的檢查,更最佳化的演算法(如 DFS、BFS 或使用鄰接矩陣/邊列表表示)是首選。

演算法

  • 從圖中選擇一個頂點,我們稱之為“v”作為起點。

  • 對圖的每個“u”和“w”(與“v”不同)頂點對執行以下操作

    • 確認“u”和“w”之間是否存在邊。

    • 如果“u”和“w”之間存在邊,則檢視“v”是否也與“u”和“w”都存在邊。

    • 如果“v”分別與“u”和“w”都有邊,則繼續處理下一個頂點對。

    • 如果“v”與“u”或“w”之間不存在邊,則返回“False”,因為三元組的條件不滿足。

  • 如果圖中所有三元組(“u”、“v”和“w”的三元組合)都滿足條件,則返回“True”。

  • 如果任何三元組都不滿足要求,則返回“False”。

示例

#include <iostream>
#include <vector>
using namespace std;

bool checkTripletCondition(const vector<vector<int>>& graph) {
   int n = graph.size();
   for (int v = 0; v < n; v++) {
      for (int u : graph[v]) {
         for (int w : graph[v]) {
            if (u != v && w != v) {
               bool hasEdgeUV = false;
               bool hasEdgeVU = false;
               bool hasEdgeVW = false;
               bool hasEdgeWV = false;

               for (int x : graph[u]) {
                  if (x == v) hasEdgeUV = true;
               }

               for (int y : graph[v]) {
                  if (y == u) hasEdgeVU = true;
                  if (y == w) hasEdgeVW = true;
               }

               for (int z : graph[w]) {
                  if (z == v) hasEdgeWV = true;
               }

               if (hasEdgeUV && hasEdgeVW && hasEdgeWV) continue;
               else return false;
            }
         }
      }
   }
   return true;
}

int main() {
   vector<vector<int>> graph = {
      {1, 2},
      {0, 2},
      {0, 1, 3},
      {2}
   };

   cout << boolalpha << checkTripletCondition(graph) << endl;
   return 0;
}

輸出

true

深度優先搜尋 (DFS) 方法

深度優先搜尋 (DFS) 方法需要系統地遍歷圖,從選定的頂點開始,以確定圖中每個頂點三元組是否包含兩個連線到第三個頂點的頂點。對於遇到的每個頂點三元組,演算法會探索所有可能的路徑,並確定是否存在必要的連線。DFS 透過檢視頂點的鄰居來有效地確定三元組中的兩個頂點是否相互連線。如果所有三元組都滿足要求,則演算法驗證整個圖的屬性。DFS 是一種強大且流行的圖遍歷方法,它提供了一種有用的方法來驗證上下文中的連線性要求。

演算法

  • 建立一個標誌變數並將其設定為 true,以監控是否滿足每個三元組的要求。

  • 應該從圖中的每個頂點開始 DFS 遍歷。

  • 對於在 DFS 遍歷期間遇到的每個頂點“v”,檢查其鄰居(相鄰頂點)。

  • 檢查“v”的每個鄰居“u”和“w”組合之間是否存在邊。

  • 如果“u”和“w”之間存在邊,則檢查“v”是否也與“u”和“w”都存在邊。

  • 如果對於任何三元組不滿足條件,則將標誌變數設定為 false 並結束該遍歷的 DFS。

  • 直到標誌變數對於任何三元組更改為 false,或者直到在 DFS 遍歷期間訪問了所有頂點。

  • 如果在 DFS 遍歷後標誌變數仍然為 true,則表示圖中每個頂點三元組都包含兩個連線到第三個頂點的頂點。否則,即使是最小的三元組也不滿足要求。

示例

#include <iostream>
#include <vector>
using namespace std;

class Graph {
private:
   int V;
   vector<vector<int>> adj;

public:
   Graph(int V) : V(V) {
      adj.resize(V);
   }

   void addEdge(int u, int v) {
      adj[u].push_back(v);
      adj[v].push_back(u);
   }

   bool checkTriplets() {
      bool flag = true;

      for (int i = 0; i < V && flag; ++i) {
         vector<bool> visited(V, false);
         flag = flag && dfs(i, -1, visited);
      }

      return flag;
   }

   bool dfs(int curr, int parent, vector<bool>& visited) {
      visited[curr] = true;
      int connectedCount = 0;

      for (int neighbor : adj[curr]) {
         if (neighbor != parent) {
            if (visited[neighbor]) {
               connectedCount++;
            } else {
               if (!dfs(neighbor, curr, visited))
                  return false;
            }
         }
      }

      return connectedCount >= 2;
   }
};

int main() {
   Graph graph(6);

   graph.addEdge(0, 1);
   graph.addEdge(1, 2);
   graph.addEdge(1, 3);
   graph.addEdge(2, 3);
   graph.addEdge(3, 4);
   graph.addEdge(4, 5);

   bool result = graph.checkTriplets();
   cout << "Requirement Met: " << boolalpha << result << endl;

   return 0;
}

輸出

Requirement Met: false

結論

總之,已經研究了兩種不同的方法——蠻力法和深度優先搜尋 (DFS) 方法——用於確定圖中每個頂點三元組是否包含兩個連線到第三個頂點的頂點。蠻力法對於小型圖效率很高,但由於其 O(V3) 的時間複雜度,對於大型圖效率低下,因為它會迭代遍歷所有可能的三個頂點組合並檢查必要的連線。

另一方面,DFS 方法提供了一種更有效的方法來驗證圖中的連線性要求。它高效地探索圖,並查詢三元組之間必要的連線。DFS 演算法確保圖滿足所需條件,並且由於其時間複雜度比蠻力法更低,因此適用於更大的網路。

更新於:2023年8月4日

瀏覽量:105

開啟您的職業生涯

完成課程獲得認證

開始學習
廣告