Geçişli azaltma algoritması: yalancı kod?

oy
30

Ben ancak başarılı olamadı, bir grafik üzerinde bir geçişli azaltma gerçekleştirmek için bir algoritma arayan edilmiştir. Benim algoritmalar İncil (Tanıtım için Cormen ve arkadaşları tarafından Algoritmalar) ve geçişli kapatma pseudocode bol gördüğümüz iken bir şey yok, ben azaltılması için bir şey izini edemedik. Bende en yakın Volker Turau (ISBN: 978-3-486-59057-9) tarafından Algorithmische Graphentheorie bir olduğunu, ancak ne yazık ki bu kitaba erişimi yok! Vikipedi yararsızdır ve Google şey açmak için henüz. : ^ (

Herkes bir geçişli azalma gerçekleştirmek için bir algoritma biliyor mu?

Oluştur 06/11/2009 saat 23:33
kaynak kullanıcı
Diğer dillerde...                            


7 cevaplar

oy
3

Wikipedia makalesi (açık kaynak) GraphViz içinde uygulamaya geçişli azaltma noktalarında. Tam olarak yalancı kod, ama belki bir yere başlatmak için?

LEDA bir içermektedir geçişli azaltma algoritması . Ben bir kopyası yoksa LEDA kitapta artık ve kitap yayınlandıktan sonra bu fonksiyon eklenmiş olabilir. Orası Ama eğer, o zaman algoritmanın iyi bir açıklama olacaktır.

Google işaret eden bir algoritma birileri Boost eklenmek üzere önerdi. Ben okumak çalışmayın, belki düzeltmedik?

Ayrıca, bu bakmaya değer olabilir.

Cevap 07/11/2009 saat 16:42
kaynak kullanıcı

oy
7

Kullandığım Geçişli azaltma tekniğinin ana esası olan


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

Aynı senaryo kullanılan Geçişli kapatma algoritması çok benzer ama geçen çizgidir


         add edge xz if edges xy and yz OR edge xz exist
Cevap 03/03/2010 saat 15:49
kaynak kullanıcı

oy
3

"Girlwithglasses" bir algoritma bir artık kenar üç kenarın bir zincirini içerir ki unutur. düzeltmek için, işlem Q = Rx R + R + geçişli kapanma ve daha sonra da Ara makalesine bakın Q görünür R bütün kenarları silin.

Cevap 08/12/2010 saat 20:42
kaynak kullanıcı

oy
13

Harry Hsu bakın. "Bir digraf az bir eşdeğer grafik bulmak için bir algoritma.", ACM Dergisi, 22 (1): 11-16 Ocak 1975 (bir N x N yolu matrisi kullanılarak), aşağıdaki basit kübik algoritması, DAG için yeterli ancak Hsu siklik grafikler için genelleştirilmiş.

// 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;
Cevap 15/07/2011 saat 03:47
kaynak kullanıcı

oy
1

Derinlik öncelikli sözde python algoritma:

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)

algoritma optimal altı olmakla birlikte, önceki çözümlerin çok kenarlı açıklıklı bir sorun ile ilgilidir. Sonuçlar graphviz üretir gelen tred ne çok benzer.

Cevap 28/06/2012 saat 03:04
kaynak kullanıcı

oy
3

(I j düğümden düğüme bir yol olup olmadığını, bir 1 vardır) Yolun matris kullanmak gerektiğini söyler Alan Donovan tarafından sağlanan referans göre yerine 1 sahiptir bitişiklik matrisi (bir kenar yoktur, sadece düğümden i) j düğüm.

Bazı örnek piton kod çözümleri arasındaki farklılıkları göstermek için aşağıdaki izler

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

Çıktı:

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
Cevap 03/05/2013 saat 12:16
kaynak kullanıcı

oy
0

java / jgrapht, @Michael Clerx bu sayfadaki piton numunesi taşıdık:

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

ünite testi :

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 çıkışına

[[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
Cevap 25/07/2015 saat 14:31
kaynak kullanıcı

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