Алгоритм дейкстры
но у меня чето проблема с массивами, предложите ваш код написания!
C++
S; заполнить числом i массив C; перенести i-ю строку матрицы
A в массив B,
S:=1; C:=0 (i - номер стартовой вершины)
2 (общий шаг). Hайти минимум среди неотмеченных (т. е. тех k, для
которых S[k]=0); пусть минимум достигается на индексе j, т. е. B[j]<=B[k]
Затем выполняются следующие операции:
S[j]:=1;
если B[k] > B[j]+A[j,k], то (B[k]:=B[j]+A[j,k]; C[k]:=j)
(Условие означает, что путь Vi ... Vk длиннее, чем путь Vi...Vj Vk).
(Если все S[k] отмечены, то длина пути от Vi до Vk равна B[k]. Теперь
надо) перечислить вершины, входящие в кратчайший путь).
3 (выдача ответа). (Путь от Vi до Vk выдается в обратном порядке
следующей процедурой:)
3.1. z:=C[k];
3.2. Выдать z;
3.3. z:=C[z]. Если z = О, то конец,
иначе перейти к 3.2.
но шото это не похоже на дейкстру подскажите шо-нибудь, как выполнить перенос i-й строки матрицы
A в массив B???
Код:
for(l=0;l<N;l++) B[l]=A[l,i];
Мда...тогда будум пробывать при помощи этого метода. А если у меня есть массивы A][j] B[j][k], то если твоим методом скопировать то получится B[k]???
Массив B, как я понял - массив меток вершин. Он должен быть одномерным.
Следовательно, мы можем искать только от начальной вершины v. Первым делом мы находим все минимальные длины путей из вершины v в каждую вершину (или пока не найдем мин.путь в w). (По сути убираем бесконечности из строки v матрицы B - некий массив D[n][2]. В D указываем длину пути, и из какой вершины прибыли.) После нахождения D мы просто пробегаем от w к v, записывая результат в обратном порядке. Таким образом мы найдем один из альтернативных кратчайших путей. Не вижу проблем с решением.
вот как классический Дейкстра выглядит (по памяти - могу чуть ошибиться):
Пусть дан массив A - матрица весов дуг графа (-1 обозначим за бесконечность). Ищем путь от X до Y
1. p=x; B[1..n]=-1; B
=0; C[1..n]=false; C
=true;
2. для всех вершин смежных с p если B
+A[p,i]<B или B=-1 и C=false, B=B
+A[p,i]
3. выбираем j - индекс min B[1..n] для которого C[j]=false
4. С[j]=true; p=j;
5. Если p<>y к 2.
Это разметка графа. Далее обратный ход:
1. p=y
2. Вывод p
3. Выбираем j для которого B[j]=B
-A[p,j]
4. p=j;
5. Если p<>x к 2
Путь будет выведен в обратном порядке.
P.S. Алгоритм Дейкстры используется на взвешанных графах с неотрицательными весами.
P.P.S. Массивы B - метки вершин, C - признак "зафиксированности" метки
Буду благодарен!!!
Ты меня удивляешь - куда уж дальше. И так почти код написан. В чем у тебя затруднения - то?
...уже все получилось, спасибо за алгоритм
Обратный ход - элементарщина.
Код:
uses Crt; {D}
const
N = 5;
W : array[1..N,1..5] of real= ( (-1, 2, 1,-1,10),
( 2,-1,-1, 2, 5),
( 1,-1,-1,-1, 6),
(-1, 2,-1,-1, 2),
(10, 5, 6, 2,-1) );
var
B : array[1..N] of real;
C : array[1..N] of boolean;
p,x,y : integer;
i : integer; {D}
{ 1. p=x; B[1..n]=-1; B=0; C[1..n]=false; C=true; }
procedure step1;
var
i : integer;
begin
for i:=1 to N do
begin
B:=-1; C:=false;
end;
end;
{ 2. для всех вершин смежных с p если B+A[p,i]<B или B<>-1 и C=false,
B=B+A[p,i] }
procedure step2;
var
i : integer;
begin
for i:=1 to N do
begin
if (W[p,i]>=0) then
if ((B<0) or (B+W[p,i]<B)) and (not C) then
B:=B+W[p,i];
end;
end;
{3. выбираем j - индекс min B[1..n] для которого C[j]=false
4. С[j]=true; p=j; }
function step3:boolean;
var
j,min : integer;
flag : boolean;
begin
flag:=false;
for min:=1 to N do
if not C[min] then
begin
flag:=true; break;
end;
if not flag then
begin
step3:=true; exit;
end;
for j:=2 to N do
if not C[j] and (B[min]>B[j]) and (B[j]>=0) then min:=j;
C[min]:=true; p:=min;
step3:=false;
end;
begin
readln(x,y);
step1; p:=x; B:=0; C:=true;
repeat
step2;
for i:=1 to N do write(B:3:0); writeln;
for i:=1 to N do write(C,' '); writeln;
readkey;
until step3;
if p=y then
begin
end;
end.
{Это была разметка графа.
Далее обратный ход (пиши по аналогии):
1. p=y
2. Вывод p
3. Выбираем j для которого B[j]=B-A[p,j]
4. p=j;
5. Если p<>x к 2}
const
N = 5;
W : array[1..N,1..5] of real= ( (-1, 2, 1,-1,10),
( 2,-1,-1, 2, 5),
( 1,-1,-1,-1, 6),
(-1, 2,-1,-1, 2),
(10, 5, 6, 2,-1) );
var
B : array[1..N] of real;
C : array[1..N] of boolean;
p,x,y : integer;
i : integer; {D}
{ 1. p=x; B[1..n]=-1; B=0; C[1..n]=false; C=true; }
procedure step1;
var
i : integer;
begin
for i:=1 to N do
begin
B:=-1; C:=false;
end;
end;
{ 2. для всех вершин смежных с p если B+A[p,i]<B или B<>-1 и C=false,
B=B+A[p,i] }
procedure step2;
var
i : integer;
begin
for i:=1 to N do
begin
if (W[p,i]>=0) then
if ((B<0) or (B+W[p,i]<B)) and (not C) then
B:=B+W[p,i];
end;
end;
{3. выбираем j - индекс min B[1..n] для которого C[j]=false
4. С[j]=true; p=j; }
function step3:boolean;
var
j,min : integer;
flag : boolean;
begin
flag:=false;
for min:=1 to N do
if not C[min] then
begin
flag:=true; break;
end;
if not flag then
begin
step3:=true; exit;
end;
for j:=2 to N do
if not C[j] and (B[min]>B[j]) and (B[j]>=0) then min:=j;
C[min]:=true; p:=min;
step3:=false;
end;
begin
readln(x,y);
step1; p:=x; B:=0; C:=true;
repeat
step2;
for i:=1 to N do write(B:3:0); writeln;
for i:=1 to N do write(C,' '); writeln;
readkey;
until step3;
if p=y then
begin
end;
end.
{Это была разметка графа.
Далее обратный ход (пиши по аналогии):
1. p=y
2. Вывод p
3. Выбираем j для которого B[j]=B-A[p,j]
4. p=j;
5. Если p<>x к 2}
Hydra!А можно уж до конца дописать реализацию обратного хода:чтоб так сказать программа была готова к использованию.