алгоритм редукции транзитивно: псевдокод?

голоса
30

Я ищу алгоритм для выполнения сокращения переходного на графике, но без успеха. Там нет ничего в моих алгоритмах библии (Введение в алгоритмах по Cormen и др) и в то время как я видел много транзитивного замыкание псевдокода, я не был в состоянии разыскать что-нибудь для сокращения. Ближайший я получил то, что есть один в «Algorithmische Graphentheorie» Фолькер Туровского (ISBN: 978-3-486-59057-9), но, к сожалению, у меня нет доступа к этой книге! Википедия не приносит никакой пользы и Google еще оказаться что угодно. : ^ (

Кто-нибудь знает алгоритм для выполнения переходного сокращения?

Задан 06/11/2009 в 23:33
источник пользователем
На других языках...                            


7 ответов

голоса
3

Статья Википедии на переходных точках сокращения к реализации в рамках GraphViz (который является открытым исходным кодом). Не совсем псевдокод, но , может быть , где - нибудь начать?

ЛЕДА включает в себя алгоритм снижения переходного . Я не имею копию книги ЛЬДА больше, и эта функция может быть добавлена после того, как книга была опубликована. Но если это там, то будет хорошее описание алгоритма.

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 х R +, где R + является транзитивным замыканием, а затем удалить все ребра из R, которые показывают в Q. Смотрите также статью в Википедии.

Ответил 08/12/2010 в 20:42
источник пользователем

голоса
13

См Гарри Хсу. «Алгоритм нахождения минимального эквивалентный графика орграфа.», Журнал ACM, 22 (1): 11-16, январь 1975 г. Простой кубический алгоритм ниже (с использованием N х N матрицы пути) достаточно для групп DAG, но Хсу обобщает его циклических графов.

// 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

Глубина первого алгоритма в псевдо-питона:

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)

Алгоритм неоптимальный, но имеет дело с проблемой мульти-краем пролетом предыдущих решений. Результаты очень похожи на то, что тред от Graphviz производит.

Ответил 28/06/2012 в 03:04
источник пользователем

голоса
3

На основании справки, предоставленной Alan Донована, который говорит, что вы должны использовать матрицу пути (который имеет значение 1, если существует путь от узла я к узлу J) вместо матрицы смежности (который имеет 1, только если есть ребро от узла к узлу я 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);
        }
    }
}

тест 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
Ответил 25/07/2015 в 14:31
источник пользователем

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