ayudo en el algoritmo de Donalds B. Johnson, no puedo entender el pseudo código (PARTE II)

votos
6

No puedo entender una cierta parte del documento publicado por Donald Johnson sobre la búsqueda de ciclos (circuitos) en un gráfico.

Más específica no puedo comprender lo que es la matriz Ak que se menciona en la siguiente línea de la pseudo código:

Ak: = estructura de adyacencia de fuerte componente K con menos vértice en subgrafo de G inducido por {s, s + 1, .... n};

para empeorar las cosas algunas líneas después de que se mentins para i en Vk hacer sin declarar lo que el Vk es ...

Por lo tengo comprender tenemos el siguiente: 1) en general, un fuerte componente es un sub-gráfico de un gráfico, en el que para cada nodo de este sub-gráfico hay un camino a cualquier nodo de la sub-gráfico ( en otras palabras, se puede acceder a cualquier nodo de la sub-gráfico de cualquier otro nodo de la sub-gráfico)

2) un sub-gráfico inducida por una lista de nodos es un gráfico que contiene todos estos nodos además de todos los bordes que conectan estos nodos. en papel de la definición matemática es F es un subgrafo de G inducido por W si W es subconjunto de V y F = (W, {u, y) | u, y en W y (u, y) en E)}) donde u, y son bordes, E es el conjunto de todos los bordes en el gráfico, W es un conjunto de nodos.

3) en la implementación del código de los nodos se denominan por números enteros 1 ... n.

4) Me sospecho que el Vk es el conjunto de nodos de la fuerte componente K.

ahora a la cuestión. Digamos que tenemos un gráfico G = (V, E) con V = {1,2,3,4,5,6,7,8,9} que se puede dividir en 3 componentes fuertes el SC1 = {1, 4,7,8} SC2 = {2,3,9} SC3 = {5,6} (y sus bordes)

Alguien me puede dar un ejemplo de s = 1, s = 2, s = 5, ¿y si va a ser el VK y Ak acuerdo con el código?

El pseudo código está en mi pregunta anterior en Entendiendo el pseudocódigo en el algoritmo de Donald B. Johnson

y el documento se puede encontrar en Entendiendo el pseudocódigo en el algoritmo de Donald B. Johnson

gracias de antemano

Publicado el 30/05/2010 a las 19:50
fuente por usuario
En otros idiomas...                            


4 respuestas

votos
10

¡Funciona! En una iteración anterior del algoritmo de Johnson , que había supuesto que Aera una matriz de adyacencia . En cambio, parece representar una lista de adyacencia . En ese ejemplo, implementada a continuación, los vértices {a, b, c} están numerados {0, 1, 2}, obteniéndose los siguientes circuitos.

Adición: Como se ha señalado en esta propuesta de edición y útil respuesta , el algoritmo se especifica que unblock()debe retirar el elemento que tiene el valor w , no el elemento que tiene el índice w .

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

Resultado de muestra:

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

Por defecto, el programa comienza con s = 0; implementar s := least vertex in Vcomo una optimización permanece. Una variación que produce sólo ciclos únicos se muestra aquí .

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;
            }
        }
    }
}
Respondida el 01/06/2010 a las 18:30
fuente por usuario

votos
1

Había sumbitted una edición solicitud de código de @ trashgod para fijar la excepción lanzada en unblock(). Esencialmente, el algoritmo dispone que el elemento w(que es no un índice) debe ser eliminado de la lista. El código de seguridad utilizado list.remove(w), que trata wcomo un índice.

Mi edición petición fue rechazada! No sé por qué, porque he probado lo anterior con mi modificación en una red de 20.000 y 70.000 nodos y bordes que no se desplome.

También he modificado el algoritmo de Johnson que se adapta más a grafos no dirigidos. Si alguien quiere estas modificaciones por favor, póngase en contacto conmigo.

A continuación se muestra el código para 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);
        }
    }
}
Respondida el 12/02/2013 a las 04:05
fuente por usuario

votos
1

@trashgod, a su salida de la muestra contiene ciclo que son permutación cíclica. Por ejemplo 0-1-0 y 1-0-1 son misma realidad la salida debe contiene sólo 5 ciclo es decir, 0 1 0, 0 2 0, 0 1 2 0, 0 2 1 0, 1 2 1,

Johnson papel explicar lo que un ciclo es: 'Dos circuitos elementales son distintos si uno no es una permutación cíclica de la otra. 'También se puede consultar la página de wolframio: Este ciclo también 5 de salida para la misma entrada.

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

Respondida el 08/04/2015 a las 12:14
fuente por usuario

votos
1

La siguiente variación produce ciclos únicos. Basándose en este ejemplo , que es una adaptación de una respuesta suministrada por @ user1406062 .

Código:

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

Salida:

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

Todos los ciclos, para la referencia:

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
Respondida el 10/03/2016 a las 14:09
fuente por usuario

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