площади для размещения, растет среднее число появляющихся мостов и
время, необходимое на отыскание одного такого моста. Если в модели с 500
0
10
20
30
40
50
60
0 5000 10000 15000
Среднее число мостов в соответствующей серии
испытаний
Среднее число
мостов
Верхняя оценка
среднего числа
мостов
0
1
2
3
4
5
6
7
8
0 2000 4000 6000 8000 10000 12000 14000 16000
18
узлами оно составляет всего лишь 0,16 мс., то уже в тестах с 4500 узлами
поднимается до 1,46 мс. на 1 мост. Однако, сильнее всего время отыскания
моста выросло в последнем случае. Для троекратного увеличения N (по
сравнению с случаем 4500 узлов) наблюдаю увеличение времени отыскания
каждого моста в 4,8 раза (7,06 мс. на 1 мост).
Также, при троекратном увеличении концентрации узлов сети, среднее
число мостов повышается только в 2 раза.
Для того, чтобы говорить о корректности данных, собранных
многопоточной программой, оценим отличия в асимптотике вероятности
появления мостов в случае однопоточной (О) и многопоточной (М)
программ:
Рисунок 7 – сравнение данных о вероятности появления мостов.
Как видно, отличия незначительны. Поэтому можно говорить о
корректности собранных данных.
Тестирование среднего числа мостов дало следующие результаты:
0
0,001
0,002
0,003
0,004
0,005
0,006
0,007
0,008
0,009
0 2000 4000 6000 8000 10000 12000
(М)
(О)
Рисунок
Результаты, полученные
следующей рекурсивной
Пусть a= F(n
Тогда остальные результаты
Для получения верхней
F
n/2 .
В результате применения
получен следующий результат
Рисунок
многопоточной
0
20
40
60
80
100
120
140
0 2000 4000
0
2
4
6
8
10
12
Однопоточная
19
8 – оценка среднего количества мостов
Результаты программой, хорошо
функцией:
/3
можно оценить как a7
оценки достаточно будет рассчитать
параллельной архитектуры
времени работы, мин.:
9 – Сравнение временных затрат однопоточной
версий программы.
6000 8000 10000 12000
Среднее
оценка
Многопоточная
Сравнение временных затрат
Однопоточная
Многопоточная
мостов.
приближаются
! a'89 a;
a!
программы был
и
число мостов
20
Таблица 2.
Сравнение производительности многопоточной и однопоточной
программ.
Однопоточная, мин. Многопоточная, 2 потока,
мин.
Прирост, %.
11,12 5,8 47,84
Листинг подпрограмм, использованных в экспериментах, приведен в
приложении Д.
21
ЗАКЛЮЧЕНИЕ
Основные результаты и выводы работы:
Разработана программа, позволяющая исследовать имеющуюся
беспроводную ad hoc сеть, представленную неориентированным графом, на
предмет повреждений структуры сети и возможности восстановить
поврежденную структуру, а так же снизить риск нарушения структуры путем
выявления ненадежных участков сети – мостов.
Проведены испытания, показавшие, что при увеличении числа узлов в
сети, расположенных на фиксированной площади, растет и количество
ненадежных каналов связи, при разрыве которых сеть потеряет целостность,
распавшись на несколько несвязанных сегментов. При этом, количество
таких каналов возрастает в 2 раза при увеличении концентрации сетевых
узлов в 3 раза.
Рассмотрен стандарт многопоточного программирования С++ 11 на
примере конкретной программы. Оценка прироста производительности
составила ~48%.
22
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
1. , , Лекции по
теории графов. // М: Наука, 1990. с. 36.
2. Басакер Р, еревод с английского. Конечные графы и сети. // М:
Наука. 1973. с. 25.
3. еория графов. Перевод с английского. // М: Едиториал УРСС.
2003. с. 27, 42.
4. зык программирования С++. // Второе дополненное
издание. 1997. с. 14 – 17.
5. Элементы теории графов.// Пенза: изд-во ПГУ, 2007.
6. Основы теории графов.// М.: Вузовская книга. 2004.
7. араллельное программирование на С++ в действии.//М.:ДМК
Пресс, 2012.
23
ПРИЛОЖЕНИЕ А
Класс node.
/*Вершина. Имеет координаты x, y и радиус действия передатчика range*/
class node
{
public:
float x, y;
float range;
node::node(float x, float y, float range)
{
this->x = x;
this->y = y;
this->range = range;
};
};
24
ПРИЛОЖЕНИЕ Б
Класс grafe.
class grafe
{
public:
vector<vector <int> > edgelist;// список смежности.
vector<int> Marker;//массив посещенных врешин
int size; //число вершин
vector<vector <int>> Components; // Хранит компоненты связности
графа
vector<int> comp; // временный вектор для сборки Components
vector<node*> GNodes; //Вектор, хранит указатели на все
имеющиеся узлы сети
vector<node*> AverageComponents;//Указатели на узлы
среднестатистических координат в компонентах
vector<T_Averaged_Components*> UCComponents; //Информация о
возможностях связать компоненты
vector<T_Bridges*> Bridges; //Ребра-мосты
vector<pair<int, int>> IRepair;/*пары вершин для прокладки ребер
между компонентами*/
int diam; //диаметр графа
grafe (int n);
~grafe(void){};
int DFS1(int); // Поиск в глубину в чистом виде.
void grafe::bridgeUtil(int u, bool visited[], int disc[], int
low[], int parent[]); //вспомогательная подпрограмма поиска мостов
void bridge(); //основная подпрограмма поиска мостов
int GDDFS_Iter(int v1);//итеративный DFS, поиск диаметра графа.
int GDiamIter(); //Поиск диаметра графа, основная подпрограмма
int GUComponents_Iter();//проверка связности графа на итеративном
обходе.
//-----------------------------------------------
void EListPrint();//Печать списка смежности графа
void UCComponentsPrint();//Печать компонент связности
int BridgesPrint();//Печать мостов
void PMayRepair(); //Информация о возможности восстановления
float Range_Between(node *, node *); // Дистанция между узлами
сети.
};
25
ПРИЛОЖЕНИЕ В
Класс T_Averaged_Components.
class T_Averaged_Components
{
public:
pair<int, node*> Node1;//Номер первого узла/компоненты,
pair<int, node*> Node2; //Номер второго узла/компоненты
float mydistance;
T_Averaged_Components(node * P1, node* P2, float dist, int num1,
int num2)
{
this->Node1.first=num1;
this->Node1.second = P1;
this->Node2.first=num2;
this->Node2.second=P2;
this->mydistance = dist;
}
};
26
ПРИЛОЖЕНИЕ Г
Класс T_Bridges
class T_Bridges
{
public:
int v1,v2;
T_Bridges(int x, int y)
{
this->v1 = x;
this->v2 = y;
}
};
27
ПРИЛОЖЕНИЕ Д
Реализация методов класса grafe.
grafe::grafe(int n)
{
size = n;
diam=0;
for (int i = 0; i<n; i++)
{
Marker. push_back(0);
edgelist. push_back(vector <int> ());
Components. push_back(vector <int> ());
}
}
//---------------Печать списка смежности графа------------------------
void grafe::EListPrint()
{
cout << "Ребра: " << endl;
int v, u;
for(int i=0; i<(int)edgelist. size(); i++)
{
for(int j=0; j<(int)edgelist[i].size(); j++)
{
u=i+1;
v=edgelist[i][j]+1;
cout << "(" << u << " <-> " << v <<"); \n";
}
cout << endl;
}
}
int grafe::DFS1(int v)
{
int tmp=0; //tmp, is result
int mtmp=0; //max for tmp
comp. push_back(v+1);
Marker[v] = 1; //вершина посещена
for (vector<int>::iterator i = this->edgelist[v].begin(); i!=
this->edgelist[v].end(); ++i)
{
if ( Marker[*i] != 1 )
{
DFS1(*i);
28
}
}
return 1;
}
//-----------------------------------------------------------
void grafe::bridgeUtil(int u, bool visited[], int disc[], int low[],
int parent[])
{
static int time = 0;
// Отметка о посещении вершины
visited[u] = true;
// Инициализуем минимальное значение и счетчик посещения
disc[u] = low[u] = ++time;
// Пройдем по всем вершинам, смежным с данной
vector<int>::iterator i;
for (i = edgelist[u].begin(); i!= edgelist[u].end(); ++i)
{
int v = *i; // выбранная v смежна с u
// Если v не посещена, повторим поиск для нее
if (!visited[v])
{
parent[v] = u;
bridgeUtil(v, visited, disc, low, parent);
/*Убедимся, что поддерево с корнем v имеет связь с одним
из предков u*/
low[u] = min(low[u], low[v]);
/*Если вершины в разных компонентах связности, то
ребро - мост*/
if (low[v] > disc[u])
{
// cout << u+1 <<" <-> " << v+1 << endl;
this->Bridges. push_back(new T_Bridges(u+1, v+1));
}
}
// Обновим значения.
else if (v!= parent[u])
low[u] = min(low[u], disc[v]);
}
}
void grafe::bridge()
{
29
// Отметим все вершины как непосещенные
bool *visited = new bool[this->size];
int *disc = new int[this->size];
int *low = new int[this->size];
int *parent = new int[this->size];
// Проинициализуем массив предков и массив посещений
for (int i = 0; i < this->size; i++)
{
parent[i] = NIL;// NIL = -1, т. к. изначально предков нет.
visited[i] = false;
}
// Вызов рекурсивной функции поиска мостов. Корень поддерева i-я
вершина.
for (int i = 0; i < this->size; i++)
if (!visited[i] )
bridgeUtil(i, visited, disc, low, parent);
}
int grafe::BridgesPrint()
{
if (this->Bridges. size()>0)
{
cout << "Найдено "<< this->Bridges. size() << " мостов,
формат вывода \nv1 <-> v2 \n";
for (int i = 0; i < this->Bridges. size(); i++)
{
cout << " " << this->Bridges[i]->v1 << " - " << this-
>Bridges[i]->v2 << endl;
}
}
else
cout << "Мостов не обнаружено. \n";
return 0;
}
//------------------Дистанция между узлами---------------------
float grafe::Range_Between(node *P1, node *P2)
{
return (float)sqrt(pow(P1->x - P2->x, 2) + pow(P1->y - P2-
>y, 2));
};
//-----------------Печать компонент связности-------------------
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 |


