Nápověda v Donalds B. Johnson algoritmu, nemohu pochopit pseudo kód (část II)

hlasů
6

nemohu pochopit určitou část článku publikovaném Donald Johnson o hledání cyklů (okruhů) v grafu.

Konkrétnější nemohu pochopit, co je matice Ak, který je uveden v následující řádek pseudo kód:

AK: = sousedů struktura silné složky K s nejméně vrcholu v podgrafu G vyvolané {S, S + 1, .... n};

aby to bylo ještě horší některé linky po mentins „for i in Vk dělat“ bez udání co Vk je ...

Pokud mám pochopit, máme následující: 1) Obecně platí, že silná složka je sub-graf grafu, ve kterém za každý uzel tohoto sub-grafu jsou na cestu k jakémukoliv uzlu sub-grafu ( jinými slovy, můžete přistupovat k libovolnému uzlu sub-grafu z jiného uzlu sub-grafu)

2) sub-graf indukovaného seznamem uzlů je graf, který obsahuje všechny tyto uzly dále všechny hrany spojující tyto uzly. v papírové matematické definice F je podgrafem G vyvolané W, pokud W je podmnožinou V a F = (W, {u, y) | u, y na W a (u, y) v E)}) kde u, y jsou hrany, E je množina všech hran v grafu, W je sada uzlů.

3) při provádění kódu uzly jsou pojmenovány podle integer čísly 1 ... n.

4) I podezření, že Vk je množina uzlů silné složky K.

Nyní k otázce. Řekněme, že máme graf G = (V, E) s V = {1,2,3,4,5,6,7,8,9}, která může být rozdělena do 3 silné komponenty SC1 = {1, 4,7,8} SC2 = {2,3,9} SC3 = {5,6} (a jejich okraje)

Může mi někdo dát příklad s = 1, s = 2, y = 5 Co když bude VK a Ak podle kódu?

Pseudo kód je v mé předchozí otázce v Pochopení pseudocode v Donald B. Johnsona algoritmu

a papír lze nalézt na Pochopení pseudocode v Donald B. Johnsona algoritmu

Děkuji předem

Položena 30/05/2010 v 19:50
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
10

Funguje to! V dřívější iterace tohoto algoritmu Johnson , jsem předpokládal, že Abyl matice sousednosti . Místo toho se zdá, že představují seznam sousednosti . V tomto příkladu provedena níže, vrcholy {a, b, c} jsou očíslovány {0, 1, 2}, čímž se získá následující obvody.

Dodatek: Jak je uvedeno v této navrhované úpravy a užitečnou odpověď , algoritmus určuje, že unblock()by mělo odstranit prvek, který má hodnotu w , nikoli prvek má index w .

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

Ukázkový výstup:

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

Ve výchozím nastavení se program začíná s = 0; prováděcí s := least vertex in Vjako optimalizace zůstane. Variace, který produkuje pouze jedinečné cykly je uveden zde .

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;
            }
        }
    }
}
Odpovězeno 01/06/2010 v 18:30
zdroj uživatelem

hlasů
1

Jsem Podané s editační žádost kódu @ trashgod pro upevnění výjimku vyvolána v unblock(). V podstatě algoritmus říká, že element w(což není index) má být odstraněn ze seznamu. Výše uvedený kód použit list.remove(w), který zachází wjako index.

My editovat žádost byla zamítnuta! Nejste si jisti, proč, protože jsem otestoval na výše uvedené se svou změnou v síti 20.000 uzlů a 70.000 hrany a to nespadne.

Také jsem upravil Johnsonův algoritmus být více přizpůsobeny neorientovaných grafech. Pokud někdo chce tyto úpravy, prosím, kontaktujte mě.

Níže je můj kód 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);
        }
    }
}
Odpovězeno 12/02/2013 v 04:05
zdroj uživatelem

hlasů
1

@trashgod Vaše vzorek výstup obsahuje cyklus, které jsou cyklické permutace. Například 0-1-0 a 1-0-1 jsou stejné skutečnosti výstup by měl obsahuje pouze 5 cyklu tj 0 1 0, 0 2 0 0 1 2 0, 0 2 1 0, 1 2 1,

Johnson papíru vysvětlit, co je to cyklus, je: ‚Dvě základní okruhy jsou odlišné, pokud není cyklická obměna druhého. "Je také možné zjistit wolframové strana: To také výstup 5 cyklus pro stejný vstup.

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

Odpovězeno 08/04/2015 v 12:14
zdroj uživatelem

hlasů
1

Následující varianta vytváří unikátní cyklů. Na základě tohoto příkladu , to je přizpůsobena z odpovědí poskytnutých @ user1406062 .

Kód:

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

Výstup:

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

Všechny cykly, k odkazu:

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
Odpovězeno 10/03/2016 v 17:09
zdroj uživatelem

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