Реализация алгоритма Флойда Уоршалла

Я написал код для матрицы смежности 100 x 100, которая представляет следующий ориентированный граф:

График магазина на углу

Я пытаюсь использовать алгоритм Флойда-Уоршалла, чтобы найти кратчайший путь для всех пар синих узлов на графике. Как найти кратчайший путь для всех пар только для выбранных узлов? Вот код, который я написал до сих пор:

public class AdjacencyMatrix
{       
    public static final int NUM_NODES = 100;
    public static final int INF = Integer.MAX_VALUE;
    
    public static boolean even(int num) 
    {
        return num%2==0;
    }

    public static boolean odd(int num) 
    {
        return num%2==1;
    }

    public static void initialize(int [][] adjMat, int N) 
    {
        for(int i = 0; i < N; i++)
            for(int j = 0; j <N; j++)
                adjMat[i][j]=INF;

        for(int x = 0; x<N; x++)
        {
            int row = x/10;
            int column = x%10;

            if (even(row)) {
                if (column!=9)
                    adjMat[x][x+1]=1;
            }
            if (odd(row)) {
                if (column!=0)
                    adjMat[x][x-1]=1;
            }
            if (even(column)){
                if (row!=9)
                    adjMat[x][x+10]=1;
            }
            if (odd(column)) {
                if (row!=0)
                    adjMat[x][x-10]=1;
            }
        }
    }
    
    public void floydWarshall(int[][] adjMat, int N)
    {
    	adjMat = new int[N][N];
	    initialize(adjMat, NUM_NODES);

        for(int k = 0; k < N; ++k) {
           for(int i = 0; i < N; ++i) {
              for(int j = 0; j < N; ++j) {
                 adjMat[i][j] = Math.min(adjMat[i][j], adjMat[i][k] +   adjMat[k][j]);
    }
}
}

    }

    public static void main(String[] args)
    {

        int adjMat[][] = new int[NUM_NODES][NUM_NODES];
        initialize(adjMat, NUM_NODES);
        
        int A,B,C,D,E,F,G,H,I,W;
        
        A = 20;
        B = 18;
        C = 47;
        D = 44;
        E = 53;
        F = 67;
        G = 95;
        H = 93;
        I = 88;
        W = 66;
       
        System.out.println(adjMat[A][B]);

        System.out.println();
    }
}


person Nate    schedule 05.03.2017    source источник
comment
Не похоже, что вы что-то отменили.   -  person Nate    schedule 06.03.2017


Ответы (2)


Прежде всего, вам не следует назначать новое значение параметру adjMat в floydWarshall (), потому что значение не будет сохранено после выхода из метода.

Следующим шагом будет проверка adjMat [i] [k] и adjMat [k] [j] на равенство INF и продолжение цикла, если это так:

for(int k = 0; k < N; ++k) {
   for(int i = 0; i < N; ++i) {
      for(int j = 0; j < N; ++j) {
        if (adjMat[i][k] != INF && adjMat[k][j] != INF) {
            adjMat[i][j] = Math.min(adjMat[i][j], adjMat[i][k] + adjMat[k][j]);
        }            
person Nolequen    schedule 06.03.2017

Кратчайшая реализация алгоритма Флойда-Уоршалла:

for(int k = 0; k < N; ++k) {
    for(int i = 0; i < N; ++i) {
        for(int j = 0; j < N; ++j) {
            adjMat[i][j] = Math.min(adjMat[i][j], adjMat[i][k] + adjMat[k][j]);
        }
    }
}

После запуска этот фрагмент кадра adjMat будет содержать кратчайшие расстояния между каждой парой узлов.

Обновление: чтобы избежать целочисленного переполнения, заполните матрицу Integer.MAX_VALUE / 2. В общем случае устанавливать для переменной максимально возможное значение как бесконечность опасно, потому что с ней нельзя выполнить операцию сложения.

person Andreikkaa    schedule 05.03.2017
comment
Я добавил ваш код в метод floydWarshall (), но он выводит матрицу всех нулей. - person Nate; 06.03.2017
comment
Я все еще не могу заставить этот код выводиться должным образом. Похоже, логика верна, поэтому я не уверен, что не так. - person Nate; 06.03.2017
comment
Я не знаком с java, но будет ли выполнено переполнение adjMat [i] [k] + adjMat [k] [j], если одним термином является Intmax? - person Petar Petrovic; 06.03.2017
comment
Вы должны помнить, что сначала необходимо очистить матрицу. Первый шаг - установить все значения матрицы на бесконечность (очень большое значение), а затем установить все диагональные значения на 0. Это должно сработать: for(int i = 0; i < size; i++) for(int j = 0; j < size; j++) M[i][j] = (i == j? 0 : 99999999);, затем вы запустите алгоритм FW, как описано выше. - person Daniel; 06.03.2017
comment
Не совсем, я работаю с матрицей, которая представляет собой график. - person Andreikkaa; 07.03.2017