Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ИИС.docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
283.21 Кб
Скачать

5 Исследование работы алгоритма в зависимости от значений параметров: ,

Необходимо провести исследование работы алгоритма в зависимости от значений параметров: , .

Параметр влияет на количество фермента, а параметр связан с видимостью (длиной) грани.

Параметр определяет соотношение (1 — ), которое представляет коэффициент испарения для существующего фермента. Этот параметр определяет концентрацию фермента, которая сохранится на гранях.

Число муравьев берется равным числу городов.

Возьмем число городов, равное 35.

1. Получим значения длины пути от значений и . При этом, изменяется от 1 до 5 при различных значениях (0.5, 1, 2).

Длина пути

0,5

1

5313

0,5

2

2570

0,5

3

2570

0,5

4

2570

0,5

5

2570

1

1

2570

1

2

2570

1

3

2570

1

4

2570

1

5

2570

2

1

2570

2

2

2570

2

3

2570

2

4

2570

2

5

2570

2. Получим значения числа циклов от значений и . При этом, изменяется от 1 до 5 при различных значениях (0.5, 1, 2).

Число циклов

0,5

1

6

0,5

2

4

0,5

3

3

0,5

4

3

0,5

5

3

1

1

5

1

2

4

1

3

3

1

4

3

1

5

3

2

1

5

2

2

3

2

3

3

2

4

3

2

5

3

3. Для оптимальных значений и , полученных выше, построим графики числа циклов от числа городов (в диапазоне от 12 до 120).

6 Текст программы

/---------------------------------------------------------------------------

#include <vcl.h>

#include <stdio.h>

#include <assert.h>

#include <time.h>

#include <math.h>

#include <stdlib.h>

#include <string>

#include <Math.hpp>

#define getSRand() ((float)rand() / (float)RAND_MAX)

#define getRand(x) (int)((x) * getSRand())

#define MAX_DISTANCE 500

#define ALPHA 1.0

#define BETA 5.0

#define RHO 0.5

#define QVAL 100

#define MAX_TOURS 500

int MAX_CITIES = 0;

int MAX_ANTS = 0;

int MAX_TOUR;

int MAX_TIME;

bool flagRes = false;

double INIT_PHEROMONE;

typedef struct

{

int curCity;

int nextCity;

unsigned char* tabu;

int pathIndex;

unsigned char* path;

double tourLength;

} antType;

typedef struct

{

double x;

double y;

} cityType;

cityType* cities;

antType* ants;

double** distance;

double** pheromone;

double best=(double)MAX_TOUR;

int bestIndex;

int* bestPath; // массив городов наилучшего пути

double XMax,YMax;

float Hx;

void restartAnts( void );

int simulateAnts( void );

void updateTrails( void );

void SavePath( void ); //сохранение массива узлов наилучшего пути

void BestPath( void ); // определение наилучшего пути

void VisualCity(void);

void VisualPath(void);

#pragma hdrstop

#include "MainAnt.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TFormAnt *FormAnt;

//---------------------------------------------------------------------------

__fastcall TFormAnt::TFormAnt(TComponent* Owner)

: TForm(Owner)

{

XMax = FormAnt->Width;

YMax = FormAnt->Height;

Hx=1.;

}

//---------------------------------------------------------------------------

void __fastcall TFormAnt::ButtonOKClick(TObject *Sender)

{

try{

MAX_CITIES = StrToInt(citiesEdit->Text);

if(MAX_CITIES<12 ||MAX_CITIES>120)

{

Application->MessageBox("Количество городов должно быть в диапозоне от 12 до 120",

"Ошибка ввода", MB_OK);

return;

}

MAX_ANTS = MAX_CITIES;}

catch(EConvertError &ex)

{

Application->MessageBox("Введите количество цифрами",

"Ошибка ввода", MB_OK);

return;

}

//определяем размеры динамических массивов

cities = new cityType[MAX_CITIES];

bestPath = new int[MAX_CITIES];

ants = new antType[MAX_ANTS];

for(int j=0;j<=MAX_ANTS;j++) {

ants[j].tabu = new unsigned char [MAX_CITIES];

ants[j].path = new unsigned char [MAX_CITIES]; }

distance = new double* [MAX_CITIES];

for(int u=0;u<=MAX_CITIES;u++)

{distance[u]=new double[MAX_CITIES];}

pheromone = new double* [MAX_ANTS];

for(int k=0;k<=MAX_ANTS;k++)

{ pheromone[k]=new double[MAX_ANTS];}

MAX_TOUR = MAX_CITIES * MAX_DISTANCE;

MAX_TIME = MAX_TOURS * MAX_CITIES;

INIT_PHEROMONE = 1.0 / MAX_CITIES;

}

//---------------------------------------------------------------------------

void PaintCircle()

{

double c_x, c_y;

c_x = 800;

c_y = 800;

double Pi = 3.141592653;

int n_line = MAX_CITIES/3; //число городов на полуокружности

int n_circle = MAX_CITIES-n_line; // число городов полуокружности

double corner = double(180.0 / -(n_circle));

double d_corner = 0;

int j = 1;

double d_cornerRD = 0; // угол в радианах

for(int i=0; i<MAX_CITIES; i++)

{

if (i<=n_circle) // полуокружность

{

d_cornerRD = (d_corner*Pi)/180;

cities[i].x = MAX_DISTANCE * cos(d_cornerRD)+c_x;

cities[i].y = c_y + MAX_DISTANCE * sin(d_cornerRD);

d_corner = d_corner + corner;

}

else // диаметр

{

cities[i].x = cities[0].x - (2*j*MAX_DISTANCE/n_line);

cities[i].y = cities[0].y;

j++;

}

}

}

void __fastcall TFormAnt::mnuCityRandomClick(TObject *Sender)

{

if(MAX_CITIES == 0)

{

Application->MessageBox("Для расположепия городов необходимо ввести их количество",

"Ошибка ввода", MB_OK);

return;

}

int from, to, ant;

// Создать города и их координаты

PaintCircle();

for (from = 0 ; from < MAX_CITIES ; from++) {

for (to = 0 ; to < MAX_CITIES ; to++) {

distance[from][to] = 0.0;

pheromone[from][to] = INIT_PHEROMONE;

}

}

// вычислить расстояние между городами

for ( from = 0 ; from < MAX_CITIES ; from++) {

for ( to = 0 ; to < MAX_CITIES ; to++) {

if ((to != from) && (distance[from][to] == 0.0)) {

double xd = cities[from].x - cities[to].x;

double yd = cities[from].y - cities[to].y;

distance[from][to] = sqrt( (xd * xd) + (yd * yd) );

distance[to][from] = distance[from][to];

}

}

}

// Инициализировать муравьев

to = 0;

for ( ant = 0 ; ant < MAX_ANTS ; ant++ ) {

// распределить муравьев по горадам равномерно

if (to == MAX_CITIES) to = 0;

ants[ant].curCity = to++;

for ( from = 0 ; from < MAX_CITIES ; from++ ) {

ants[ant].tabu[from] = 0;

ants[ant].path[from] = -1;

}

ants[ant].pathIndex = 1;

ants[ant].path[0] = ants[ant].curCity;

ants[ant].nextCity = -1;

ants[ant].tourLength = 0.0;

// Загрузить текущий город муравья в список табу

ants[ant].tabu[ants[ant].curCity] = 1;

}

flagRes = true;

}

//---------------------------------------------------------------------------

void VisualCity(void)

{

int city,x0,y0,x,y;

float hx,hy , Hy;

hx=0;

hy=0;

// зальем форму белым цветом

FormAnt->Canvas->Brush->Color = clWhite;

FormAnt->Canvas->FillRect(Rect(0,0,XMax,YMax));

for (city = 0 ; city < MAX_CITIES ; city++)

{

x = cities[city].x;

y = cities[city].y;

if(x>hx) hx=x;

if(y>hy) hy=y;

}

Hx=(XMax-100)/hx;

Hy=(YMax-100)/hy;

if(Hx > Hy) Hx= Hy;

FormAnt->Canvas->Brush->Color = clRed;

for (city = 0 ; city < MAX_CITIES ; city++)

{

x= Hx*cities[city].x;

y = Hx*cities[city].y;

FormAnt->Canvas->FillRect(Rect(x-5,y+5,x+5,y-5));

}

}

//---------------------------------------------------------------------------

void __fastcall TFormAnt::mnuCityShowClick(TObject *Sender)

{

if(!flagRes)

{ Application->MessageBox("Для отображения выполните размещение городов",

"Ошибка отображения", MB_OK);

return;

}

VisualCity();

}

//---------------------------------------------------------------------------

void __fastcall TFormAnt::mnuExitClick(TObject *Sender)

{

Close();

}

//---------------------------------------------------------------------------

void BestPath(void)

{

int ant ;

for ( ant = 0 ; ant < MAX_ANTS ; ant++ )

{

if (ants[ant].tourLength < best)

{

best = ants[ant].tourLength;

bestIndex = ant;

}

}

}

void SavePath( void )

{

int to;

for ( to = 0 ; to < MAX_CITIES ; to++ )

bestPath[to]=ants[bestIndex].path[to];

}

//---------------------------------------------------------------------------

void VisualPath()

{

int city,x0,y0,x,y;

FormAnt->Canvas->Brush->Color = clWhite;

FormAnt->Canvas->FillRect(Rect(0,0,XMax,YMax));

VisualCity();

x0= Hx*cities[bestPath[0] ].x;

y0= Hx*cities[bestPath [0] ].y;

FormAnt->Canvas->FillRect(Rect(x0-5,y0+5,x0+5,y0-5));

FormAnt->Canvas->Brush->Color = clGreen;

FormAnt->Canvas->MoveTo(x0,y0);

for (city = 0 ; city < MAX_CITIES ; city++)

{

x= Hx*cities[bestPath [city] ].x;

y= Hx*cities[bestPath [city] ].y;

FormAnt->Canvas->LineTo(x,y);

}

FormAnt->Canvas->LineTo(x0,y0);

x0= Hx*cities[0 ].x;

y0= Hx*cities[0 ].y;

FormAnt->Canvas->Brush->Color = clBlack;

FormAnt->Canvas->FillRect(Rect(x0-5,y0+5,x0+5,y0-5));

}

//---------------------------------------------------------------------------

void restartAnts( void )

{

int ant, i, to=0;

for ( ant = 0 ; ant < MAX_ANTS ; ant++ ) {

if (ants[ant].tourLength < best)

{

best = ants[ant].tourLength;

bestIndex = ant;

}

ants[ant].nextCity = -1;

ants[ant].tourLength = 0.0;

for (i = 0 ; i < MAX_CITIES ; i++)

{

ants[ant].tabu[i] = 0;

ants[ant].path[i] = -1;

}

if (to == MAX_CITIES) to = 0;

ants[ant].curCity = to++;

ants[ant].pathIndex = 1;

ants[ant].path[0] = ants[ant].curCity;

ants[ant].tabu[ants[ant].curCity] = 1;

}

}

//---------------------------------------------------------------------------

void __fastcall TFormAnt::mnuMinRoadClick(TObject *Sender)

{

if(!flagRes)

{ Application->MessageBox("Для расчета выполните размещение городов",

"Ошибка расчета", MB_OK);

return;

}

int curTime = 0, cycle=0;

double mbest;

best=(double)MAX_TOUR;

mbest=best*2;

while (curTime++ < MAX_TIME)

{

if ( simulateAnts() == 0 )

{

cycle++;

updateTrails();

BestPath();

if(mbest > best)

{

mbest=best;

SavePath();

restartAnts();

}

else

break;

}

}

// визуализация пути муравья

VisualPath();

// отображение пути

StatusBar1->Panels->Items[0]->Text="Длина пути = " + FloatToStr(mbest)+ " Число циклов = " + IntToStr(cycle);

}

//---------------------------------------------------------------------------

double antProduct(int from, int to )

{

return (( pow( pheromone[from][to], ALPHA ) *

pow( (1.0 / distance[from][to]), BETA ) ));

}

//---------------------------------------------------------------------------

int selectNextCity( int ant )

{

int from, to;

double denom=0.0;

// выбрать следующий город для составления пути

from = ants[ant].curCity;

// Вычислить знаменателя выражения

for (to = 0 ; to < MAX_CITIES ; to++) {

if (ants[ant].tabu[to] == 0) {

denom += antProduct( from, to );

}

}

assert(denom != 0.0);

do {

double p;

to++;

if (to >= MAX_CITIES) to = 0;

if ( ants[ant].tabu[to] == 0 ) {

p = antProduct(from, to)/denom;

if (getSRand() < p ) break;

}

} while (1);

return to;

}

//---------------------------------------------------------------------------

int simulateAnts( void )

{

int k;

int moving = 0;

for (k = 0 ; k < MAX_ANTS ; k++)

{

// муравьи посещают города

if (ants[k].pathIndex < MAX_CITIES)

{

ants[k].nextCity = selectNextCity( k );

ants[k].tabu[ants[k].nextCity] = 1;

ants[k].path[ants[k].pathIndex++] = ants[k].nextCity;

ants[k].tourLength += distance[ants[k].curCity][ants[k].nextCity];

// Обработать финальный случай (последний город )

if (ants[k].pathIndex == MAX_CITIES)

{

ants[k].tourLength +=

distance[ants[k].path[MAX_CITIES-1]][ants[k].path[0]];

}

ants[k].curCity = ants[k].nextCity;

moving++;

}

}

return moving;

}

//---------------------------------------------------------------------------

void updateTrails( void )

{

int from, to, i, ant;

// испарение фермента

for (from = 0 ; from < MAX_CITIES ; from++)

{

for (to = 0 ; to < MAX_CITIES ; to++)

{

if (from != to)

{

pheromone[from][to] *= (1.0 - RHO);

if (pheromone[from][to] < 0.0) pheromone[from][to] = INIT_PHEROMONE;

}

}

}

// нанесение нового фермента

for (ant = 0 ; ant < MAX_ANTS ; ant++)

{

//обновляем каждый шаг пути

for (i = 0 ; i < MAX_CITIES ; i++)

{

if (i < MAX_CITIES-1)

{

from = ants[ant].path[i];

to = ants[ant].path[i+1];

}

else

{

from = ants[ant].path[i];

to = ants[ant].path[0];

}

pheromone[from][to] += (QVAL / ants[ant].tourLength);

pheromone[to][from] = pheromone[from][to];

}

}

for (from = 0 ; from < MAX_CITIES ; from++)

{

for (to = 0 ; to < MAX_CITIES ; to++)

{

pheromone[from][to] *= RHO;

}

}

}//---------------------------------------------------------------------------