hjelpe i Donalds B. Johnson algoritme, jeg kan ikke forstå pseudo-kode (del II)

stemmer
6

Jeg kan ikke forstå en bestemt del av artikkel publisert av Donald Johnson om å finne sykluser (kretser) i en graf.

Mer konkret kan jeg ikke forstå hva som er matrisen Ak som er nevnt i følgende linje i pseudo-kode:

Ak: = tilstøter struktur av sterk komponent K med minst topp-punkt i sub-graf av G indusert av {S, S + 1, .... n};

for å gjøre ting verre noen linjer etter, er mentins For jeg i Vk gjøre uten å erklære hva Vk er ...

Så vidt jeg har forstår har vi følgende: 1) generelt, er en sterk komponent en sub-graf av en graf, der for hver node i denne sub-grafen er det en sti til enhver node av under grafen ( med andre ord du kan få tilgang til enhver node av sub-grafen fra enhver annen node av under graf)

2) et sub-graf indusert av en liste med noder er en graf som inneholder alle disse nodene pluss alle de kanter som forbinder disse nodene. i papir den matematiske definisjon er F er en subgraf av G indusert av W hvis W er delsett av v og F = (W, {u, y) | u, y i W og (u, y) i E)}) hvor u, y er kanter, E er settet av alle kanter i grafen, er W et sett av noder.

3) i kode gjennomføringen nodene er oppkalt etter heltall 1 ... n.

4) Jeg har mistanke om at Vk er settet med noder av sterk komponent K.

nå til spørsmålet. La oss si at vi har en graf G = (V, E) med V = {1,2,3,4,5,6,7,8,9} hvilken den kan deles opp i 3 sterke komponenter SC1 = {1, 4,7,8} SC2 = {2,3,9} SC3 = {5,6} (og deres kanter)

Kan noen gi meg et eksempel for s = 1, s = 2, s = 5 hva om kommer til å være den Vk og Ak i henhold til koden?

Pseudo-kode er i mitt forrige spørsmål i Forstå pseudokode i Donald B. Johnson algoritme

og papiret kan bli funnet på Forstå pseudokode i Donald B. Johnson algoritme

takk på forhånd

Publisert på 30/05/2010 klokken 18:50
kilden bruker
På andre språk...                            


4 svar

stemmer
10

Det fungerer! I en tidligere iterasjon av Johnson algoritmen , hadde jeg antok at Avar en naboskapsmatrise . I stedet ser det ut til å representere en tilstøter liste . I dette eksempel, gjennomført under,-punktene {a, b, c} er nummerert {0, 1, 2}, noe som ga følgende kretser.

Tillegg: Som nevnt i denne foreslåtte redigere og nyttig svar , algoritmen presiserer at unblock()skal fjerne elementet ha verdi w , ikke elementet ha indeksen w .

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

Prøve utgang:

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

Som standard starter programmet med s = 0; implementering s := least vertex in Vsom en optimalisering gjenstår. En variant som produserer bare unike sykluser er vist her .

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;
            }
        }
    }
}
Svarte 01/06/2010 kl. 17:30
kilden bruker

stemmer
1

Jeg hadde sumbitted en redigerings forespørsel til @ trashgod kode for å fikse unntak kastet i unblock(). I hovedsak, fastslår algoritmen at elementet w(som ikke er en indeks) skal fjernes fra listen. Koden ovenfor anvendes list.remove(w), som behandler wsom en indeks.

Min redigere forespørselen ble avvist! Ikke sikker på hvorfor, fordi jeg har testet over med min modifikasjon på et nettverk av 20.000 noder og 70.000 kanter og det gjør ikke krasje.

Jeg har også endret Johnson algoritme for å bli mer tilpasset rettede grafer. Hvis noen ønsker disse endringene kan du kontakte meg.

Nedenfor er min kode for 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);
        }
    }
}
Svarte 12/02/2013 kl. 03:05
kilden bruker

stemmer
1

@trashgod, inneholder prøven utgang syklus som er syklisk permutasjon. For eksempel 0-1-0 og 1-0-1 er samme Egentlig utgangs bør kun inneholder 5 syklus dvs. 0 1 0, 0 2 0, 0 1 2 0 0 2 1 0, 1 2 1,

Johnson papir forklare hva en syklus er: 'To elementære kretser er tydelig hvis man ikke er en syklisk permutasjon av den andre. «Man kan også sjekke wolfram side: Dette også utgang 5 sykle for samme inngang.

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

Svarte 08/04/2015 kl. 12:14
kilden bruker

stemmer
1

Den følgende variasjon frembringer unike sykluser. Basert på dette eksemplet , er det tilpasset fra et svar som leveres av @ user1406062 .

Kode:

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;
            }
        }
    }
}

Produksjon:

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

Alle sykluser, for referanse:

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
Svarte 10/03/2016 kl. 17:09
kilden bruker

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