Алгоритм Дейкстра/ ошибка - Free Pascal

Узнай цену своей работы

Формулировка задачи:

Не проходит некоторые тесты в задаче, где нужно найти кратчайший путь от 1-ой вершины неориентированного графа в n-ую. В чём же тут ошибка?
var max,gr,x,y,z,j,i,n,m:longint;
a:array[1..1000,1..1000] of longint;
d,v:array[1..1000] of longint;
BEGIN
readln(n,m);
for i:=1 to m do begin
readln(x,y,z);
if a[x,y]=0 then a[x,y]:=z else if z<a[x,y] then a[x,y]:=z;
if a[y,x]=0 then a[y,x]:=z else if z<a[y,x] then a[y,x]:=z;
end;
i:=1;
while gr<n do begin
for j:=1 to n do
if (d[j]=0) and (v[j]=0) and(a[i,j]>0) then d[j]:=d[i]+a[i,j] else if (d[i]+a[i,j]<d[j]) and (v[j]=0) and (a[i,j]>0) then d[j]:=a[i,j]+d[i];
inc(v[i]);
inc(gr);
max:=maxlongint;
for j:=1 to n do
if (d[j]<=max) and (v[j]=0) then begin max:=d[j]; i:=j; end;
end;
for j:=1 to n do
writeln(d[n]);
end.

Решение задачи: «Алгоритм Дейкстра/ ошибка»

textual
Листинг программы
{
V - множество вершин графа (vertex)
E - множество рёбер графа
w[i,j] - вес (длина) ребра ij
a - вершина, расстояния от которой ищутся
U - множество посещённых вершин (used)
d[u] - по окончании работы алгоритма равно
       длине кратчайшего пути из a до вершины u (distance)
p[u] - по окончании работы алгоритма содержит кратчайший путь из a в u
       (предшествующий u элемент, previous)
}
program Dijkstra;
 
const
  INFINITY  = MaxInt;
  UNDEFINED = -1;
 
const
  Nmax = 6;
type
  TMatrix = array[0..Nmax - 1, 0..Nmax - 1] of integer;
  TVertexList = array[0..Nmax - 1] of integer;
  TDistance = array[0..Nmax - 1] of integer;
  TUsed = array[0..Nmax - 1] of boolean;
 
  function MinOf(const a: TDistance; const m: TUsed): integer;
  var
    i: integer;
    Imin: integer;
    Min: integer;
  begin
    i := low(a);
    while i <= high(a) do
    begin
      if not m[i] then
      begin
        Imin := i;
        Min  := a[i];
        break;
      end;
      inc(i);
    end;
    for i := Imin + 1 to high(a) do
      if (Min > a[i]) and not m[i] then
      begin
        Imin := i;
        Min  := a[i];
      end;
    MinOf := Imin;
  end;
 
  procedure DijkstrasAlgorithm(const W: TMatrix; a: integer;
  var D: TDistance; var P: TVertexList);
  var
    v: integer;
    U: TUsed;
    i, j: integer;
  begin
    {initialization    
      d[a]:=0; p[a]:=0;
      d[v]:=INFINITY; p[v]:=UNDEFINED; для всех вершин отличных от a
    }
    for v := low(D) to high(D) do
    begin
      if v = a then
      begin
        D[v] := 0;
        P[v] := UNDEFINED;
      end
      else
      begin
        D[v] := INFINITY;
        P[v] := UNDEFINED;
      end;
      U[v] := False;
    end;
    {основной цикл}
    for i := low(D) to high(D) do {пока есть нерассмотренные вершины}
    begin
      v := MinOf(D, U); {берём непосещённую вершину с минимальным d[v]}
      U[v] := True;     {отмечаем её как посещённую}
      for j := low(D) to high(D) do
        if W[v, j] <> INFINITY then
          if D[j] > D[v] + W[v, j] then
          begin
            D[j] := D[v] + W[v, j];
            P[j] := v;
          end;
    end;
  end;
 
  procedure ShowPath(A, B: integer; const P: TVertexList; const D: TDistance);
  var
    Q: TVertexList;
    Len: integer;
    v: integer;
  begin
    Len := 0;
    if D[B] = INFINITY then
      writeln('There is not exist path from ', A, ' to ', B, '.')
    else
    begin
      v := B;
      repeat
        Q[Len] := v;
        Inc(Len);
        v := P[v];
      until v=UNDEFINED;
      write('A path from ', A, ' to ', B, ' is <');
      for v := Len - 1 downto 0 do
        Write(Q[v]: 4);
      writeln('>.');
    end;
  end;
 
var
  W: TMatrix =
  (
    (00, 07, 09, 00, 00, 14),
    (07, 00, 10, 15, 00, 00),
    (09, 10, 00, 11, 00, 02),
    (00, 15, 11, 00, 06, 00),
    (00, 00, 00, 06, 00, 09),
    (14, 00, 02, 00, 09, 00)
  );
var
  i, j: integer;
  P: TVertexList;
  D: TDistance;
  A, B: integer;
begin
  {для упрощения ввода вместо INFINITY в матрице весов W я использовал нули
   Поэтому нужно удалить нули из матрицы весов, заменив их на бесконечность}
  for i := 0 to Nmax - 1 do
    for j := 0 to Nmax - 1 do
      if (i <> j) and (W[i, j] = 0) then
        W[i, j] := INFINITY;
  {Ввод начальной и конечной точек маршрута}
  A := 0;
  B := 4;
  {Обработка графа по алгоритму Дейкстры}
  DijkstrasAlgorithm(W, A, D, P);
  {контрольный вывод значений результирующих массивов}
  write('Distance: ');
  for i := low(D) to high(D) do
    Write(D[i]: 4);
  writeln;
  write('Previous: ');
  for i := low(P) to high(P) do
    Write(P[i]: 4);
  writeln;
  {вывод вершин по кратчайшему пути из A в B}
  ShowPath(A, B, P, D);
end.

Объяснение кода листинга программы

{ V - множество вершин графа (vertex) E - множество рёбер графа w[i,j] - вес (длина) ребра ij a - вершина, расстояния от которой ищутся U - множество посещённых вершин (used) d[u] - по окончании работы алгоритма равно       длине кратчайшего пути из a до вершины u (distance) p[u] - по окончании работы алгоритма содержит кратчайший путь из a в u       (предшествующий u элемент, previous) } В данном коде реализован алгоритм Дейкстры для поиска кратчайшего пути между двумя вершинами графа. Алгоритм работает следующим образом:

  1. Инициализация:   - Значения d[a] и p[a] устанавливаются равными 0, что означает, что начальная вершина уже достигнута и является конечной точкой кратчайшего пути.   - Для всех вершин, не равных a, значения d[v] устанавливаются равными INFINITY, что означает, что из этих вершин путь не найден. Значения p[v] устанавливаются равными UNDEFINED, что означает, что предшествующая вершина для этих вершин не найдена.
  2. Основной цикл:   - На каждой итерации алгоритма выбирается вершина v с минимальным значением d[v].   - Вершина v помечается как посещённая (U[v] := True).   - Для каждой вершины j, смежной с v, проверяется, если d[j] больше d[v] + w[v, j], то обновляются значения d[j] и p[j] с учётом нового пути через v.
  3. Вывод:   - Выводятся значения d[u] для всех вершин графа.   - Выводится путь из начальной вершины a в конечную вершину B. В данном коде используются следующие константы:
    • INFINITY - максимальное значение расстояния в графе.
    • UNDEFINED - значение, которое получает переменная, если для вершины не найден путь.
    • Nmax - количество вершин в графе. В данном коде определены следующие типы и переменные:
    • TMatrix - массив, представляющий собой взвешенный граф.
    • TVertexList - массив, содержащий номера вершин графа.
    • TDistance - массив, содержащий значения расстояний от начальной вершины до всех остальных вершин графа.
    • TUsed - массив, содержащий логические значения, указывающие, была ли вершина посещена во время выполнения алгоритма.
    • MinOf - функция, которая находит вершину с минимальным значением d[v] среди не посещённых вершин.
    • DijkstrasAlgorithm - процедура, которая реализует алгоритм Дейкстры для поиска кратчайшего пути от начальной вершины до всех остальных вершин графа.
    • ShowPath - процедура, которая выводит путь из начальной вершины в конечную вершину. В данном коде используются следующие значения:
    • A и B - начальная и конечная вершины соответственно.
    • W - матрица весов ребер графа.
    • P - массив, содержащий предшествующие вершины для каждой вершины графа.
    • D - массив, содержащий значения расстояний от начальной вершины до всех остальных вершин графа. В данном коде выполняются следующие действия:
    • Инициализация переменных d[a] и p[a].
    • Инициализация массива U[v] для всех вершин графа.
    • Выполнение алгоритма Дейкстры для поиска кратчайшего пути от начальной вершины до всех остальных вершин графа.
    • Вывод значений d[u] для всех вершин графа.
    • Вывод пути из начальной вершины в конечную вершину.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 3.667 из 5
Похожие ответы