Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #include <cmath>
- #include <time.h>
- using namespace std;
- //typedef vector<vector<int> > matrix;
- //typedef vector<int> vector, array;
- int IndividsCount;
- int CitiesCount;
- class individ;
- class city
- {
- public:
- int x,y,id;
- city(){}
- city(int x1, int y1, int id1)
- {
- x = x1;
- y = y1;
- id = id1;
- }
- void SearchClosest(individ& , vector<city>&, vector<city> );
- city operator=(city Second)
- {
- x = Second.x;
- y = Second.y;
- id = Second.id;
- }
- };
- class individ
- {
- public:
- vector<city> Genes;
- float Way;
- individ()
- {
- }
- float WayLength()
- {
- Way = 0;
- for(size_t i = 0; i<CitiesCount-1; i++)
- {
- Way+= sqrt( abs(Genes[i].x - Genes[i+1].x) + abs(Genes[i].y - Genes[i+1].y) );
- }
- return Way;
- }
- template <typename T>
- individ operator= (T second)
- {
- if(Genes.size() > 0)
- {
- Genes.clear();
- vector<city>().swap(Genes); //Чистим память
- }
- for(size_t i = 0; i<CitiesCount; i++)
- {
- Genes.push_back(second.Genes[i]);
- }
- }
- };
- void city::SearchClosest(individ& _individ, vector<city>& Used, vector<city> _cities)
- {
- float way;
- float min = 1000000000;
- int minId;
- for(size_t i = 0; i<CitiesCount; i++)
- {
- bool isUsed = false;
- for(size_t j = 0; j<Used.size() ; j++)
- if(_cities[i].id == Used[j].id) isUsed = true;
- if(isUsed) continue;
- if(id == _cities[i].id) continue; //Необязатльная проверка(вроде)
- way = sqrt( abs(x - _cities[i].x) + abs(y - _cities[i].y) );
- if(way < min)
- {
- min = way;
- minId = i;
- }
- }
- _individ.Genes.push_back(_cities[minId]);
- Used.push_back(_cities[minId]);
- if(Used.size() == CitiesCount) return;
- else
- _cities[minId].SearchClosest(_individ, Used, _cities);
- }
- void Cross (individ parent1 , individ parent2, individ& child1 , individ& child2) // replace двух случайных городов (a и b) в обоих потомках
- {
- int RandCity1 = rand()%CitiesCount;
- int RandCity2 = rand()%CitiesCount;
- while(RandCity1 == RandCity2)
- RandCity2 = rand()%CitiesCount;
- child1 = parent1;
- child2 = parent2;
- city a,b;
- int aID, bID;
- for(size_t i = 0; i<CitiesCount; i++)
- {
- if(child1.Genes[i].id == RandCity1) {a = child1.Genes[i]; aID = i;}
- if(child1.Genes[i].id == RandCity2) {b = child1.Genes[i]; bID = i;}
- }
- city temp = a;
- child1.Genes[aID] = b;
- child1.Genes[bID] = temp;
- for(size_t i = 0; i<CitiesCount; i++)
- {
- if(child2.Genes[i].id == RandCity1) {a = child2.Genes[i]; aID = i;}
- if(child2.Genes[i].id == RandCity2) {b = child2.Genes[i]; bID = i;}
- }
- temp = a;
- child2.Genes[aID] = b;
- child2.Genes[bID] = temp;
- }
- class population
- {
- public:
- vector<individ> individs;
- population(){}
- void RandomFirstPopulation(vector<city> cities)
- {
- for(size_t i = 0; i<IndividsCount; i++)
- {
- individ Create;
- int k = CitiesCount;
- vector<city> TempCities = cities;
- for(size_t j = 0; j<CitiesCount; j++)
- {
- int RandIndex = rand()%k;
- Create.Genes.push_back(TempCities[RandIndex]);
- TempCities.erase(TempCities.begin() + RandIndex);
- k--;
- }
- individs.push_back(Create);
- }
- }
- void LogicFirstPopulation(vector<city> cities)
- {
- individ Create;
- vector<city> UsedCities;
- int RandIndex = rand()%CitiesCount;
- Create.Genes.push_back(cities[RandIndex]);
- UsedCities.push_back(cities[RandIndex]);
- cities[RandIndex].SearchClosest(Create, UsedCities, cities);
- individs.push_back(Create);
- }
- void Mutation(float probability)
- {
- for(size_t i = 0; i<IndividsCount; i++)
- {
- if(rand()%IndividsCount < probability*IndividsCount)
- {
- int RandID1 = rand()%CitiesCount;
- int RandID2 = rand()%CitiesCount;
- while(RandID2 == RandID1)
- RandID2 = rand()%CitiesCount;
- city temp;
- temp = individs[i].Genes[RandID1];
- individs[i].Genes[RandID1] = individs[i].Genes[RandID2];
- individs[i].Genes[RandID2] = temp;
- }
- }
- }
- void Selection(int T, population& NewPopulation)
- {
- while(NewPopulation.individs.size() < IndividsCount)
- {
- vector<int> CompetitorsIDs;
- float LeastCompetitorWay = 1999999999;
- int LCWid;
- for(size_t i = 0; i<T; i++)
- {
- int Random;
- bool isUnique = false;
- while(!isUnique)
- {
- Random = rand()%IndividsCount;
- isUnique = true;
- for(size_t j=0; j<CompetitorsIDs.size(); j++)
- {
- if(Random == CompetitorsIDs[j])
- {
- isUnique = false;
- }
- }
- }
- CompetitorsIDs.push_back(Random);
- if(individs[Random].WayLength() < LeastCompetitorWay)
- {
- LeastCompetitorWay = individs[Random].WayLength();
- LCWid = Random; // id особи с наименьшим расстоянием
- }
- }
- NewPopulation.individs.push_back(individs[LCWid]);
- }
- }
- void Crossing(population& NewPopulation, float Probability)
- {
- while(NewPopulation.individs.size() < IndividsCount)
- {
- int ParentID1 = rand()%IndividsCount;
- int ParentID2 = rand()%IndividsCount;
- while(ParentID1 == ParentID2)
- ParentID2 = rand()%IndividsCount;
- if(rand()%100 < Probability*100)
- {
- individ _child1;
- individ _child2;
- Cross(individs[ParentID1], individs[ParentID2], _child1, _child2); //Функция описана на 103 строке
- NewPopulation.individs.push_back(_child1);
- NewPopulation.individs.push_back(_child2);
- }
- }
- }
- void Out()
- {
- for(size_t i = 0; i<IndividsCount; i++)
- {
- cout<<i<<" особь: ";
- for(size_t j = 0; j<CitiesCount; j++)
- {
- cout<<individs[i].Genes[j].id<<" ";
- }
- cout<<"Way = "<<individs[i].WayLength()<<endl;
- }
- }
- };
- int main()
- {
- srand(time(NULL));
- cout<<"Введите количество особей"<<endl;
- cin>>IndividsCount;
- cout<<"Введите количсетво городов"<<endl;
- cin>>CitiesCount;
- vector<city> MainCities(CitiesCount);
- for(size_t i = 0; i<CitiesCount; i++)
- {
- int variable;
- MainCities[i].id = i;
- cout<<"Введите абциссу(X) "<<i<<" города"<<endl;
- cin>>variable;
- MainCities[i].x = variable;
- cout<<"Введите ординату(Y) "<<i<<" города"<<endl;
- cin>>variable;
- MainCities[i].y = variable;
- }
- population _FirstPopulation;
- _FirstPopulation.RandomFirstPopulation(MainCities);
- _FirstPopulation.Out();
- population _NewPopulation;
- _FirstPopulation.Selection(2,_NewPopulation);
- cout<<endl;
- _NewPopulation.Out();
- cout<<endl;
- _NewPopulation.Mutation(1/IndividsCount);
- _NewPopulation.Out();
- cout<<endl;
- population ThirdPopulation;
- _NewPopulation.Crossing(ThirdPopulation, 0.6);
- ThirdPopulation.Out();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement