helpen bij het Donalds B. Johnson's algoritme, ik kan de pseudo-code niet begrijpen (deel II)

stemmen
6

Ik kan een bepaald deel van de door Donald Johnson gepubliceerd over het vinden van cycli (Circuits) in een grafiek papier niet begrijpen.

Meer specifiek kan ik niet begrijpen wat is de matrix Ak, die in de volgende regel van de pseudo-code wordt genoemd:

Ak: = nabijheid structuur van sterke component K met tenminste top samenvalt subgraaf van G geïnduceerd door {s, s + 1, .... n};

Tot overmaat van ramp sommige lijnen na is mentins maken voor i in Vk doen, zonder te verklaren wat de Vk is ...

Voor zover ik heb verstaan ​​we de volgende: 1) over het algemeen een sterke component een deelgraaf een grafiek, waarin voor elk knooppunt van het deelgraaf is er een pad naar elk knooppunt van de deelgraaf ( in andere woorden, je hebt toegang tot elk knooppunt van de sub-grafiek van een ander knooppunt van de sub-grafiek)

2) een deelgraaf geïnduceerd door een lijst van knooppunten is een grafiek die deze knooppunten plus alle randen die deze knooppunten verbinden. in document de wiskundige definitie F is een subgraaf van G geïnduceerd door W of W deelverzameling van V en F = (W, {u, y) | u, y W en (u, y) E)}) indien u, y randen, E de verzameling van alle randen in de grafiek, w een set knopen.

3) in de implementatie van de code de knooppunten worden benoemd door gehele getallen 1 ... n.

4) Ik vermoed dat de Vk de set knopen van de sterke component K.

nu op de vraag. Laten we zeggen dat we een graaf G = (V, E) met V = {} 1,2,3,4,5,6,7,8,9 die kan worden verdeeld in 3 componenten sterk de SC1 = {1, 4,7,8} = {2,3,9 SC2 SC3} = {5,6} (en hun randen)

Kan iemand me een voorbeeld voor s = 1, s = 2, s = 5 wat als gaat de Vk en Ak volgens de code te zijn?

De pseudo-code is in mijn vorige vraag in Inzicht in de pseudocode in de Donald B. Johnson's algoritme

en het papier kan worden gevonden op Inzicht in de pseudocode in de Donald B. Johnson's algoritme

dank u bij voorbaat

De vraag is gesteld op 30/05/2010 om 19:50
bron van user
In andere talen...                            


4 antwoorden

stemmen
10

Het werkt! In een eerdere iteratie van de Johnson-algoritme , had ik verondersteld dat Awas een adjacentiematrix . In plaats daarvan lijkt het een vertegenwoordigen nabijheid lijst . In dit voorbeeld, uitgevoerd onder de hoekpunten {a, b, c} genummerd {0, 1, 2}, waarbij de volgende circuits.

Aanhangsel: Zoals in de voorgestelde bewerken en behulpzaam antwoord , het algoritme bepaald dat unblock()moet het element te verwijderen die de waarde w , niet het element met de index w .

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

Voorbeeld output:

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

Standaard wordt het programma begint met s = 0; implementeren s := least vertex in Vals een optimalisatie blijft. Een variant die alleen uniek cycli produceert weergegeven here .

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;
            }
        }
    }
}
antwoordde op 01/06/2010 om 18:30
bron van user

stemmen
1

Ik had een sumbitted bewerking verzoek om de code @ trashgod om de uitzondering gegooid in te lossen unblock(). In wezen, het algoritme dat het element w(dat niet een index) is uit de lijst verwijderd. De code gebruikt list.remove(w), die behandeld wals index.

Mijn bewerken verzoek werd afgewezen! Ik weet niet zeker waarom, omdat ik het bovenstaande met mijn modificatie op een netwerk van 20.000 nodes en 70.000 randen hebben getest en is het niet crashen.

Ik heb ook gemodificeerde Johnson's algoritme meer worden aangepast aan de ongerichte grafieken. Als iemand wil dat deze wijzigingen kunt u contact met mij op.

Hieronder is mijn code voor 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);
        }
    }
}
antwoordde op 12/02/2013 om 04:05
bron van user

stemmen
1

@trashgod, je steekproef uitvoer bevat cyclus welke cyclische permutatie zijn. Bijvoorbeeld 0-1-0 en 1-0-1 zijn gelijk feite de productie moet bevat 5 cyclus dwz 0 1 0 0 2 0 0 1 2 0 0 2 1 0 1 2 1,

Johnson papier uit te leggen wat een cyclus is: 'Two elementaire circuits zijn te onderscheiden als men niet een cyclische permutatie van de ander. 'Men kan ook controleren wolfram pagina Ook dit uitgang 5 cyclus voor dezelfde ingang.

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

antwoordde op 08/04/2015 om 12:14
bron van user

stemmen
1

De volgende variatie produceert unieke cycli. Op basis van dit voorbeeld wordt omgebouwd antwoord op geleverde @ 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;
            }
        }
    }
}

Output:

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

Alle cycli, ter referentie:

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
antwoordde op 10/03/2016 om 17:09
bron van user

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