Поиск ширину (волновой алгоритм)



02.09.2015

Сетевые структуры

Элемент в сетевой структуре данных характеризуются набором связи с другими соседними элементами,в таких структурах данных не начальные, не корневой элементы явно не выделены.

Сетевые структуры в основном моделируются структурой графа.

Схема структуры графа: неориентированный (рис1) (вершины, ребра (без стрелок)); ориентированный (петля, дуга (со стрелками)); взвешенный (,весы (со цифркаим)).

Представления графов: мы рассмотрим 2 способа представления графа: 1) При помощи матрицы смежности; 2) При помощи списка смежности.

Матрица смежности: для графа представленного на (рис 1) матрица смежности будет иметь вид: для неориентированного графа матрица смежности симметрична; для ориентированного графа матрица смежности не симметрична.

Список смежности: если в графе мало ребер используется список смежности. Для (рис 1) список смежности будет иметь вид:

Основной задачей в алгоритмах на графа являются задачей поиска, например минимального пути, минимальной затраты и т.д.

Поиск ширину (волновой алгоритм)

Задача: пусть дан неориентированный граф G<V,E> например представленный на (рис 1).

Необходимо найти кротчайший путь от вершины START до вершины FINISH.

Задание матрицы смежности при помощи списка ребер. Для примера из (рис 1) будет выглядеть так: количество вершин; количество ребер (перечисление ребер; весы).

START=1; FINISH=5

Для реализации данного алгоритма необходимо иметь матрицу смежности и 3 одномерных массива: QUEUE; VISIT; WAY;

 

#include <iostream>

#include <string.h>

Using namespace std;

 

Int QUEUE[100],WAY[1000], VISIT[1000], a[1000][1000], n, m, k, start, finish;

 

Void Print(int v)

{

If(v>0)

{

Print(WAY[v]); cout<<v<<’ ’;

}

}

 

Void bfs (int st) //breads-first search.

{

Int i=1, j, k=1, u;

QUEUE[k]=st; VSIT[st]=1;

Do

{

u=QUEUE[i];

for(j=1;j<=n;j++)

if(a[u][j]>0 && VISIT[j]==0)

{

VISIT[j]=1; WAY[j]=u; QUEUE[++k]=j;

}

i++;

}

While(i<=k);

}

 

Void init()

{

Int i, j,k;

Cin>>n>>m; //n-кол-во вершин, m-количество ребер

Memset(a,0,sizeof(a));

Memset(visit,o,sizeof(visit));

For(k=1;k<=m;k++)

{

cin>>i>>j;

a[i][j]=1; a[j][i]=1;

}

cin>>start<<finish;

}

Void main()

{

init();

bfs(start);

Print(finish);

}

 

Временная сложность алгоритма O(n*n) так как мы используем для поиска двумерную матрицу смежности.

Поиск ширины с использованием списка смежности.

Та же задача. Рассмотрим программу.

 

#include <iostream>

#include <string.h>

Using namespace std;

 

Const int MAXN=100;

Vect<int>spis[MAXN];

Int visit[MAXN], way[MAXN], queue[MAXN];

Int n,m,start,finish;

 

Void init()

{

Int I,j,k;

Cin>>n>>m;

Memset(visit,0,sizeof(visit));

For(k=1;k<=m;k++)

{

Cin>>i>>j;

Spis[i].push.back(j);

Spis[j].push.back(i);

}

Cin>>start>>finish;

}

 

Void Print (int v)

{

If(v>0)

{

Print(way[v]); cout<<v<<i;

}

}

Void bfs (int v)

{

Int i=1, j,k=1,u;

Queue[k]=v; visit[v]=1;

Do

{

u=queue[i];

for(j=0;j<spis[u].size();j++)

if(visit[spis[u][j]]==0)

{

Visit[spis[u][j]]=1; way[spis[u][j]]=u;

Queue[++k]=spis[u][j];

}

I++;

}

While(i<=k);

}

 

Void main()

{

Init();

Bfs(start);

Print(finish);

}

Временная сложность с использованием списка смежности равна O(n+m). M=n(n-1)/2

 

Поиск глубину (рис)

Dfs-depth-first search/поиск первого глубину.

Алгоритм:

а) Поиск начинается с некоторой вершины v=start

б) Ищется ранее не посещенная вершина u смежная с вершиной v, если такая вершина есть, это вершина u запоминается и снова повторяется шаг б с вершиной v=u.

Иначе: с) Возвращается в предыдущей вершине для очередного выполнения шага б. В том случае, когда не посещенной смежной вершины нет, процесс заканчивается.

И так мы не рассматриваем все смежные вершины, а выбираем первую не посещенную и быстро продвигаемся вглубь, откладывая их посещения на потом.

Используемые структуры: Алгоритм использует кроме матрицы смежности 2 одномерных массива: VISIT[v] -отметка по посещенности: 0-вершина еще непосещена; 1-вершина уже посещена. WAY[u] -содержит номер вершины v с которой мы пришли в вершину u. Временная сложность также зависит от представления графа. О(n*n)-матрица смежности; О(n+m)-список смежности.

Рассмотрим порядок заполнения вспомогательных массивов на исходном примере:

 

Дан граф, напечатать все цепи.

Void dfs(int v)

{

Int u;

Visit[v]=1;

For(u=1;u<=n;u++)

If(a[v][u]>0&&visit[u]=0)

{

Way[u]=v; dfs(u);

}

Print(v); cout<<end;

Visit[v]=0;

}

 

16.09.2015.


Дата добавления: 2016-01-06; просмотров: 14; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!