Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [Pascal] Поиск кратчайшего пути в графе


Автор: Kubus 18.7.2006, 16:13
Приветствую!
Требуется помощь в написании программы!
В заданном графе найти кратчайший путь от одной вершины к другой и найти все пути между этими вершинами, не пересекающиеся по вершинам. Так звучит задание. Пояснений по поводу способов решения не было. Может у кого-то завалялся код, или кто-нибудь возьмется сделать с нуля, в любом случае, буду очень признателен! 

Автор: comtat 18.7.2006, 16:17
могу предложить 
1. Алгоритм Дейкcтры задачи о кратчайших путях
2. Алгоритм Беллмана-Форда задачи о кратчайших путях.
3. Алгоритм Флойда задачи о кратчайших путях (Delphi)

Выбор за вами сударь   smile  

Автор: Kubus 18.7.2006, 16:29
К сожалению, я не знаю, чем они отличаются! В соседней теме я писал, что у меня большие проблемы с доступом в интернет, посему оперативно сунуться в лекции по теории графов нет возможности! Я постараюсь разобрать алгоритмы сегодня и выйти онлайн, или же на ваш выбор, Comtat. А я уж буду исходить из этого выбора и разбираться. 

Автор: comtat 18.7.2006, 16:44
алгоритм Дейкстры
Код

{Dijkstra's algorithm}
var a : array [1..20,1..20] of word;
    c, pred : array [1..20] of word;
    i, j, k, n, first, last, jn, kn : byte;
    f, g : text;
    min : word;
begin
     assign(f,'in.txt');
     reset(f);
     readln(f, n);
     for i := 1 to n do
     begin
          for j := 1 to n do
          read(f, a[i,j]);
          readln(f);
     end;
     readln(f, first, last);
     close(f);

     min := 32767;
     for j := 1 to n do
         if a[first,j] < min then begin min := a[first,j];jn := j;end;
     c[jn] := min;pred[jn] := first;
     j := jn;
     for i := 2 to n do
     begin
         min := 32767;
         for j := 1 to n do
         if c[j] <> 0 then
         begin
               for k := 1 to n do
               if (c[j] + a[j,k] < min)and(c[k] = 0) then begin min := c[j] + a[j,k];jn := j;kn := k;end;
         end;
         c[kn] := min;pred[kn] := jn;
     end;


     assign(g,'out.txt');
     rewrite(g);
     if c[last] = 32767 then writeln(g,'N') else
     begin
          writeln(g,'Y');
          write(g,first,' ');
          i := last;k := 1;
          while i <> first do
          begin
               a[1,k] := i;
               k := k + 1;
               i := pred[i];
          end;
          for i := k - 1 downto 1 do
          write(g,a[1,i],' ');
          writeln(g);
          writeln(g,c[last]);
     end;
     close(g);
end.


пример входного файла
Цитата
9
32767 6 32767 32767 1 32767 32767 32767 32767
32767 32767 32767 32767 32767 32767 3 32767 32767
32767 1 32767 32767 32767 32767 32767 32767 32767
4 32767 32767 32767 32767 32767 32767 32767 32767
32767 32767 32767 7 32767 7 32767 5 32767
32767 5 2 32767 32767 32767 32767 32767 32767
32767 32767 32767 2 32767 32767 32767 32767 32767
32767 32767 32767 10 32767 32767 32767 32767 32767
32767 32767 32767 32767 32767 1 32767 8 32767
9 1

32767 это типа бесконечность 

Автор: comtat 19.7.2006, 13:06
Алгоритм Беллмана-Форда
Код

{Bellman-Ford algorithm}
var a : array [1..20,1..20] of word;
    c, pred : array [1..20] of word;
    i, j, k, n, first, last : byte;
    f, g : text;
begin
     assign(f,'in.txt');
     reset(f);
     readln(f, n);
     for i := 1 to n do
     begin
          for j := 1 to n do
          read(f, a[i,j]);
          readln(f);
     end;
     readln(f, first, last);
     close(f);


     for j := 1 to n do
     begin
          c[j] := a[first,j];if a[first,j] < 32767 then pred[j] := first;
     end;

     for i := 3 to n do
         for j := 1 to n do
             if j <> first then
             for k := 1 to n do
                 if (c[k] < 32767) and (c[k] + a[k,j] < c[j]) then begin c[j] := c[k] + a[k,j];pred[j] := k;end;

     assign(g,'out.txt');
     rewrite(g);
     if c[last] = 32767 then writeln(g,'N') else
     begin
          writeln(g,'Y');
          write(g,first,' ');
          i := last;k := 1;
          while i <> first do
          begin
               a[1,k] := i;
               k := k + 1;
               i := pred[i];
          end;
          for i := k - 1 downto 1 do
          write(g,a[1,i],' ');
          writeln(g);
          writeln(g,c[last]);
     end;
     close(g);
end.

Входной файл аналочично как у Белмана  smile  

Автор: Kubus 24.7.2006, 21:15
а здесь можно в матрицу смежности вбивать единици и нули? я возьму алгоритм Белмана-Форда. Не подскажешь, как сделать, чтоб на выходе была последовательность номеров вершин кратчайшего пути? 

Автор: Kubus 25.7.2006, 06:28
вот есть код
Код

const
  maxn = 250;

const
  queue_size = maxn;

type
  item = integer;

  queue = record
    a: array [0..queue_size] of item;
    head, tail: integer;
  end;

procedure init_queue(var q: queue);
begin
  q.head := 0;
  q.tail := 0;
end;

procedure push_to_queue(var q: queue; x: item);
begin
  with q do
  begin
    a[tail] := x;
    tail := (tail + 1) mod queue_size;
  end;
end;

function pop_from_queue(var q: queue): item;
begin
  with q do
  begin
    pop_from_queue := a[head];
    head := (head + 1) mod queue_size;
  end;
end;

function is_queue_empty(const q: queue): boolean;
begin
  is_queue_empty := q.head = q.tail;
end;

function get_queue_top(const q: queue): item;
begin
  get_queue_top := q.a[q.head];
end;


var
  a: array [1..maxn, 1..maxn] of boolean;
  p: array [1..maxn] of integer;
  q: queue;
  visited: array [1..maxn] of boolean;
  n, c: longint;

procedure init;
var
  i, x, y, nn: longint;
begin
  fillchar(a, sizeof(a), false);
  fillchar(p, sizeof(p), 0);
  fillchar(visited, sizeof(visited), false);
  c := 1;

  assign(input, 'graph.in');
  reset(input);

  read(n);
  read(nn);

  for i := 1 to nn do
  begin
    read(x, y);
    a[x, y] := true;
    a[y, x] := true;                    { ¥á«¨ ­¥®à¨¥­â¨à®¢ ­­ë© £à ä }
  end;
end;

procedure print;
var
  i, j: integer;
begin
  writeln;
  writeln('number of vertex : ', n);
  writeln('adjacency matrix');
  for i := 1 to n do
  begin
    for j := 1 to n do
      write(ord(a[i, j]));
    writeln;
  end;
end;

procedure bfs(v: longint);
var
  i: integer;
begin
  init_queue(q);
  push_to_queue(q, v);
  p[v] := 0;
  inc(c);
  visited[v] := true;

  while not is_queue_empty(q) do
  begin
    v := pop_from_queue(q);
    for i := 1 to n do
      if a[v, i] and not visited[i] then
      begin
        p[i] := v;
        visited[i] := true;
        push_to_queue(q, i);
      end;
  end;
end;


procedure print_path(x, y: longint);
begin
  if x <> y then
    print_path(x, p[y]);
  write(y, ' ');
end;

var
  i, j: longint;

begin
  init;

  for i := 1 to n do
    if not visited[i] then
      bfs(i);

  writeln('breath-first search (shortest path)');

  for i := 1 to n do
  begin
    write('[', 1, '->', i, '] ');
    print_path(1, i);
    writeln;
  end;

{  print;}
end.


скажите, пожалуйста, почему не работает? 

M
alexeis1
Модератор: не забывайте указывать тип подсветки. http://forum.vingrad.ru/index.php?showtopic=126445

Автор: Zlo 11.12.2006, 20:44
comtat, выложи плиз:
Алгоритм Флойда задачи о кратчайших путях (Delphi)[/B]
Очень надо smile

Автор: comtat 12.12.2006, 09:13
Zlo, сударь создайте свою тему и обязательно выложу  smile 
В чужой писать некрасиво

Автор: Alexeis 12.12.2006, 11:30
comtat, если вопрос имеет непосредственное отношение к теме, то выкладывать лучше тут. Это позволит в дальнейшем давать ссылку всего на одну тему или облегчит поиск другим участникам.

Автор: comtat 14.12.2006, 12:02
alexeis1, приму к сведению  smile 
Тогда вот реализация метода Флойда
реализация графическая

Автор: Guga 21.12.2006, 01:40
comtat, спасибо за выложенный архив...
автору проги гранд мерси

Автор: comtat 23.12.2006, 17:04
На здоровье  smile 

Автор: temp9temp9 7.11.2010, 20:26
а случайно нет кода для нахождения всевозможных путей?

Автор: ilya92 23.3.2013, 16:14
Ребят, мой вопрос в тему. помогите. может у кого то завалялся программа реализующая алгоритм флойда. попроще чем тут выложенная.и граф должен задаваться с помощью матрицы смежности. отпишитесь

Автор: Mary2108 23.12.2015, 16:45
 что значат эти строки в алгоритме Форда:
assign(f,'in.txt');
     reset(f);
     readln(f, n);

Автор: rudolfninja 23.12.2015, 20:34
Я думаю, что в алгоритме Форда они значат тоже самое, что и в целом в Pascal.
assign(f,'in.txt'); // связывает переменную f с текстовым файлом in.txt. После этого все дальнейшие операции с переменной f на самом деле происходят с внешним файлом с in.txt
reset(f); // открывает существующий внешний файл с именем, назначенным в переменной f
readln(f, n); // читает из файла, связанного с переменной f строку и записывает ее в переменную n

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)