Консультация № 177415
22.03.2010, 21:51
45.00 руб.
0 6 1
Здравствуйте, уважаемые эксперты! Помогите, пожалуйста, с решением задач:
1)Реализовать поиск в глубину и в ширину в графе
2)Реализовать Эйлеров и Гамильтонов цикл в графе.
3)Найти в графе фундаментальное множество циклов минимального суммарного веса.
Если возможно, с подробными объяснениями.
Заранее огромное спасибо!

Обсуждение

давно
Академик
324866
619
23.03.2010, 06:43
общий
23.03.2010, 09:43
это ответ
Здравствуйте, Аня Ласточка.
Поис в ширину - реализация на Паскале с использованием матрицы смежности
Код:
var
Q:array[1..100] of byte; {очередь}
left,right:byte;
procedure Enqueue(x:word); {процедура добавления в очередь вершины}
begin
Q[right]:=x;
if right=100 then right:=1 else inc(right);
end;

procedure Dequeue; {процедура удаления из очереди вершины}
begin
if left=100 then left:=1 else inc(left);
end;
var
G:array[1..100,1..100] of word; {граф}
i,j,k,h:word;
d:array[1..100] of word; {массив расстояний}
p:array[1..100] of word; {массив предков}
color:array[1..100] of byte; {массив цветов}
n:word;
fin:text;
beg:word; {начальная вершина}
begin
k:=0;
{чтение графа из файла, имя которого - первый параметр командной строки}
assign(fin,paramstr(1)); reset(fin);
read(fin,n); readln(fin,beg);
while not EOF(fin) do
begin
read(fin,i); readln(fin,j);
g[i,j]:=1; g[j,i]:=1;
end;
close(fin);
{конец чтения из файла}
{инициализация массивов}
for i:=1 to n do
begin
color[i]:=0;
d[i]:=65535;
p[i]:=0;
end;
{конец инициализации массивов}
color[beg]:=1;
d[beg]:=0;
p[beg]:=0;
left:=1;
right:=1;
Enqueue(beg); {добавление первой вершины в очередь}
while left<>right do {пока очередь не пуста}
begin
k:=Q[left];
for i:=1 to n do {для всех вершин...}
if g[k,i]=1 then {...смежных с k...}
begin
if color[i] = 0 then {...если мы ее еще не обрабатывали...}
begin
color[i]:=1; {...сделать цвет серым...}
d[i]:=d[k]+1; {...указать расстояние...}
p[i]:=k; {...указать предка...}
EnQueue(i); {...добавить в очередь}
end;
end;
Dequeue; {удалить из очереди}
color[k]:=2; {сделать цвет черным: вершина полностью обработана}
end;
{вывод на экран расстояния от s до всех вершин, достигаемых из нее}
for i:=1 to n do
write(d[i],' ');
writeln;
end.
Поиск в глубину
Код:
var
fin:text;
g:array[1..100,1..100] of word; {матрица смежности}
N:word;
d,f:array[1..100] of word; {массивы меток}
p:array[1..100] of word; {массив предков}
color:array[1..100] of byte; {массив цветов}
time:word; {счетчик времени}
procedure DFS_visit(u:word);
var
i,j:word;
begin
color[u]:=1; {"окрашиваем"вершину u в серый цвет}
inc(time);
d[u]:=time;
for i:=1 to n do
if g[u,i]=1 then {Если есть ребро из u в i...}
if color[i]=0 then {... то если цвет i белый (мы ее еще не обрабатывали)...}
begin
p[i]:=u; {...предок i - v...}
DFS_Visit(i); {...вызываем рекурсивно процедуру для вершины i}
end;
{после выполнения цикла мы гарантируем, что обработали все смежные u необработанные вершины}
color[u]:=2; {помечаем u как обработанную}
inc(time);
f[u]:=time;
end;
var
i,j:word;
begin
{читаем информацию про граф из файла, заданного первым параметром командной строки}
{граф задан так: первая строка файла - колличество вершин. В каждой следующей строке - два числа i и j. Это означает, что в графе существует ребро i->j}
assign(fin,paramstr(1)); reset(fin);
readln(fin,n);
while not EOF(fin) do
begin
read(fin,i); readln(fin,j);
g[i,j]:=1;
end;
close(fin);
{граф прочитан}
{обнуляем массивы предков и цветов}
for i:=1 to n do
begin
color[i]:=0;
p[i]:=0;
end;
for i:=1 to n do
if color[i]=0 then
DFS_Visit(i);
{в этот момент построенно дерево поиска, которое находится в массиве p, известно, на каком шаге каждая вершины вошла в поиск. Эту информацию можно использовать как данные для других алгоритмов}
end.
Метод Эйлера
Код:
Program Metod_Eyler; { Алгоритм Эйлера}
Uses Crt;
Const Nmax=10;
N_St=Nmax*(Nmax-1) div 2;
Type A_array=array [1..Nmax,1..Nmax] of integer;
Var A,A_Eiler : A_array;
Stack : array [1..N_St] of integer;
yk :integer;
Procedure Init (var A:A_array);
var F : text;
Err,Ch,i,j : integer;
St , S : string;
begin
assign (F,'graf_2.txt');
reset (F);
i:=1;
FillChar (A,SizeOf(A),0);
While not Eof(F) do begin
ReadLn (F,St);
for j:=1 to Nmax do begin
if Pos (' ',St)=0 then
Val (Copy(St,1,Length(St)),A[i,j],Err)
else
Val (Copy(St,1,Pos(' ',St)-1),A[i,j],Err);
Delete (St,1,Pos (' ',St));
end;
inc(i);
end;
Close (F);
end;
Procedure Find_Tree (var A_Eiler : A_array);
var Sp : set of 1..Nmax;
i,j,min,l,t : integer;
begin
min:=MaxInt;
Sp:=[];
l:=0; t:=0;
for i:=1 to Nmax-1 do
for j:=i+1 to Nmax do
if (A[i,j]<min) and (A[i,j]<>0) then begin
min:=A[i,j];
l:=i; t:=j;
end;
A_Eiler[l,t]:=A[l,t]; A_Eiler[t,l]:=A[t,l];
Sp:=Sp+[l,t];
While Sp<>[1..Nmax] do begin
min:=MaxInt;
l:=0; t:=0;
for i:=1 to Nmax do
if i in Sp then
for j:=1 to Nmax do
if not (j in Sp) and (A[i,j]<min) and (A[i,j]<>0) then
begin
min:=A[i,j];
l:=i; t:=j;
end;
A_Eiler[l,t]:=A[l,t]; A_Eiler[t,l]:=A[t,l];
Sp:=Sp+[l,t];
end;
end;
Procedure Eiler_Way (v:integer);
var j : integer;
begin
for j:=1 to Nmax do
if A_Eiler[v,j]<>0 then begin
A_Eiler[v,j]:=0;
Eiler_Way (j);
end;
Inc (yk); Stack[yk]:=v;
end;
Procedure Solve;
begin
FillChar (A_Eiler,SizeOf(A_Eiler),0);
yk:=0;
Find_Tree(A_Eiler);
Eiler_Way (1);
end;
Procedure OutPut;
var Way : set of 1..Nmax;
i,pred_v : integer;
Cost : integer;
begin
Write ('Путь -',Stack[1]:3);
Cost:=0;
Way:=[Stack[1]];
pred_v:=Stack[1];
for i:=2 to yk do
if Not (Stack[i] in Way) then begin
Write (Stack[i]:3);
Way:=Way+[Stack[i]];
Cost:=Cost+A[pred_v,Stack[i]];
pred_v:=Stack[i];
end;
WriteLn (Stack[1]:3);
Cost:=Cost+A[pred_v,Stack[1]];
Write ('Стоимость маршрута- ',Cost);
end;
Begin
ClrScr;
Init (A);
Solve;
OutPut;
ReadLn;
End.
Гамильтон
Код:
program HS;
uses new_crt;
type
CM = array[1..100, 1..100] of integer;
StArr = array[1..100] of integer;
NnewA = array[1..100] of boolean;
var St: StArr;
Nnew:NnewA;
A: CM;
i, N, M:integer;
f: text;
function ReadArr(S: string; var A: CM; var k: integer):boolean;
var f: text;
i, j, l: integer;
c: integer;
begin
assign(f, S);
reset(f);
i:=1; j:=1;
while not eof(f) do
begin
while not eoln(f) do
begin
read(f, c);
a[i, j]:=c;
j:=j+1;
end;
i:=i+1; l:=j-1; j:=1;
readln(f);
end;
close(f);
k:=i-1;
if (k=l) then ReadArr:=true
else ReadArr:=false;
end;
procedure Gm(k: integer);
var j,v: integer;
f: text;
i: integer;
begin
v:=St[k-1];
assign(f, 'output.txt');
rewrite(f);
for j:=1 to N do begin
write(A[v,j], ' ');
if (A[v,j]<>0) then begin
if (k=N+1) and (j=1) then for i:=1 to k do write(f, St[i], ' '); end
else if Nnew[j] then begin
St[k]:=j;
Nnew[j]:=false;
writeln(f);
Gm(k+1);
Nnew[j]:=true;
end;
end; writeln;
close(f);
end;
begin
clrscr;
if ReadArr('input.txt', A, N) then begin
Writeln(N);
St[1]:=1;
Nnew[1]:=false;
Gm(2);
end;
repeat until keypressed;
end.
давно
Академик
324866
619
23.03.2010, 06:49
общий
Аня Ласточка:
Впервые отправлял ответ и не все положил сразу
{Поиск в глубину}
var
fin:text;
g:array[1..100,1..100] of word; {матрица смежности}
N:word;
d,f:array[1..100] of word; {массивы меток}
p:array[1..100] of word; {массив предков}
color:array[1..100] of byte; {массив цветов}
time:word; {счетчик времени}
procedure DFS_visit(u:word);
var
i,j:word;
begin
color[u]:=1; {"окрашиваем"вершину u в серый цвет}
inc(time);
d[u]:=time;
for i:=1 to n do
if g[u,i]=1 then {Если есть ребро из u в i...}
if color[i]=0 then {... то если цвет i белый (мы ее еще не обрабатывали)...}
begin
p[i]:=u; {...предок i - v...}
DFS_Visit(i); {...вызываем рекурсивно процедуру для вершины i}
end;
{после выполнения цикла мы гарантируем, что обработали все смежные u необработанные вершины}
color[u]:=2; {помечаем u как обработанную}
inc(time);
f[u]:=time;
end;
var
i,j:word;
begin
{читаем информацию про граф из файла, заданного первым параметром командной строки}
{граф задан так: первая строка файла - колличество вершин. В каждой следующей строке - два числа i и j. Это означает, что в графе существует ребро i->j}
assign(fin,paramstr(1)); reset(fin);
readln(fin,n);
while not EOF(fin) do
begin
read(fin,i); readln(fin,j);
g[i,j]:=1;
end;
close(fin);
{граф прочитан}
{обнуляем массивы предков и цветов}
for i:=1 to n do
begin
color[i]:=0;
p[i]:=0;
end;
for i:=1 to n do
if color[i]=0 then
DFS_Visit(i);
{в этот момент построенно дерево поиска, которое находится в массиве p, известно, на каком шаге каждая вершины вошла в поиск. Эту информацию можно использовать как данные для других алгоритмов}
end.
давно
Академик
324866
619
23.03.2010, 06:53
общий
Аня Ласточка:
{Метод Эйлера}
Program Metod_Eyler; { Алгоритм Эйлера}
Uses Crt;
Const Nmax=10;
N_St=Nmax*(Nmax-1) div 2;
Type A_array=array [1..Nmax,1..Nmax] of integer;
Var A,A_Eiler : A_array;
Stack : array [1..N_St] of integer;
yk :integer;
Procedure Init (var A:A_array);
var F : text;
Err,Ch,i,j : integer;
St , S : string;
begin
assign (F,'graf_2.txt');
reset (F);
i:=1;
FillChar (A,SizeOf(A),0);
While not Eof(F) do begin
ReadLn (F,St);
for j:=1 to Nmax do begin
if Pos (' ',St)=0 then
Val (Copy(St,1,Length(St)),A[i,j],Err)
else
Val (Copy(St,1,Pos(' ',St)-1),A[i,j],Err);
Delete (St,1,Pos (' ',St));
end;
inc(i);
end;
Close (F);
end;
Procedure Find_Tree (var A_Eiler : A_array);
var Sp : set of 1..Nmax;
i,j,min,l,t : integer;
begin
min:=MaxInt;
Sp:=[];
l:=0; t:=0;
for i:=1 to Nmax-1 do
for j:=i+1 to Nmax do
if (A[i,j]<min) and (A[i,j]<>0) then begin
min:=A[i,j];
l:=i; t:=j;
end;
A_Eiler[l,t]:=A[l,t]; A_Eiler[t,l]:=A[t,l];
Sp:=Sp+[l,t];
While Sp<>[1..Nmax] do begin
min:=MaxInt;
l:=0; t:=0;
for i:=1 to Nmax do
if i in Sp then
for j:=1 to Nmax do
if not (j in Sp) and (A[i,j]<min) and (A[i,j]<>0) then
begin
min:=A[i,j];
l:=i; t:=j;
end;
A_Eiler[l,t]:=A[l,t]; A_Eiler[t,l]:=A[t,l];
Sp:=Sp+[l,t];
end;
end;
Procedure Eiler_Way (v:integer);
var j : integer;
begin
for j:=1 to Nmax do
if A_Eiler[v,j]<>0 then begin
A_Eiler[v,j]:=0;
Eiler_Way (j);
end;
Inc (yk); Stack[yk]:=v;
end;
Procedure Solve;
begin
FillChar (A_Eiler,SizeOf(A_Eiler),0);
yk:=0;
Find_Tree(A_Eiler);
Eiler_Way (1);
end;
Procedure OutPut;
var Way : set of 1..Nmax;
i,pred_v : integer;
Cost : integer;
begin
Write ('Путь -',Stack[1]:3);
Cost:=0;
Way:=[Stack[1]];
pred_v:=Stack[1];
for i:=2 to yk do
if Not (Stack[i] in Way) then begin
Write (Stack[i]:3);
Way:=Way+[Stack[i]];
Cost:=Cost+A[pred_v,Stack[i]];
pred_v:=Stack[i];
end;
WriteLn (Stack[1]:3);
Cost:=Cost+A[pred_v,Stack[1]];
Write ('Стоимость маршрута- ',Cost);
end;
Begin
ClrScr;
Init (A);
Solve;
OutPut;
ReadLn;
End.
давно
Академик
324866
619
23.03.2010, 06:55
общий
Аня Ласточка:
{Гамильтон}
program HS;
uses new_crt;
type
CM = array[1..100, 1..100] of integer;
StArr = array[1..100] of integer;
NnewA = array[1..100] of boolean;
var St: StArr;
Nnew:NnewA;
A: CM;
i, N, M:integer;
f: text;
function ReadArr(S: string; var A: CM; var k: integer):boolean;
var f: text;
i, j, l: integer;
c: integer;
begin
assign(f, S);
reset(f);
i:=1; j:=1;
while not eof(f) do
begin
while not eoln(f) do
begin
read(f, c);
a[i, j]:=c;
j:=j+1;
end;
i:=i+1; l:=j-1; j:=1;
readln(f);
end;
close(f);
k:=i-1;
if (k=l) then ReadArr:=true
else ReadArr:=false;
end;
procedure Gm(k: integer);
var j,v: integer;
f: text;
i: integer;
begin
v:=St[k-1];
assign(f, 'output.txt');
rewrite(f);
for j:=1 to N do begin
write(A[v,j], ' ');
if (A[v,j]<>0) then begin
if (k=N+1) and (j=1) then for i:=1 to k do write(f, St[i], ' '); end
else if Nnew[j] then begin
St[k]:=j;
Nnew[j]:=false;
writeln(f);
Gm(k+1);
Nnew[j]:=true;
end;
end; writeln;
close(f);
end;
begin
clrscr;
if ReadArr('input.txt', A, N) then begin
Writeln(N);
St[1]:=1;
Nnew[1]:=false;
Gm(2);
end;
repeat until keypressed;
end.
Неизвестный
23.03.2010, 07:06
общий
vitalkise:
Попросите модераторов добавить к ответу программы из мини-форума, а то в рассылку уйдет не полный ответ.
давно
Посетитель
7438
7205
23.03.2010, 09:44
общий
vitalkise:
Сделано.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа