using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Diagnostics;
public int ID { get; set; }
public int X { get; set; }
public int Y {get; set; }
public Point ( int id, int x, int y)
public double DistanceToPoint (Point p)
var temp1 = Math.Pow((this.X - p.X), 2);
var temp2 = Math.Pow((this.Y - p.Y), 2);
var result = Math.Sqrt(temp1+temp2);
public class ResultingTour
public double Distance {get;set;}
public double CumulativeSum {get;set;}
public List<Point> Tour {get;set;}
public ResultingTour (List <Point> tour, double distanceofthetour)
Distance = distanceofthetour;
public class GenericAlgorithm
public List<Point> PointList;
public List<ResultingTour> solutions = new List<ResultingTour>();
public List<ResultingTour> NewSolutions = new List<ResultingTour>();
public double mutation = 5;
public int solutionCount = 100;
public int tournamentCount = 20;
public int stopcrit = 100;
public double meanDistance = 0;
public List<ResultingTour> child;
public bool stop = false;
public int generationCount = 0;
public Random rand = new Random();
public static void Main (string [] args)
GenericAlgorithm ga = new GenericAlgorithm();
ga.rand = new Random(ga.seed);
Stopwatch sw = new Stopwatch();
ga.solutions = ga.Initialization(ga.solutionCount, ga.PointList);
if(ga.NewSolutions.Count == ga.solutionCount)
ga.solutions = new List<ResultingTour>(ga.NewSolutions);
ga.NewSolutions = new List<ResultingTour>();
ga.solutions = ga.FitnessEvaluation(ga.solutions);
List<ResultingTour> Parent = ga.TournamentSelection(ga.tournamentCount, ga.solutions);
ga.SinglePointCrossover(Parent);
foreach(var i in ga.solutions)
TimeSpan ts = sw.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
Console.WriteLine("Tournament Selection");
Console.WriteLine("Best Fit: " + bestFit);
Console.WriteLine("RunTime " + elapsedTime);
ga.rand = new Random(ga.seed);
ga = new GenericAlgorithm();
ga.solutions = ga.Initialization(ga.solutionCount, ga.PointList);
if(ga.NewSolutions.Count == ga.solutionCount)
ga.solutions = new List<ResultingTour>(ga.NewSolutions);
ga.NewSolutions = new List<ResultingTour>();
ga.solutions = ga.FitnessEvaluation(ga.solutions);
List<ResultingTour> Parent = ga.ProportionalSelection(ga.solutions);
ga.SinglePointCrossover(Parent);
foreach(var i in ga.solutions)
elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
Console.WriteLine("Proportional Selection");
Console.WriteLine("Best Fit: " + bestFit);
Console.WriteLine("RunTime " + elapsedTime);
string [] Givendata = {"NAME : att48","COMMENT : 48 capitals of the US (Padberg/Rinaldi)","TYPE : TSP","DIMENSION : 48",
"EDGE_WEIGHT_TYPE : ATT","NODE_COORD_SECTION","1 6734 1453","2 2233 10","3 5530 1424","4 401 841","5 3082 1644","6 7608 4458","7 7573 3716","8 7265 1268","9 6898 1885","10 1112 2049","11 5468 2606","12 5989 2873",
"13 4706 2674","14 4612 2035","15 6347 2683","16 6107 669","17 7611 5184","18 7462 3590","19 7732 4723","20 5900 3561",
"21 4483 3369","22 6101 1110","23 5199 2182","24 1633 2809","25 4307 2322","26 675 1006","27 7555 4819","28 7541 3981",
"29 3177 756","30 7352 4506","31 7545 2801","32 3245 3305","33 6426 3173","34 4608 1198","35 23 2216","36 7248 3779",
"37 7762 4595","38 7392 2244","39 3484 2829","40 6271 2135","41 4985 140","42 1916 1569","43 7280 4899","44 7509 3239",
"45 10 2676","46 6807 2993","47 5185 3258","48 3023 1942"};
PointList = new List<Point>();
for(int i=0; i< Givendata.Length; i++)
string firstPosition = Givendata[i].Split(new char[0],StringSplitOptions.RemoveEmptyEntries)[0];
if (int.TryParse(firstPosition, out j) == true)
int id = Int32.Parse(Givendata[i].Split(new char[0],StringSplitOptions.RemoveEmptyEntries)[0]);
int X = Int32.Parse(Givendata[i].Split(new char[0],StringSplitOptions.RemoveEmptyEntries)[1]);
int Y = Int32.Parse(Givendata[i].Split(new char[0],StringSplitOptions.RemoveEmptyEntries)[2]);
PointList.Add(new Point(id,X,Y));
public double calculateDistance(List<Point> Tour){
for(int i = 0; i < Tour.Count-1; i++){
distance = distance + Tour[i].DistanceToPoint(Tour[i+1]);
static public List<Point> RandomTour(List <Point> Points, Random rand)
var temp = new List<Point>(Points);
List<Point> Tour = new List<Point> ();
int remainingCount = temp.Count-1;
int randomID = rand.Next(remainingCount);
Tour.Add(temp[randomID]);
public List<ResultingTour> Initialization(int numberSolution, List<Point> Points){
solutions = new List<ResultingTour>();
for(int i = 0; i < numberSolution; i++){
List<Point> Tour = RandomTour(Points, rand);
double Distance = calculateDistance(Tour);
solutions.Add(new ResultingTour(Tour, 0));
meanDistance = sum / numberSolution;
public List<ResultingTour> FitnessEvaluation(List<ResultingTour> solutions){
foreach(var i in solutions){
i.Distance = meanDistance/calculateDistance(i.Tour);
public List<ResultingTour> TournamentSelection(int tournamentSize, List<ResultingTour> solutions){
List<ResultingTour> candidates = new List<ResultingTour>(solutions.OrderBy(x => rand.Next()).Take(tournamentSize));
List<ResultingTour> chosen = new List<ResultingTour>();
double totalCandidatesDistance = 0;
foreach(var i in candidates)
totalCandidatesDistance = totalCandidatesDistance + i.Distance;
i.CumulativeSum = totalCandidatesDistance;
double sepPoint = rand.NextDouble() * totalCandidatesDistance;
ResultingTour parent = candidates.FirstOrDefault(i => i.CumulativeSum >= sepPoint);
candidates.Remove(parent);
public List<ResultingTour> ProportionalSelection(List<ResultingTour> solutions){
List<ResultingTour> candidates = new List<ResultingTour>(solutions);
List<ResultingTour> chosen = new List<ResultingTour>();
double totalCandidatesDistance = 0;
foreach(var i in candidates)
totalCandidatesDistance = totalCandidatesDistance + i.Distance;
i.CumulativeSum = totalCandidatesDistance;
double sepPoint = rand.NextDouble() * totalCandidatesDistance;
ResultingTour parent = candidates.FirstOrDefault(i => i.CumulativeSum >= sepPoint);
candidates.Remove(parent);
public void SinglePointCrossover(List<ResultingTour> chosen){
int cutPoint = rand.Next(chosen[0].Tour.Count-1);
child = new List<ResultingTour>();
List<Point> childTourOne = new List<Point>();
List<Point> childTourTwo = new List<Point>();
for(int i = 0; i < chosen[0].Tour.Count; i++){
childTourOne.Add(chosen[0].Tour[i]);
childTourTwo.Add(chosen[1].Tour[i]);
childTourOne.Add(chosen[1].Tour[i]);
childTourTwo.Add(chosen[0].Tour[i]);
double childDistanceOne = meanDistance / calculateDistance(childTourOne);
double childDistanceTwo = meanDistance / calculateDistance(childTourTwo);
child.Add(new ResultingTour(childTourOne,childDistanceOne));
child.Add(new ResultingTour(childTourTwo,childDistanceTwo));
public void SwapMutation(){
ResultingTour childTourOne = child[0];
ResultingTour childTourTwo = child[1];
if(rand.Next(0,100) <= mutation){
int positionOne = rand.Next(childTourOne.Tour.Count-1);
int positionTwo = rand.Next(childTourOne.Tour.Count-1);
Point temp = childTourOne.Tour[positionOne];
childTourOne.Tour[positionOne] = childTourOne.Tour[positionTwo];
childTourOne.Tour[positionTwo] = temp;
positionOne = rand.Next(childTourOne.Tour.Count-1);
positionTwo = rand.Next(childTourOne.Tour.Count-1);
temp = childTourTwo.Tour[positionOne];
childTourTwo.Tour[positionOne] = childTourOne.Tour[positionTwo];
childTourTwo.Tour[positionTwo] = temp;
NewSolutions.Add(childTourOne);
NewSolutions.Add(childTourTwo);
if(generationCount == stopcrit)