Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
3ZadeSSG committed Aug 7, 2018
1 parent b87b3a0 commit 1b41ac0
Show file tree
Hide file tree
Showing 4 changed files with 897 additions and 0 deletions.
310 changes: 310 additions & 0 deletions TSP.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
#include<iostream>
#include<vector>
#include<algorithm>
#include<stdint.h>
#include<string.h>
#include<random>
#define random (rand()/(double)RAND_MAX)
#define ll int64_t
#define Add push_back
using namespace std;
//=======================================================================//
//=====================Class Definition of Graph=========================//
//=======================================================================//
class Graph{
ll TotalVertices;
vector<pair<ll,ll> >Vertices; //pair of vertices between which path exists
vector<pair<ll,ll> >Edges; //first one is weight and second one is index corresponding to the vertex pair
vector<ll>OptimalPath; //this will store the path for which TotalCost variable's value will be set
ll TotalCost;
public:
Graph(ll TotalVertices){
TotalCost=0;
this->TotalVertices=TotalVertices;
}
Graph(){ //Add entries for the vertice and edges, addEdge(Vertex1,Vertex2,WeightOfEdge)
this->TotalVertices=5;
addEdge(1,2,7);
addEdge(1,3,50);
addEdge(1,4,6);
addEdge(1,5,4);
addEdge(2,3,11);
addEdge(2,4,5);
addEdge(2,5,15);
addEdge(3,4,8);
addEdge(3,5,2);
addEdge(4,5,27);
}
void addEdge(ll v1,ll v2,ll weight); //given verices and edge weight betwene them, add a new entry into graph
void display(void); //display the current graph contents
ll getCost(vector<ll>Path); //give a path funciton will reutrn the travel cost or 0 in case path is not valid
ll getCost(); //in case the optimal path is set then return the cost of that path
ll getTotalVertices(); //return total number of vertices in the Graph
bool isPathValid(vector<ll>Path); //for checking is path is valid
void setPath(vector<ll>OptimalPath); //set the current optimal path as received from the calling function
ll getDecesionVariables(); //return the number of decesion variables, TotalVertices in this case;
};
//===========================================================//
//===================Class definition of Individual==========//
//===========================================================//
class Individual{
vector<ll>Gene; //Gene will hold the path
ll DecesionVariables; //Total number of vertices in this case
Graph Properties; //An ofject of Graph type to calculate the path cost and find validity of an randomly choosen path
public:
Individual(){
Properties=Graph(); //Create a Graph type object
DecesionVariables=Properties.getDecesionVariables();
Gene.resize(DecesionVariables,0); //Resize the Gene array to the size of TotalVertices and initialize them with 0
do{
Gene.clear();
Gene.resize(DecesionVariables,0);
for(ll i=0;i<Gene.size();i++){
ll vertex=(random*DecesionVariables)+1;
while(find(Gene.begin(),Gene.end(),vertex)!=Gene.end()){ //if randomly created vertex is already added in Gene then create a new one
vertex=(random*DecesionVariables)+1;
}
Gene[i]=vertex; //add created valid vertex into the Gene
}
}while(!Properties.isPathValid(Gene)); //check if the created path is valid
Properties.setPath(Gene); //if path(Gene) is valid then set this path as the optimal path for the Graph object
this->Fitness=Properties.getCost(); //get the cost of path form the Graph object corresponding to this individual's Gene
}
ll Fitness;
ll getFitness();
vector<ll>getGene(); //return the Gene array
bool isGeneValid(vector<ll>Array); //given an array of path check if it is valid path or not
void setGene(vector<ll>Gene); //set the Gene of this individual equal to the received path array
void displayIndividual();
ll getDecesionVariables();
};
bool compare(const Individual & l,const Individual & r){ //this compartor function is required for 'sort()' function defined in <algorithm>
return l.Fitness < r.Fitness; //for sorting objects according to one of their data members (Cost/Fitness in this case)
}
//===========================================================//
//===================Class definition of SimulateGA==========//
//===========================================================//
class SimulateGA{
vector<Individual>Population; //List of population
ll PopulationSize; //Initial population size (as for now in this program this must be even)
public:
SimulateGA(int PopulationSize){
this->PopulationSize=PopulationSize; //Initialize the population with given size
Population.resize(PopulationSize); //Resize the population array to the Population size
}
void doCrossover();
vector<ll> doMutation(vector<ll>Array); //Mutation on the passed array of genes
void displayPopulation();
void displayFittest();
};
//===========================================================//
//==============Member functions for SimulateGA Class========//
//===========================================================//
void SimulateGA::displayPopulation(){
for(int i=0;i<Population.size();i++){
cout<<endl;
Population[i].displayIndividual();
}
}
void SimulateGA::displayFittest(){
cout<<"\nFittest Individual: \n";
(*min_element(Population.begin(),Population.end(),compare)).displayIndividual();//display the best cost(Min fitness value in this case) individual
}
void SimulateGA::doCrossover(){
vector<Individual>NewPopulation;
ll range=Population[0].getDecesionVariables();
vector<pair<ll,ll> >MatingPair;
for(ll i=0;i<PopulationSize/2;i++){ //create the mating pair from while population by randomly selecting them
ll p1=random*PopulationSize;
ll p2=random*PopulationSize;
MatingPair.Add(make_pair(p1,p2));
}
//select mating pair in best to worst order
/*sort(Population.begin(),Population.end(),compare); //sort the population so the fittest ones will be at top
for(ll i=0;i<PopulationSize/2;i++){ //create the mating pair from while population
ll p1=i; //select the most fit ones to be added in mating pair
ll p2=i+1;
MatingPair.Add(make_pair(p1,p2));
}*/
for(ll index=0;index<MatingPair.size();index++){
Individual Parent1=Population[MatingPair[index].first]; //Select 1st parent from population as per mating pair
Individual Parent2=Population[MatingPair[index].second]; //Select 2nd parent from population as per mating pair
vector<ll>Gene1=Parent1.getGene(); //Obtain genes of first parent
vector<ll>Gene2=Parent2.getGene(); //Obtain genes of the second parent
vector<ll>Points;
Points.Add(random*Gene1.size()); //select two random points
Points.Add(random*Gene2.size());
sort(Points.begin(),Points.end()); //sort the random points so that they can be used as a range for swapping
vector<ll>ChildGene1(range);
vector<ll>ChildGene2(range);
for(ll i=Points[0];i<Points[1];i++){ //add the genes of parents within the selected range
ChildGene1[i]=Gene1[i];
ChildGene2[i]=Gene2[i];
}
for(ll i=0;i<range;i++){ //add remaining genes in such a way that no two verties are repeated
if(ChildGene1[i]==0){
ll id=0;
ll flag=0;
do{
if(find(ChildGene1.begin(),ChildGene1.end(),Gene2[id])==ChildGene1.end()){
ChildGene1[i]=Gene1[id];
flag=1;
}
id++;
}while(flag==0);
}
if(ChildGene2[i]==0){
ll id=0;
ll flag=0;
do{
if(find(ChildGene2.begin(),ChildGene2.end(),Gene1[id])==ChildGene2.end()){
ChildGene1[i]=Gene1[id];
flag=1;
}
id++;
}while(flag==0);
}
}
ChildGene1=doMutation(ChildGene1); //do mutaiton on this gene array of both childs
ChildGene2=doMutation(ChildGene2);
vector<Individual>Family;
Family.Add(Parent1); //add both parnets to family list
Family.Add(Parent2);
Individual Child1;
Individual Child2;
if(Child1.isGeneValid(ChildGene1)){ //add children if they have valid gene
Child1.setGene(ChildGene1);
Family.Add(Child1);
}
if(Child1.isGeneValid(ChildGene2)){
Child1.setGene(ChildGene2);
Family.Add(Child2);
}
sort(Family.begin(),Family.end(),compare); //sort the family based on their fitness (lower fitness here in this case because of minimization problem)
NewPopulation.Add(Family[0]); //select top 2 individual whether its parent or child and add them into new list of population
NewPopulation.Add(Family[1]);
}
Population.clear();
Population=NewPopulation; //replace the current population with new population
}
vector<ll> SimulateGA::doMutation(vector<ll>Array){
Individual Person;
ll r1=random*Array.size();
ll r2=random*Array.size();
vector<ll>Temp=Array;
Temp=Array;
ll t=Temp[r1];
Temp[r1]=Temp[r2];
Temp[r2]=t;
return Temp;
}
//===========================================================//
//==============Member functions for Individual Class========//
//===========================================================//
ll Individual::getFitness(){
return Fitness;
}
vector<ll> Individual::getGene(){
return Gene;
}
bool Individual::isGeneValid(vector<ll>Array){
if(Properties.isPathValid(Array)){
return true;
}
return false;
}
void Individual::setGene(vector<ll>Gene){
this->Gene=Gene;
Properties.setPath(Gene);
this->Fitness=Properties.getCost();
}
void Individual::displayIndividual(){
cout<<"Path: ";
for(int i=0;i<Gene.size();i++){
cout<<Gene[i]<<" ";
}
cout<<"Fitness: "<<Fitness;
}
ll Individual::getDecesionVariables(){
return this->DecesionVariables;
}
//===========================================================//
//================Member functions for Graph Class===========//
//===========================================================//
bool Graph::isPathValid(vector<ll>Path){
if(getCost(Path)==0){
return false;
}
return true;
}
void Graph::addEdge(ll v1,ll v2,ll weight){
Vertices.Add(make_pair(v1,v2));
Edges.Add(make_pair(weight,Vertices.size()-1));
}
void Graph::display(void){
cout<<"\nGraph Contents: \n";
for(int i=0;i<Edges.size();i++){
cout<<"Vertex: "<<Vertices[i].first<<" Vertex: "<<Vertices[i].second<<" Edge: "<<Edges[i].first<<endl;
}
}
ll Graph::getCost(vector<ll>Path){
ll cost=0;
vector<ll>visited;
for(ll i=0;i<Path.size()-1;i++){
ll v1=Path[i];
ll v2=Path[i+1];
if(find(visited.begin(),visited.end(),v1)==visited.end()){
visited.Add(v1);
}
else{
return 0;
}
if(i==Path.size()-2){
if(find(visited.begin(),visited.end(),v2)==visited.end()){
visited.Add(v2);
}
else{
return 0;
}
}
if(find(Vertices.begin(),Vertices.end(),make_pair(v1,v2))<Vertices.end()){
cost+=Edges[(find(Vertices.begin(),Vertices.end(),make_pair(v1,v2))-Vertices.begin())].first;
}
else if(find(Vertices.begin(),Vertices.end(),make_pair(v2,v1))<Vertices.end()){
cost+=Edges[(find(Vertices.begin(),Vertices.end(),make_pair(v2,v1))-Vertices.begin())].first;
}
else{
//cout<<"\nNo path found! ";
return 0;
}
}
return cost;
}
ll Graph::getTotalVertices(){
return TotalVertices;
}
void Graph::setPath(vector<ll>OptimalPath){
this->OptimalPath=OptimalPath;
TotalCost=getCost(OptimalPath);
}
ll Graph::getCost(){
return TotalCost;
}
ll Graph::getDecesionVariables(){
return TotalVertices;
}
int main(){
SimulateGA g=SimulateGA(100);
cout<<"\n==================Initial Population==============\n";
//g.displayPopulation();
g.displayFittest();
for(int i=0;i<10;i++){
cout<<"\n==================Generation "<<i+1<<"==============\n";
g.doCrossover();
//g.displayPopulation();
g.displayFittest();
}
//g.displayPopulation();
g.displayFittest();
return 0;
}
49 changes: 49 additions & 0 deletions TSP_Input_2
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Graph(){
this->TotalVertices=17;
addEdge(1,2,633);addEdge(1,3,257);addEdge(1,4,91);addEdge(1,5,412);addEdge(1,6,150);addEdge(1,7,80);addEdge(1,8,134);addEdge(1,9,259);
addEdge(1,10,505);addEdge(1,11,353);addEdge(1,12,324);addEdge(1,13,70);addEdge(1,14,211);addEdge(1,15,268);addEdge(1,16,246);addEdge(1,17,121);
//=================================================================================================================//
addEdge(2,3,390);addEdge(2,4,661);addEdge(2,5,227);addEdge(2,6,488);addEdge(2,7,572);addEdge(2,8,530);addEdge(2,9,555);addEdge(2,10,289);
addEdge(2,11,282);addEdge(2,12,638);addEdge(2,13,567);addEdge(2,14,466);addEdge(2,15,420);addEdge(2,16,745);addEdge(2,17,518);
//=================================================================================================================//
addEdge(3,4,228);addEdge(3,5,169);addEdge(3,6,112);addEdge(3,7,196);addEdge(3,8,154);addEdge(3,9,372);addEdge(3,10,262);
addEdge(3,11,110);addEdge(3,12,437);addEdge(3,13,191);addEdge(3,14,74);addEdge(3,15,53);addEdge(3,16,472);addEdge(3,17,142);
//=================================================================================================================//
addEdge(4,5,383);addEdge(4,6,120);addEdge(4,7,77);addEdge(4,8,105);addEdge(4,9,175);addEdge(4,10,476);addEdge(4,11,324);
addEdge(4,12,240);addEdge(4,13,27);addEdge(4,14,182);addEdge(4,15,239);addEdge(4,16,237);addEdge(4,17,84);
//=================================================================================================================//
addEdge(5,6,267);addEdge(5,7,351);addEdge(5,8,309);addEdge(5,9,338);addEdge(5,10,196);addEdge(5,11,61);
addEdge(5,12,421);addEdge(5,13,346);addEdge(5,14,243);addEdge(5,15,199);addEdge(5,16,528);addEdge(5,17,297);
//=================================================================================================================//
addEdge(6,7,63);addEdge(6,8,34);addEdge(6,9,264);addEdge(6,10,360);addEdge(6,11,208);addEdge(6,12,329);
addEdge(6,13,83);addEdge(6,14,105);addEdge(6,15,123);addEdge(6,16,364);addEdge(6,17,35);
//=================================================================================================================//
addEdge(7,8,29);addEdge(7,9,232);addEdge(7,10,444);addEdge(7,11,292);addEdge(7,12,297);
addEdge(7,13,47);addEdge(7,14,150);addEdge(7,15,207);addEdge(7,16,332);addEdge(7,17,29);
//=================================================================================================================//
addEdge(8,9,249);addEdge(8,10,402);addEdge(8,11,250);addEdge(8,12,314);addEdge(8,13,68);
addEdge(8,14,108);addEdge(8,15,165);addEdge(8,16,349);addEdge(8,17,36);
//=================================================================================================================//
addEdge(9,10,495);addEdge(9,11,352);addEdge(9,12,95);addEdge(9,13,189);
addEdge(9,14,326);addEdge(9,15,383);addEdge(9,16,202);addEdge(9,17,236);
//=================================================================================================================//
addEdge(10,11,154);addEdge(10,12,578);addEdge(10,13,439);addEdge(10,14,336);
addEdge(10,15,240);addEdge(10,16,685);addEdge(10,17,390);
//=================================================================================================================//
addEdge(11,12,435);addEdge(11,13,287);addEdge(11,14,184);
addEdge(11,15,140);addEdge(11,16,542);addEdge(11,17,238);
//=================================================================================================================//
addEdge(12,13,254);addEdge(12,14,391);addEdge(12,15,448);
addEdge(12,16,157);addEdge(12,17,301);
//=================================================================================================================//
addEdge(13,14,145);addEdge(13,15,202);
addEdge(13,16,289);addEdge(13,17,55);
//=================================================================================================================//
addEdge(14,15,57);addEdge(14,16,426);
addEdge(14,17,96);
//=================================================================================================================//
addEdge(15,16,483);
addEdge(15,17,153);
//=================================================================================================================//
addEdge(16,17,336);
}
Loading

0 comments on commit 1b41ac0

Please sign in to comment.