Annak ellenőrzése, hogy van-e Java grafikonnak ciklusa

1. Áttekintés

Ebben a gyors bemutatóban megtudhatjuk, hogyan tudunk ciklust észlelni egy adott irányított gráfban.

2. Grafikonábrázolás

Ehhez az oktatóanyaghoz ragaszkodunk a szomszédsági lista grafikon ábrázolásához.

Először is kezdjük az a meghatározásával Csúcs Java-ban:

public class Vertex {private String label; privát logikai lényVisited; privát logikai látogatás; private List adjacencyList; public Vertex (String label) {this.label = label; this.adjacencyList = new ArrayList (); } public void addNeighbor (Vertex szomszédos) {this.adjacencyList.add (szomszédos); } // szerelők és beállítók}

Itt a adjacencyList egy csúcs v a szomszédos csúcsok listáját tartalmazza v. A addNeighbor () metódus hozzáad egy szomszédos csúcsot a v.

Kettőt is definiáltunk logikai paraméterek,meglátogatva és meglátogatott, amelyek azt jelzik, hogy a csomópontot jelenleg látogatják-e, vagy már meglátogatták-e.

A gráf felfogható csúcsok vagy csomópontok csoportjaként, amelyek összekapcsolódnak az éleken.

Tehát, most képviseljük gyorsan a Grafikon Java-ban:

public class Graph {private List csúcsok; public Graph () {this.vertices = new ArrayList (); } public void addVertex (csúcscsúcs) {this.vertices.add (csúcs); } public void addEdge (Vertex from, Vertex to) {from.addNeighbor (to); } // ...}

Használjuk a addVertex () és addEdge () módszerek új csúcsok és élek hozzáadásához a grafikonunkba.

3. Ciklusérzékelés

Ciklus észleléséhez irányított gráfban, a variációját fogjuk használni DFS bejárás:

  • Vedd fel egy nem látogatott csúcsot v és jelölje meg állapotát meglátogatva
  • Minden szomszédos csúcsra u nak,-nek v, jelölje be:
    • Ha u már a meglátogatva állapot, egyértelműen azt jelenti van egy hátsó él és így egy ciklust észleltek
    • Ha u még nem látogatott állapotban van, rekurzívan meglátogatjuk u mélység-első módon
  • Frissítse a csúcsot v’S meglátogatva zászló to hamis és annak meglátogatta zászló to igaz

Vegye figyelembe, hogy gráfunk összes csúcsa kezdetben nem látogatott állapotban van, mindkettő meglátogatva és meglátogatta zászlók inicializálva vannak hamis.

Most nézzük meg a Java megoldásunkat:

nyilvános logikai hasCycle (Vertex sourceVertex) {sourceVertex.setBeingVisited (true); mert (Vertex szomszéd: sourceVertex.getAdjacencyList ()) {if (szomszéd.isBeingVisited ()) {// hátsó él létezik true true; } else if (! szomszéd.isVisited () && hasCycle (szomszéd)) {return true; }} sourceVertex.setBeingVisited (hamis); sourceVertex.setVisited (true); return false; }

A grafikon bármely csúcsát felhasználhatjuk forrásnak vagy kiinduló csúcsnak.

A leválasztott grafikonhoz hozzá kell adnunk egy további burkoló módszert:

public logikai hasCycle () {for (Vertex csúcs: csúcsok) {if (! vertex.isVisited () && hasCycle (vertex)) {return true; }} return false; }

Ennek célja, hogy meglátogassuk a lekapcsolt gráf minden elemét a ciklus észleléséhez.

4. Megvalósítás tesztelése

Vegyük figyelembe az alábbi ciklikusan irányított grafikont:

Gyorsan írhatunk egy JUnit-et, hogy ellenőrizzük hasCycle () módszer ehhez a grafikonhoz:

@Test public void givenGraph_whenCycleExists_thenReturnTrue () {Vertex vertexA = new Vertex ("A"); Vertex vertexB = új csúcs ("B"); Csúcscsúcs C = új Csúcs ("C") Csúcscsúcs D = új Csúcs ("D"); Grafikondiagram = new Graph (); 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 ()); }

Itt, a mi hasCycle () módszer visszaküldött igaz jelezve, hogy gráfunk ciklikus.

5. Következtetés

Ebben az oktatóanyagban megtanultuk, hogyan lehet ellenőrizni, hogy létezik-e ciklus egy adott irányított gráfban a Java-ban.

Szokás szerint a kód megvalósítása példákkal együtt elérhető a Github oldalon.


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