transitief reductie algoritme: pseudocode?

stemmen
30

Ik ben al op zoek naar een algoritme om een ​​transitieve korting op een grafiek uit te voeren, maar zonder succes. Er is niets in mijn algoritmen bijbel (Introduction To Algorithms door Cormen et al) en hoewel ik heb tal van transitieve afsluiting pseudocode gezien, heb ik niet in staat op te sporen om het even wat voor een verlaging geweest. Het dichtst ik heb is dat er één in Algorithmische Graphentheorie door Volker Toeraw (ISBN: 978-3-486-59057-9), maar helaas heb ik geen toegang tot dit boek te hebben! Wikipedia is nutteloos en Google is nog niet opdagen niets. : ^ (

Weet iemand van een algoritme voor het uitvoeren van een transitieve vermindering?

De vraag is gesteld op 06/11/2009 om 23:33
bron van user
In andere talen...                            


7 antwoorden

stemmen
3

Het artikel van Wikipedia op transitieve vermindering wijst op een implementatie binnen GraphViz (die open source). Niet precies pseudocode, maar misschien ergens te beginnen?

LEDA is voorzien van een transitieve vermindering algoritme . Ik heb geen exemplaar van het hebben LEDA boek meer, en deze functie zou kunnen zijn toegevoegd na het boek werd gepubliceerd. Maar als het er in zit, dan zal er een goede beschrijving van het algoritme zijn.

Google wijst op een algoritme dat iemand voorgesteld voor opname in Boost. Ik heb niet geprobeerd om het te lezen, dus misschien niet?

Ook dit misschien een kijkje waard.

antwoordde op 07/11/2009 om 16:42
bron van user

stemmen
7

De fundamentele kern van de transitieve reductiealgoritme I gebruikte


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

De transitieve afsluiting algoritme dat ik in hetzelfde script is zeer vergelijkbaar, maar de laatste regel is


         add edge xz if edges xy and yz OR edge xz exist
antwoordde op 03/03/2010 om 15:49
bron van user

stemmen
3

Het algoritme van "girlwithglasses" vergeet dat een redundante rand een keten van drie randen kunnen omvatten. Te corrigeren, compute Q = R x R + waarbij R + is de transitieve afsluiting en verwijder alle randen van R die worden weergegeven in Q. Zie ook het artikel Wikipedia.

antwoordde op 08/12/2010 om 20:42
bron van user

stemmen
13

Zie Harry Hsu. "Een algoritme voor het vinden van een minimum gelijk grafiek van een digraph.", Journal of the ACM, 22 (1): 11-16, januari 1975. De eenvoudige kubieke algoritme beneden (met een NxN-matrix path) volstaat voor DAG's, maar Hsu veralgemeent aan cyclische grafieken.

// 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;
antwoordde op 15/07/2011 om 03:47
bron van user

stemmen
1

Diepte-eerste algoritme 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)

Het algoritme niet optimaal, maar behandelt multi-edge overspanningen probleem van de eerdere oplossingen. De resultaten zijn zeer vergelijkbaar met wat tred van graphviz produceert.

antwoordde op 28/06/2012 om 03:04
bron van user

stemmen
3

Gebaseerd op de verwijzing door Alan Donovan, die zegt moet het pad matrix gebruiken (die een 1 heeft als er een pad van knoop i tot knoop j) plaats van de adjacentiematrix (die een 1 heeft indien er een rand van knoop i tot knoop j).

Enkele voorbeelden python code volgt hieronder om de verschillen tussen de oplossingen tonen

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')

Output:

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
antwoordde op 03/05/2013 om 12:16
bron van user

stemmen
0

geport naar java / jgrapht, de python monster op deze pagina via @Michael Clerx:

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

hoofdstuk toets :

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 output

[[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
antwoordde op 25/07/2015 om 14:31
bron van user

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