transitiv Reduktionsalgorithmus: Pseudo-Code?

stimmen
30

Ich habe für einen Algorithmus gesucht, eine transitive Reduktion auf ein Diagramm zu erfüllen, aber ohne Erfolg. Es gibt nichts in meinem Algorithmen Bibel (Einführung in die Algorithmen von Cormen et al) und während ich habe viele transitive Schließung Pseudo-Code gesehen, ich habe es nicht gelungen, eine Reduktion auf die Spur etwas. Die nächstgelegene ich habe ist, dass es eine in „Algorithmische Graphentheorie“ von Volker Turau (ISBN: 978-3-486-59057-9), aber leider habe ich keinen Zugang zu diesem Buch! Wikipedia ist nicht hilfreich und Google ist noch etwas aufdrehen. : ^ (

Kennt jemand einen Algorithmus für eine transitive Reduktion durchführen?

Veröffentlicht am 06/11/2009 um 23:33
quelle vom benutzer
In anderen Sprachen...                            


7 antworten

stimmen
3

Der Wikipedia - Artikel über transitive Reduktion Punkte auf eine Implementierung innerhalb GraphViz (die Open Source). Nicht gerade Pseudo - Code, aber vielleicht irgendwo zu beginnen?

LEDA enthält einen transitiven Reduktionsalgorithmus . Ich habe nicht eine Kopie des LEDA Buchs mehr, und diese Funktion möglicherweise hinzugefügt wurde , nachdem das Buch veröffentlicht wurde. Aber wenn es da drin ist, dann wird es eine gute Beschreibung des Algorithmus sein.

Google verweist auf einen Algorithmus , der jemand für die Aufnahme in Boost - vorgeschlagen. Ich habe nicht versucht , es zu lesen, so korrigieren , vielleicht doch nicht?

Auch dies könnte sich lohnen, einen Blick zu .

Beantwortet am 07/11/2009 um 16:42
quelle vom benutzer

stimmen
7

Der grundlegende Kern des transitiven Reduktionsalgorithmus I verwendet wird,


foreach x in graph.vertices
   foreach y in graph.vertices
      foreach z in graph.vertices
         delete edge xz if edges xy and yz exist

Die transitive Schließung Algorithmus ich im selben Skript verwendet wird, ist sehr ähnlich, aber die letzte Zeile ist


         add edge xz if edges xy and yz OR edge xz exist
Beantwortet am 03/03/2010 um 15:49
quelle vom benutzer

stimmen
3

Der Algorithmus von „girlwithglasses“ vergisst, dass eine redundante Kante eine Kette von drei Kanten überspannen könnte. Zur Korrektur berechnen Q = R x R +, wobei R + ist die transitive Hülle und löscht dann alle Kanten von R, die in Q. zeigen Siehe auch Wikipedia-Artikel.

Beantwortet am 08/12/2010 um 20:42
quelle vom benutzer

stimmen
13

Siehe Harry Hsu. "Ein Algorithmus ein minimales äquivalentes Graphen eines Digraphen für die Suche.", Journal of the ACM, 22 (1): 11-16, Januar 1975. Der einfache kubische Algorithmus unten (unter Verwendung einer N x N-Pfad-Matrix) reicht für DAGs, aber Hsu verallgemeinert es zu zyklischen Graphen.

// reflexive reduction
for (int i = 0; i < N; ++i)
  m[i][i] = false;

// transitive reduction
for (int j = 0; j < N; ++j)
  for (int i = 0; i < N; ++i)
    if (m[i][j])
      for (int k = 0; k < N; ++k)
        if (m[j][k])
          m[i][k] = false;
Beantwortet am 15/07/2011 um 03:47
quelle vom benutzer

stimmen
1

Depth-First-Algorithmus in Pseudo-Python:

for vertex0 in vertices:
    done = set()
    for child in vertex0.children:
        df(edges, vertex0, child, done)

df = function(edges, vertex0, child0, done)
    if child0 in done:
        return
    for child in child0.children:
        edge.discard((vertex0, child))
        df(edges, vertex0, child, done)
    done.add(child0)

Der Algorithmus ist suboptimal, aber beschäftigt sich mit der Mehrkant Spannweiten Problem der bisherigen Lösungen. Die Ergebnisse sind sehr ähnlich zu dem, was tred von graphviz produziert.

Beantwortet am 28/06/2012 um 03:04
quelle vom benutzer

stimmen
3

Basierend auf dem Referenz bereitgestellt von Alan Donovan, die sagt man den Pfad-Matrix verwendet werden soll (die eine 1 hat, wenn es einen Pfad von Knoten i Knoten j) anstelle der Adjazenzmatrix (die nur eine 1 hat, wenn es eine Kante von Knoten Knoten i j).

Einige Beispiel Python-Code folgt unter die Unterschiede zwischen den Lösungen zu zeigen,

def prima(m, title=None):
    """ Prints a matrix to the terminal """
    if title:
        print title
    for row in m:
        print ', '.join([str(x) for x in row])
    print ''

def path(m):
    """ Returns a path matrix """
    p = [list(row) for row in m]
    n = len(p)
    for i in xrange(0, n):
        for j in xrange(0, n):
            if i == j:
                continue
            if p[j][i]:
                for k in xrange(0, n):
                    if p[j][k] == 0:
                        p[j][k] = p[i][k]
    return p

def hsu(m):
    """ Transforms a given directed acyclic graph into its minimal equivalent """
    n = len(m)
    for j in xrange(n):
        for i in xrange(n):
            if m[i][j]:
                for k in xrange(n):
                    if m[j][k]:
                        m[i][k] = 0

m = [   [0, 1, 1, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 1, 1],
        [0, 0, 0, 0, 1],
        [0, 1, 0, 0, 0]]

prima(m, 'Original matrix')
hsu(m)
prima(m, 'After Hsu')

p = path(m)
prima(p, 'Path matrix')
hsu(p)
prima(p, 'After Hsu')

Ausgabe:

Adjacency matrix
0, 1, 1, 0, 0
0, 0, 0, 0, 0
0, 0, 0, 1, 1
0, 0, 0, 0, 1
0, 1, 0, 0, 0

After Hsu
0, 1, 1, 0, 0
0, 0, 0, 0, 0
0, 0, 0, 1, 0
0, 0, 0, 0, 1
0, 1, 0, 0, 0

Path matrix
0, 1, 1, 1, 1
0, 0, 0, 0, 0
0, 1, 0, 1, 1
0, 1, 0, 0, 1
0, 1, 0, 0, 0

After Hsu
0, 0, 1, 0, 0
0, 0, 0, 0, 0
0, 0, 0, 1, 0
0, 0, 0, 0, 1
0, 1, 0, 0, 0
Beantwortet am 03/05/2013 um 12:16
quelle vom benutzer

stimmen
0

zu java / JGraphT, der Python-Probe auf dieser Seite von @ Michael Clerx portiert:

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.jgrapht.DirectedGraph;

public class TransitiveReduction<V, E> {

    final private List<V> vertices;
    final private int [][] pathMatrix;

    private final DirectedGraph<V, E> graph;

    public TransitiveReduction(DirectedGraph<V, E> graph) {
        super();
        this.graph = graph;
        this.vertices = new ArrayList<V>(graph.vertexSet());
        int n = vertices.size();
        int[][] original = new int[n][n];

        // initialize matrix with zeros
        // --> 0 is the default value for int arrays

        // initialize matrix with edges
        Set<E> edges = graph.edgeSet();
        for (E edge : edges) {
            V v1 = graph.getEdgeSource(edge);
            V v2 = graph.getEdgeTarget(edge);

            int v_1 = vertices.indexOf(v1);
            int v_2 = vertices.indexOf(v2);

            original[v_1][v_2] = 1;
        }

        this.pathMatrix = original;
        transformToPathMatrix(this.pathMatrix);
    }

    // (package visible for unit testing)
    static void transformToPathMatrix(int[][] matrix) {
        // compute path matrix 
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix.length; j++) { 
                if (i == j) {
                    continue;
                }
                if (matrix[j][i] > 0 ){
                    for (int k = 0; k < matrix.length; k++) {
                        if (matrix[j][k] == 0) {
                            matrix[j][k] = matrix[i][k];
                        }
                    }
                }
            }
        }
    }

    // (package visible for unit testing)
    static void transitiveReduction(int[][] pathMatrix) {
        // transitively reduce
        for (int j = 0; j < pathMatrix.length; j++) { 
            for (int i = 0; i < pathMatrix.length; i++) {
                if (pathMatrix[i][j] > 0){
                    for (int k = 0; k < pathMatrix.length; k++) {
                        if (pathMatrix[j][k] > 0) {
                            pathMatrix[i][k] = 0;
                        }
                    }
                }
            }
        }
    }

    public void reduce() {

        int n = pathMatrix.length;
        int[][] transitivelyReducedMatrix = new int[n][n];
        System.arraycopy(pathMatrix, 0, transitivelyReducedMatrix, 0, pathMatrix.length);
        transitiveReduction(transitivelyReducedMatrix);

        for (int i = 0; i <n; i++) {
            for (int j = 0; j < n; j++) { 
                if (transitivelyReducedMatrix[i][j] == 0) {
                    // System.out.println("removing "+vertices.get(i)+" -> "+vertices.get(j));
                    graph.removeEdge(graph.getEdge(vertices.get(i), vertices.get(j)));
                }
            }
        }
    }
}

Gerätetest :

import java.util.Arrays;

import org.junit.Assert;
import org.junit.Test;

public class TransitiveReductionTest {

    @Test
    public void test() {

        int[][] matrix = new int[][] {
            {0, 1, 1, 0, 0},
            {0, 0, 0, 0, 0},
            {0, 0, 0, 1, 1},
            {0, 0, 0, 0, 1},
            {0, 1, 0, 0, 0}
        };

        int[][] expected_path_matrix = new int[][] {
            {0, 1, 1, 1, 1},
            {0, 0, 0, 0, 0},
            {0, 1, 0, 1, 1},
            {0, 1, 0, 0, 1},
            {0, 1, 0, 0, 0}
        };

        int[][] expected_transitively_reduced_matrix = new int[][] {
            {0, 0, 1, 0, 0},
            {0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0},
            {0, 0, 0, 0, 1},
            {0, 1, 0, 0, 0}
        };

        System.out.println(Arrays.deepToString(matrix) + " original matrix");

        int n = matrix.length;

        // calc path matrix
        int[][] path_matrix = new int[n][n];
        {
            System.arraycopy(matrix, 0, path_matrix, 0, matrix.length);

            TransitiveReduction.transformToPathMatrix(path_matrix);
            System.out.println(Arrays.deepToString(path_matrix) + " path matrix");
            Assert.assertArrayEquals(expected_path_matrix, path_matrix);
        }

        // calc transitive reduction
        {
            int[][] transitively_reduced_matrix = new int[n][n];
            System.arraycopy(path_matrix, 0, transitively_reduced_matrix, 0, matrix.length);

            TransitiveReduction.transitiveReduction(transitively_reduced_matrix);
            System.out.println(Arrays.deepToString(transitively_reduced_matrix) + " transitive reduction");
            Assert.assertArrayEquals(expected_transitively_reduced_matrix, transitively_reduced_matrix);
        }
    }
}

Test ouput

[[0, 1, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 1, 1], [0, 0, 0, 0, 1], [0, 1, 0, 0, 0]] original matrix
[[0, 1, 1, 1, 1], [0, 0, 0, 0, 0], [0, 1, 0, 1, 1], [0, 1, 0, 0, 1], [0, 1, 0, 0, 0]] path matrix
[[0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1], [0, 1, 0, 0, 0]] transitive reduction
Beantwortet am 25/07/2015 um 14:31
quelle vom benutzer

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