Hilfe bei der Algorithmus Donalds B. Johnson, ich nicht dem Pseudo-Code verstehen kann (Teil II)

stimmen
6

Ich kann nicht einen bestimmten Teil des Papiers veröffentlicht von Donald Johnson über die Suche nach Zyklen (Circuits) in einem Graphen verstehen.

Speziellere ich nicht verstehen kann, was die Matrix Ak, die in der folgenden Zeile des Pseudo-Code erwähnt wird:

Ak: = adjacency Struktur starke Komponente K mit mindestens Vertex in Subgraphen von G induziert durch {s, s + 1, .... n};

einige Zeilen nachdem es mentins „für i in Vk tun“, um alles noch schlimmer zu machen, ohne zu erklären, was der Vk ist ...

Was ich habe verstehen wir haben die folgenden: 1) in der Regel eine starke Komponente ist ein Teilgraph eines Graphen, bei dem für jeden Knoten dieses Teil Graph, der einen Weg dorthin zu jedem Knoten des Unter Graph ist ( mit anderen Worten können Sie einen beliebigen Knoten des Unter graph von jedem anderen Knoten des Unter graph zugreifen)

2) Ein Teilgraph induzierten durch eine Liste von Knoten ist ein Graph , all diese Knoten enthält , sowie alle Kanten Verbinden dieser Knoten. in Papier ist die mathematische Definition F ein Teilgraph von G nach W induziert ist , wenn W Teilmenge von V und F = (W ist {u, y) | u, y in W und (u, y) in E)}) wobei u, y Kanten sind, E die Menge aller Kanten in dem Graphen ist, W eine Gruppe von Knoten.

3) in der Code-Implementierung werden die Knoten, die durch ganze Zahlen 1 ... n bezeichnet.

4) I vermuten , dass die Vk der Satz von Knoten der starken Komponente K.

jetzt auf die Frage. Können sagen wir haben einen Graph G = (V, E) mit V = {} 1,2,3,4,5,6,7,8,9 die sie kann in 3 starke Komponenten der SC1 = {1 unterteilt werden, 4,7,8} SC2 = {2,3,9} SC3 = {5,6} (und ihre Kanten)

Kann mir jemand ein Beispiel geben für s = 1, s = 2, s = 5, was, wenn gehen die Vk und Ak gemäß dem Code sein?

Der Pseudocode ist in meiner vorherigen Frage in dem Pseudo - Code in der Donald B. Johnsons Algorithmus zu verstehen

und das Papier finden Sie unter Grundlegendes zu den Pseudo - Code in der Donald B. Johnsons Algorithmus

Vielen Dank im Voraus

Veröffentlicht am 30/05/2010 um 19:50
quelle vom benutzer
In anderen Sprachen...                            


4 antworten

stimmen
10

Es klappt! In einer früheren Iteration des Johnson - Algorithmus , hatte ich angenommen , dass Awar eine Adjazenzmatrix . Stattdessen scheint es eine darzustellen Adjazenzliste . In diesem Beispiel implementiert nachstehend haben die Scheitelpunkte {a, b, c} sind nummeriert {0, 1, 2}, wobei die folgenden Schaltungen.

Nachtrag: Wie in diesem Vorschlag festgestellt , bearbeiten und hilfreiche Antwort gibt der Algorithmus , dass unblock()sollte das Element entfernen Sie den mit Wert w , nicht das Element die mit Index w .

list.remove(Integer.valueOf(w));

Beispielausgabe:

0 1 0
0 1 2 0
0 2 0
0 2 1 0
1 0 1
1 0 2 1
1 2 0 1
1 2 1
2 0 1 2
2 0 2
2 1 0 2
2 1 2

Standardmäßig startet das Programm mit s = 0; Umsetzung s := least vertex in Vals eine Optimierung bleibt. Eine Variante , die nur einmalige Zyklus erzeugt wird gezeigt hier .

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

/**
 * @see http://dutta.csc.ncsu.edu/csc791_spring07/wrap/circuits_johnson.pdf
 * @see https://stackoverflow.com/questions/2908575
 * @see https://stackoverflow.com/questions/2939877
 * @see http://en.wikipedia.org/wiki/Adjacency_matrix
 * @see http://en.wikipedia.org/wiki/Adjacency_list
 */
public final class CircuitFinding {

    final Stack<Integer> stack = new Stack<Integer>();
    final List<List<Integer>> a;
    final List<List<Integer>> b;
    final boolean[] blocked;
    final int n;
    int s;

    public static void main(String[] args) {
        List<List<Integer>> a = new ArrayList<List<Integer>>();
        a.add(new ArrayList<Integer>(Arrays.asList(1, 2)));
        a.add(new ArrayList<Integer>(Arrays.asList(0, 2)));
        a.add(new ArrayList<Integer>(Arrays.asList(0, 1)));
        CircuitFinding cf = new CircuitFinding(a);
        cf.find();
    }

    /**
     * @param a adjacency structure of strong component K with
     * least vertex in subgraph of G induced by {s, s + 1, n};
     */
    public CircuitFinding(List<List<Integer>> a) {
        this.a = a;
        n = a.size();
        blocked = new boolean[n];
        b = new ArrayList<List<Integer>>();
        for (int i = 0; i < n; i++) {
            b.add(new ArrayList<Integer>());
        }
    }

    private void unblock(int u) {
        blocked[u] = false;
        List<Integer> list = b.get(u);
        for (int w : list) {
            //delete w from B(u);
            list.remove(Integer.valueOf(w));
            if (blocked[w]) {
                unblock(w);
            }
        }
    }

    private boolean circuit(int v) {
        boolean f = false;
        stack.push(v);
        blocked[v] = true;
        L1:
        for (int w : a.get(v)) {
            if (w == s) {
                //output circuit composed of stack followed by s;
                for (int i : stack) {
                    System.out.print(i + " ");
                }
                System.out.println(s);
                f = true;
            } else if (!blocked[w]) {
                if (circuit(w)) {
                    f = true;
                }
            }
        }
        L2:
        if (f) {
            unblock(v);
        } else {
            for (int w : a.get(v)) {
                //if (v∉B(w)) put v on B(w);
                if (!b.get(w).contains(v)) {
                    b.get(w).add(v);
                }
            }
        }
        v = stack.pop();
        return f;
    }

    public void find() {
        while (s < n) {
            if (a != null) {
                //s := least vertex in V;
                L3:
                circuit(s);
                s++;
            } else {
                s = n;
            }
        }
    }
}
Beantwortet am 01/06/2010 um 18:30
quelle vom benutzer

stimmen
1

Ich hatte eine sumbitted bearbeiten Anfrage @ trashgod der Code die Ausnahme geworfen zu beheben in unblock(). Im Wesentlichen stellt der Algorithmus, der das Element w(das ist nicht ein Index) aus der Liste entfernt werden soll. Der obige Code verwendet list.remove(w), der behandelt wals Index.

Mein bearbeiten Antrag wurde abgelehnt! Nicht sicher , warum, weil ich das oben mit meiner Modifikation in einem Netzwerk von 20.000 Knoten und 70.000 Kanten getestet habe und es nicht abstürzt.

Ich habe auch auf ungerichtete Graphen angepasst Johnsons Algorithmus werden mehr geändert. Wenn jemand diese Änderungen will kontaktieren Sie mich.

Unten ist mein Code für unblock().

private void unblock(int u) {
    blocked[u] = false;
    List<Integer> list = b.get(u);
    int w;
    for (int iw=0; iw < list.size(); iw++) {
        w = Integer.valueOf(list.get(iw));
        //delete w from B(u);
        list.remove(iw);
        if (blocked[w]) {
            unblock(w);
        }
    }
}
Beantwortet am 12/02/2013 um 04:05
quelle vom benutzer

stimmen
1

@trashgod, Ihre Beispielausgabe enthält Zyklus die zyklische Vertauschung sind. Zum Beispiel 0-1-0 und 1-0-1 gleiche sind eigentlich sollte die Ausgabe enthält nur 5 Zyklus dh 0 1 0, 0 2, 0, 0 1 2 0 0 2 1 0, 1 2 1,

Johnson Papier erklären, was ein Zyklus ist: ‚Zwei Elementarschaltungen sind verschieden, wenn man nicht eine zyklische Permutation des anderen ist. "Man kann auch Wolfram- Seite überprüfen: Diese auch Ausgang 5-Zyklus für den gleichen Eingang.

http://demonstrations.wolfram.com/EnumeratingCyclesOfADirectedGraph/

Beantwortet am 08/04/2015 um 12:14
quelle vom benutzer

stimmen
1

Die folgende Variante produziert einzigartige Zyklen. Basierend auf diesem Beispiel wird von einer angepassten Antwort geliefert von @ user1406062 .

Code:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
 * @see https://en.wikipedia.org/wiki/Johnson%27s_algorithm
 * @see https://stackoverflow.com/questions/2908575
 * @see https://stackoverflow.com/questions/2939877
 * @see http://en.wikipedia.org/wiki/Adjacency_matrix
 * @see http://en.wikipedia.org/wiki/Adjacency_list
 */
public final class CircuitFinding {

    final Stack<Integer> stack = new Stack<Integer>();
    final Map<Integer, List<Integer>> a;
    final List<List<Integer>> b;
    final boolean[] blocked;
    final int n;
    Integer s;

    public static void main(String[] args) {
        List<List<Integer>> a = new ArrayList<List<Integer>>();
        a.add(new ArrayList<Integer>(Arrays.asList(1, 2)));
        a.add(new ArrayList<Integer>(Arrays.asList(0, 2)));
        a.add(new ArrayList<Integer>(Arrays.asList(0, 1)));
        CircuitFinding cf = new CircuitFinding(a);
        cf.find();
    }

    /**
     * @param a adjacency structure of strong component K with least vertex in
     * subgraph of G induced by {s, s + 1, n};
     */
    public CircuitFinding(List<List<Integer>> A) {
        this.a = new HashMap<Integer, List<Integer>>(A.size());
        for (int i = 0; i < A.size(); i++) {
            this.a.put(i, new ArrayList<Integer>());
            for (int j : A.get(i)) {
                this.a.get(i).add(j);
            }
        }
        n = a.size();
        blocked = new boolean[n];
        b = new ArrayList<List<Integer>>();
        for (int i = 0; i < n; i++) {
            b.add(new ArrayList<Integer>());
        }
    }

    private void unblock(int u) {
        blocked[u] = false;
        List<Integer> list = b.get(u);
        for (int w : list) {
            //delete w from B(u);
            list.remove(Integer.valueOf(w));
            if (blocked[w]) {
                unblock(w);
            }
        }
    }

    private boolean circuit(int v) {
        boolean f = false;
        stack.push(v);
        blocked[v] = true;
        L1:
        for (int w : a.get(v)) {
            if (w == s) {
                //output circuit composed of stack followed by s;
                for (int i : stack) {
                    System.out.print(i + " ");
                }
                System.out.println(s);
                f = true;
            } else if (!blocked[w]) {
                if (circuit(w)) {
                    f = true;
                }
            }
        }
        L2:
        if (f) {
            unblock(v);
        } else {
            for (int w : a.get(v)) {
                //if (v∉B(w)) put v on B(w);
                if (!b.get(w).contains(v)) {
                    b.get(w).add(v);
                }
            }
        }
        v = stack.pop();
        return f;
    }

    public void find() {
        s = 0;
        while (s < n) {
            if (!a.isEmpty()) {
                //s := least vertex in V;
                L3:
                for (int i : a.keySet()) {
                    b.get(i).clear();
                    blocked[i] = false;
                }
                circuit(s);
                a.remove(s);
                for (Integer j : a.keySet()) {
                    if (a.get(j).contains(s)) {
                        a.get(j).remove(s);
                    }
                }
                s++;
            } else {
                s = n;
            }
        }
    }
}

Ausgabe:

0 1 0
0 1 2 0
0 2 0
0 2 1 0
1 2 1

Alle Zyklen, als Referenz:

0 1 0
0 1 2 0
0 2 0
0 2 1 0
1 0 1
1 0 2 1
1 2 0 1
1 2 1
2 0 1 2
2 0 2
2 1 0 2
2 1 2
Beantwortet am 10/03/2016 um 17:09
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more