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.


$config[zx-auto] not found$config[zx-overlay] not found