μεταβατικό αλγόριθμο μείωσης: ψευδοκώδικα;

ψήφοι
30

Έχω ήδη ψάχνει για έναν αλγόριθμο για να εκτελέσει μια μείωση μεταβατικό σε ένα γράφημα, αλλά χωρίς επιτυχία. Δεν υπάρχει τίποτα σε αλγόριθμους μου Αγία Γραφή (Εισαγωγή στην Αλγόριθμοι από Cormen κ.ά.) και ενώ έχω δει πολλές ψευδοκώδικα κλείσιμο μεταβατική, δεν ήταν σε θέση να εντοπίσουμε τίποτα για τη μείωση. Το πιο κοντινό έχω είναι ότι υπάρχει μία στις «Algorithmische Graphentheorie» του Volker Turau (ISBN: 978-3-486-59057-9), αλλά δυστυχώς δεν έχω πρόσβαση σε αυτό το βιβλίο! Η Wikipedia είναι άχρηστες και η Google δεν έχει ακόμη εμφανιστεί τίποτα. : ^ (

Ξέρει κανείς από έναν αλγόριθμο για την εκτέλεση μεταβατική μείωση;

Δημοσιεύθηκε 06/11/2009 στις 23:33
πηγή χρήστη
Σε άλλες γλώσσες...                            


7 απαντήσεις

ψήφοι
3

Το άρθρο της Wikipedia για μεταβατική σημεία μείωση σε εφαρμογή εντός GraphViz (που είναι open source). Όχι ακριβώς ψευδοκώδικας, αλλά ίσως κάπου να ξεκινήσετε;

LEDA περιλαμβάνει μια μεταβατική αλγόριθμο μείωσης . Δεν έχω ένα αντίγραφο του βιβλίου LEDA πια, και αυτή η λειτουργία μπορεί να έχουν προστεθεί μετά εκδόθηκε το βιβλίο. Αλλά αν είναι εκεί, τότε θα υπάρξει μια καλή περιγραφή του αλγορίθμου.

Η Google οδηγεί σε έναν αλγόριθμο που κάποιος προταθεί για ένταξη στο Boost. Δεν προσπάθησα να το διαβάσετε, οπότε ίσως να μην διορθώσει;

Επίσης, αυτό μπορεί να αξίζει μια ματιά.

Απαντήθηκε 07/11/2009 στις 16:42
πηγή χρήστη

ψήφοι
7

Η βασική ουσία της μεταβατικό αλγόριθμο μείωσης που χρησιμοποιείται είναι


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

Το μεταβατικό αλγόριθμος κλεισίματος που χρησιμοποιούνται κατά τον ίδιο σενάριο είναι πολύ παρόμοια, αλλά η τελευταία γραμμή είναι


         add edge xz if edges xy and yz OR edge xz exist
Απαντήθηκε 03/03/2010 στις 15:49
πηγή χρήστη

ψήφοι
3

Ο αλγόριθμος της «girlwithglasses» ξεχνά ότι μια περιττή ακμή θα μπορούσε να εκτείνονται σε μια αλυσίδα από τρία άκρα. Για να διορθώσετε, υπολογίζουν Q = R x R +, όπου το R + είναι το μεταβατικό κλείσιμο και στη συνέχεια να διαγράψετε όλες τις άκρες από το R που εμφανίζονται στο Q. Δείτε επίσης το άρθρο της Wikipedia.

Απαντήθηκε 08/12/2010 στις 20:42
πηγή χρήστη

ψήφοι
13

Δείτε Χάρι Hsu. «Ένας αλγόριθμος για την εύρεση μια ελάχιστη ισοδύναμη γράφημα ενός δίγραμμα.», Journal of the ACM, 22 (1): 11-16, Ιανουάριος 1975. Η απλή κυβικά αλγόριθμος παρακάτω (χρησιμοποιώντας ένα Ν χ Ν μήτρα διαδρομή) αρκεί για ΚΑΓ, αλλά Hsu γενικεύει σε κυκλικές γραφικές παραστάσεις.

// 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;
Απαντήθηκε 15/07/2011 στις 03:47
πηγή χρήστη

ψήφοι
1

Βάθος πρώτο αλγόριθμο σε ψευδο-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)

Ο αλγόριθμος δεν είναι το καλύτερο, αλλά ασχολείται με το πρόβλημα multi-άκρη διάρκεια των προηγούμενων λύσεων. Τα αποτελέσματα είναι πολύ παρόμοιο με αυτό που TRED από GraphViz παράγει.

Απαντήθηκε 28/06/2012 στις 03:04
πηγή χρήστη

ψήφοι
3

Με βάση την αναφοράς που παρέχεται από τον Alan Donovan, το οποίο λέει θα πρέπει να χρησιμοποιήσετε τη μήτρα διαδρομή (η οποία έχει ένα 1 αν υπάρχει ένα μονοπάτι από τον κόμβο i στον κόμβο j) αντί του πίνακας γειτνίασης (το οποίο έχει ένα 1 μόνο εάν υπάρχει μία ακμή από τον κόμβο i στον κόμβο j).

Μερικά κώδικα python δείγμα ακολουθεί παρακάτω, για να δείξει τις διαφορές μεταξύ των λύσεων

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

Παραγωγή:

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
Απαντήθηκε 03/05/2013 στις 12:16
πηγή χρήστη

ψήφοι
0

μεταφερθεί και σε java / jgrapht, το δείγμα πύθωνα σε αυτή τη σελίδα από @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)));
                }
            }
        }
    }
}

δοκιμή μονάδα:

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

δοκιμή φωτεινότητά

[[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
Απαντήθηκε 25/07/2015 στις 14:31
πηγή χρήστη

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