الفرز الطوبولوجي

تم إعداد ترجمة للمقال قبل بدء دورة "الخوارزميات للمطورين" .




الفرز الطوبولوجي للرسم البياني الحلقي الموجه (الرسوم البيانية الحلقية الموجهة ، والمشار إليها فيما بعد باسم DAG) هو ترتيب خطي للقمم ينطبق عليه الشرط التالي: لكل حافة موجهة للأشعة فوق البنفسجية ، يسبق الرأس u القمة v في الترتيب. إذا لم يكن الرسم البياني DAG ، فإن التصنيف الطوبولوجي غير ممكن لذلك.

على سبيل المثال ، التصنيف الطبوغرافي للرسم البياني أدناه هو "5 4 2 3 1 0". يمكن أن يكون هناك العديد من الفرز الطوبولوجي للرسم البياني. على سبيل المثال ، تصنيف طوبولوجي آخر للرسم البياني نفسه هو "4 5 2 3 1 0". الرأس الأول في الفرز الطوبولوجي هو دائمًا الرأس بدون حواف واردة.



الفرز الطوبولوجي مقابل المشي العميق:

عند التعمق(Depth First Traversal ، المشار إليها فيما بعد باسم DFS ) نقوم بإخراج الرأس ثم استدعاء DFS بشكل متكرر للقمم المجاورة. في الفرز الطوبولوجي ، نحتاج إلى عرض الرأس أمام القمم المجاورة. على سبيل المثال ، في هذا الرسم البياني ، يجب عرض الرأس "5" قبل الرأس "0" ، وعلى عكس DFS ، يجب أيضًا عرض الرأس "4" قبل الرأس "0". هذا يميز الفرز الطوبولوجي عن DFS. على سبيل المثال ، DFS للعمود أعلاه هو "5 2 3 1 0 4" ، لكن هذا ليس ترتيبًا طوبولوجيًا.

توصية: قبل الانتقال إلى تطبيق الخوارزمية ، حاول أولاً فهم المهمة عمليًا .

خوارزمية البحث الفرز الطوبولوجي.

للبدء ، نوصي بأن تتعرف على تنفيذ DFS هذا . يمكننا تعديل DFS بحيث يتم الحصول على فرز طوبولوجي للرسم البياني. في dfsنبدأ برأس مناسب ، والذي نخرجه أولاً ، ثم نسمي DFS بشكل متكرر للقمم المجاورة. في الفرز الطوبولوجي ، نستخدم كومة مؤقتة. لا يتم عرض الرأس على الفور - أولاً ، يتم استدعاء الفرز الطوبولوجي لجميع القمم المجاورة ، ثم يتم دفع الرأس إلى المكدس. يتم عرض محتويات المكدس فقط بعد اجتياز جميع القمم. لاحظ أنه لا يتم دفع الرأس إلى المكدس إلا عندما تكون جميع القمم المتجاورة (والقمم المجاورة ، وما إلى ذلك) موجودة بالفعل في المكدس.

الصورة أدناه هي توضيح للنهج أعلاه:



:
(G)

0 →
1→
2 → 3
3 → 1
4 → 0, 1
5 → 2, 0

1:
(0), visited[0] = true
. .
0
2:
(1), visited[1] = true
. .
0 1
3:
(2),, visited[2] = true
(3),, visited[3] = true
1 .
0 1 3 2
4:
(4),, visited[4] = true
تمت زيارة القمم 0 و 1 بالفعل. لا مزيد من المكالمات العودية.
المكدس 0 1 3 2 4
الخطوة 5:
الفرز الطوبولوجي (5) ، تمت
الزيارة [5] = صحيح تم زيارة الذراعين 2 و 0 بالفعل. لا مزيد من المكالمات المتكررة ،
المكدس 0 1 3 2 4 5
الخطوة 6:
سحب جميع عناصر المكدس من الأعلى إلى الأسفل


فيما يلي تطبيقات الفرز الطبوغرافية. يرجى التحقق من تنفيذ DFT للحصول على رسم بياني غير متصل وملاحظة الاختلافات بين الرمز الثاني المعطى هناك والرمز أدناه.

C ++


//   C++     DAG
 
#include<iostream>
#include <list>
#include <stack>
using namespace std;
  
//    
class Graph
{
    int V;	//  
  
    //    ,   
    list<int> *adj;
  
    // ,  topologicalSort
    void topologicalSortUtil(int v, bool visited[], stack<int> &Stack);
public:
    Graph(int V);   // 
  
     //      
    void addEdge(int v, int w);
  
    //    
    void topologicalSort();
};
  
Graph::Graph(int V)
{
    this->V = V;
    adj = new list<int>[V];
}
  
void Graph::addEdge(int v, int w)
{
    adj[v].push_back(w); // Add w to v’s list.
}
  
//  ,  topologicalSort
void Graph::topologicalSortUtil(int v, bool visited[], 
                                stack<int> &Stack)
{
    //     
    visited[v] = true;
  
    //       
    list<int>::iterator i;
    for (i = adj[v].begin(); i != adj[v].end(); ++i)
        if (!visited[*i])
            topologicalSortUtil(*i, visited, Stack);
  
    //       
    Stack.push(v);
}
  
//     . 
//   topologicalSortUtil()
void Graph::topologicalSort()
{
    stack<int> Stack;
  
    //     
    bool *visited = new bool[V];
    for (int i = 0; i < V; i++)
        visited[i] = false;
  
    //     
    //       
    for (int i = 0; i < V; i++)
      if (visited[i] == false)
        topologicalSortUtil(i, visited, Stack);
  
    //   
    while (Stack.empty() == false)
    {
        cout << Stack.top() << " ";
        Stack.pop();
    }
}
  
//    
int main()
{
    //  ,    
    Graph g(6);
    g.addEdge(5, 2);
    g.addEdge(5, 0);
    g.addEdge(4, 0);
    g.addEdge(4, 1);
    g.addEdge(2, 3);
    g.addEdge(3, 1);
  
    cout << "Following is a Topological Sort of the given graph \n";
    g.topologicalSort();
  
    return 0;
}

جافا


//   Java    
import java.io.*;
import java.util.*;
  
//          
class Graph
{
    private int V;   //  
    private LinkedList<Integer> adj[]; //  
  
    // 
    Graph(int v)
    {
        V = v;
        adj = new LinkedList[v];
        for (int i=0; i<v; ++i)
            adj[i] = new LinkedList();
    }
  
    //      
    void addEdge(int v,int w) { adj[v].add(w); }
  
    //  ,  topologicalSort
    void topologicalSortUtil(int v, boolean visited[],
                             Stack stack)
    {
        //      
        visited[v] = true;
        Integer i;
  
        //       
        Iterator<Integer> it = adj[v].iterator();
        while (it.hasNext())
        {
            i = it.next();
            if (!visited[i])
                topologicalSortUtil(i, visited, stack);
        }
  
        //       
        stack.push(new Integer(v));
    }
  
    //     .
    //   topologicalSortUtil()
    void topologicalSort()
    {
        Stack stack = new Stack();
  
        //     
        boolean visited[] = new boolean[V];
        for (int i = 0; i < V; i++)
            visited[i] = false;
  
        //    
        //       
        for (int i = 0; i < V; i++)
            if (visited[i] == false)
                topologicalSortUtil(i, visited, stack);
  
        //   
        while (stack.empty()==false)
            System.out.print(stack.pop() + " ");
    }
  
    //   
    public static void main(String args[])
    {
        //  ,    
        Graph g = new Graph(6);
        g.addEdge(5, 2);
        g.addEdge(5, 0);
        g.addEdge(4, 0);
        g.addEdge(4, 1);
        g.addEdge(2, 3);
        g.addEdge(3, 1);
  
        System.out.println("Following is a Topological " +
                           "sort of the given graph");
        g.topologicalSort();
    }
}
//      (Aakash Hasija)

بيثون


#  Python       DAG   import defaultdict
  
#   
class Graph:
    def __init__(self,vertices):
        self.graph = defaultdict(list) #dictionary containing adjacency List
        self.V = vertices #No. of vertices
  
    #      
    def addEdge(self,u,v):
        self.graph[u].append(v)
  
    #  ,  topologicalSort
    def topologicalSortUtil(self,v,visited,stack):
  
        #     
        visited[v] = True
  
        #       
        for i in self.graph[v]:
            if visited[i] == False:
                self.topologicalSortUtil(i,visited,stack)
  
        #       
        stack.insert(0,v)
  
    #     . 
    #   topologicalSortUtil()
    def topologicalSort(self):
        #     
        visited = [False]*self.V
        stack =[]
  
        #    
        #       
        for i in range(self.V):
            if visited[i] == False:
                self.topologicalSortUtil(i,visited,stack)
  
        #   
        print stack
  
g= Graph(6)
g.addEdge(5, 2);
g.addEdge(5, 0);
g.addEdge(4, 0);
g.addEdge(4, 1);
g.addEdge(2, 3);
g.addEdge(3, 1);
  
print "Following is a Topological Sort of the given graph"
g.topologicalSort()
#     (Neelam Yadav)

<b>:</b>
Following is a Topological Sort of the given graph
5 4 2 3 1 0

الصعوبة في الوقت المناسب: الخوارزمية أعلاه هي DFS مع مكدس إضافي. وبالتالي ، فإن تعقيد الوقت هو نفسه تعقيد DFS ، وهو O (V + E).

ملاحظة: يمكنك أيضًا استخدام متجه بدلاً من مكدس. إذا كنت تستخدم متجهًا للحصول على الفرز الطوبولوجي ، فأنت بحاجة إلى إخراج العناصر بالترتيب العكسي.

تطبيق:

يستخدم الفرز الطوبولوجي بشكل أساسي لجدولة العمل من تبعيات معينة بينهما. في علوم الكمبيوتر ، يتم استخدامه لتخطيط الأوامر ، وتنظيم الخلايا لحساب الصيغ عند إعادة حساب قيم الصيغة في جداول البيانات ، والتوليف المنطقي ، وتحديد ترتيب مهام التجميع التي يتم إجراؤها في ملفات makefiles ، وتسلسل البيانات ، وحل التبعيات الرمزية في الروابط [ 2 ].


مقالات ذات صلة


خوارزمية كان للفرز الطوبولوجي : خوارزمية أخرى (V + E).
جميع الفرز الطوبولوجي للرسم البياني الحلقي الموجه

المراجع


http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/GraphAlgor/topoSort.htm
http://en.wikipedia.org/wiki/Topological_sorting

يرجى ترك تعليق إذا وجدت خطأ أو إذا كنت تريد المشاركة معلومات إضافية حول الموضوع قيد المناقشة.



تعلم المزيد عن الدورة.



All Articles