Kontrola, či má Java Graph cyklus
1. Prehľad
V tomto rýchlom výučbe sa dozvieme, ako môžeme detekovať cyklus v danom riadenom grafe.
2. Grafové znázornenie
V tomto tutoriále sa budeme držať znázornenia grafu zoznamu susedných práv.
Najskôr začnime definovaním a Vrchol v Jave:
public class Vertex {private String label; súkromná logická bytosťNavštívené; navštívil súkromný boolean; private List adjacencyList; public Vertex (reťazcový štítok) {this.label = štítok; this.adjacencyList = nový ArrayList (); } public void addNe Neighbor (susediaci vrchol) {this.adjacencyList.add (susedný); } // zakladatelia a zakladatelia}
Tu je adjacencyList vrcholu v obsahuje zoznam všetkých vrcholov susediacich s v. The addNe Neighbor () metóda pridá susedný vrchol do zoznamu susednosti v.
Definovali sme tiež dva boolovský parametre,byť navštívený a navštívil, ktoré predstavujú, či je uzol práve navštevovaný alebo už bol navštívený.
Graf možno považovať za skupinu vrcholov alebo uzlov spojených cez okraje.
Poďme teda teraz rýchlo predstaviť a Graf v Jave:
public class Graph {private List vertices; public Graph () {this.vertices = new ArrayList (); } public void addVertex (vrchol vrcholu) {this.vertices.add (vrchol); } public void addEdge (vrchol od, vrchol do) {from.addNe Neighbor (do); } // ...}
Použijeme addVertex () a addEdge () metódy na pridanie nových vrcholov a hrán do nášho grafu.
3. Detekcia cyklu
Ak chcete zistiť cyklus v usmernenom grafe, použijeme variáciu DFS prechod:
- Zdvihnite nenavštívený vrchol v a označiť jeho stav ako byť navštívený
- Pre každý susedný vrchol u z v, skontrolovať:
- Ak u je už v byť navštívený štát, to jednoznačne znamená existuje spätná hrana a tak bol zistený cyklus
- Ak u zatiaľ nie je v nenavštívenom stave, navštívime ho rekurzívne u spôsobom do hĺbky
- Aktualizujte vrchol v‘S byť navštívený označiť nepravdivé a jeho navštívil označiť pravda
Poznač si to všetky vrcholy nášho grafu sú spočiatku v nenavštívenom stave ako obidva byť navštívený a navštívil vlajky sú inicializované pomocou nepravdivé.
Pozrime sa teraz na naše riešenie Java:
public boolean hasCycle (Vertex sourceVertex) {sourceVertex.setBeingVisited (true); for (Vertex Neighbor: sourceVertex.getAdjacencyList ()) {if (Neighbor.isBeingVisited ()) {// spätná hrana existuje return true; } else if (! Neighbor.isVisited () && hasCycle (Neighbor)) {return true; }} sourceVertex.setBeingVisited (false); sourceVertex.setVisited (true); návrat nepravdivý; }
Akýkoľvek vrchol v grafe môžeme použiť ako východiskový alebo východiskový vrchol.
Pre odpojený graf budeme musieť pridať ďalšiu obalovú metódu:
public boolean hasCycle () {for (Vertex vertex: vertices) {if (! vertex.isVisited () && hasCycle (vertex)) {return true; }} return false; }
To zaisťuje, že navštívime všetky komponenty odpojeného grafu na detekciu cyklu.
4. Testovanie implementácie
Uvažujme nižšie uvedený cyklický smerovaný graf:
Môžeme rýchlo napísať JUnit, aby sme si overili našu hasCycle () metóda pre tento graf:
@Test public void givenGraph_whenCycleExists_thenReturnTrue () {Vertex vertexA = nový Vertex ("A"); Vrchol vertexB = nový Vrchol ("B"); Vrchol vertexC = nový Vrchol ("C") Vrchol vertexD = nový Vrchol ("D"); Graf graf = nový Graf (); graph.addVertex (vertexA); graph.addVertex (vertexB); graph.addVertex (vertexC); graph.addVertex (vertexD); graph.addEdge (vertexA, vertexB); graph.addEdge (vertexB, vertexC); graph.addEdge (vertexC, vertexA); graph.addEdge (vertexD, vertexC); assertTrue (graph.hasCycle ()); }
Tu, náš hasCycle () metóda vrátená pravda čo znamená, že náš graf je cyklický.
5. Záver
V tomto tutoriáli sme sa naučili, ako skontrolovať, či v danom riadenom grafe v Jave existuje cyklus.
Implementácia kódu s príkladmi je ako obvykle k dispozícii na serveri Github.