aider dans le Donalds B. L'algorithme de Johnson, je ne peux pas comprendre le code pseudo (PARTIE II)

voix
6

Je ne peux pas comprendre une certaine partie du document publié par Donald Johnson sur la recherche de cycles (circuits) dans un graphique.

i Plus spécifique ne comprends pas ce qui est la matrice Ak qui est mentionné dans la ligne suivante du code pseudo:

Ak: = structure de contiguïté de K forte de composants avec le sommet en moins sous-graphe de G induite par {s, s + 1, .... n};

de faire empirer les choses quelques lignes AFTER est mentins « pour i à Vk faire » sans déclarer ce que le Vk est ...

En ce que j'ai bien compris, nous avons ce qui suit: 1) en général, une forte composante est un sous-graphe d'un graphe, dans lequel, pour chaque nœud de ce sous-graphe il y a un chemin vers un nœud du sous-graphe ( en d'autres termes, vous pouvez accéder à un nœud du sous-graphe d'un autre nœud du sous-graphe)

2) un sous-graphe induit par une liste de noeuds est un graphique contenant tous ces noeuds ainsi que toutes les arêtes reliant ces noeuds. dans le document de la définition mathématique est F est un sous - graphe de G induite par W si W est sous - ensemble de V et F = (W, {u, y) | u, y en W et (u, y) à E)}) où u, y sont des bords, E est l'ensemble de toutes les arêtes du graphe, W est un ensemble de noeuds.

3) la mise en œuvre du code les noeuds sont désignés par des nombres entiers 1 ... n.

4) Je pense que le Vk est l'ensemble des noeuds du composant solide K.

maintenant à la question. Disons que nous avons un graphe G = (V, E) avec V = {} 1,2,3,4,5,6,7,8,9 qui peut être divisé en 3 composantes fortes SC1 = {1, 4,7,8} SC2 = {2,3,9} SC3 = {5,6} (et leurs bords)

Quelqu'un peut-il me donner un exemple pour s = 1, s = 2, s = 5 si va être le Vk et Ak selon le code?

Le pseudo - code est dans ma question précédente Comprendre le pseudo - code dans l'algorithme de Donald B. Johnson

et le papier se trouve à Comprendre le pseudo - code dans l'algorithme de Donald B. Johnson

Merci d'avance

Créé 30/05/2010 à 19:50
source utilisateur
Dans d'autres langues...                            


4 réponses

voix
10

Ça marche! Dans une précédente itération de l' algorithme Johnson , je l' avais supposé que Aétait une matrice de contiguïté . Il semble plutôt représenter une liste de contiguïté . Dans cet exemple, mis en oeuvre ci - dessous, les sommets {a, b, c} sont numérotées {0, 1, 2}, ce qui donne les circuits suivants.

Additif: Comme il est indiqué dans ce projet modifier et utile réponse , l'algorithme spécifie que unblock()devrait supprimer l'élément ayant la valeur w , et non l'élément ayant l' indice w .

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

Exemple de sortie:

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

Par défaut, le programme commence par s = 0; la mise en œuvre s := least vertex in Vcomme une optimisation reste. Une variation qui ne produit que des cycles uniques est montré ici .

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;
            }
        }
    }
}
Créé 01/06/2010 à 18:30
source utilisateur

voix
1

J'avais sumbitted une modifier demande au code de @ trashgod pour fixer l'exception jeté unblock(). Pour l' essentiel, l'algorithme indique que l'élément w(qui est pas un indice) doit être retiré de la liste. Le code utilisé ci - dessus list.remove(w), qui traite wcomme indice.

Ma modifier demande a été rejetée! Je ne sais pas pourquoi, parce que je l' ai testé ci - dessus avec ma modification sur un réseau de 20.000 noeuds et 70000 arêtes et il ne tombe pas en panne.

Je l'ai également modifié l'algorithme de Johnson à plus adaptée aux graphes non orientés. Si quelqu'un veut que ces modifications s'il vous plaît me contacter.

Ci - dessous mon code 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);
        }
    }
}
Créé 12/02/2013 à 04:05
source utilisateur

voix
1

@trashgod, votre sortie de l'échantillon contient cycle qui sont permutation cyclique. Par exemple 0-1-0 et 1-0-1 sont identiques En fait, la sortie devrait contenir seulement cinq cycles à-dire 0 1 0 0 2 0 0 1 2 0, 0 2 1 0 1 2 1,

papier Johnson expliquer ce qu'est un cycle est: « Deux circuits élémentaires sont distincts si l'on est pas une permutation cyclique de l'autre. 'On peut aussi consulter la page de Wolfram: Ce cycle 5 également sortie pour la même entrée.

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

Créé 08/04/2015 à 12:14
source utilisateur

voix
1

La variation suivante produit des cycles uniques. Sur la base de cet exemple , il est adapté d'une réponse fournie par @ 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;
            }
        }
    }
}

Sortie:

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

Tous les cycles, pour référence:

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
Créé 10/03/2016 à 17:09
source utilisateur

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