static void Main(string[] args)
        {
#if DEBUG
            const string testingPath = "C:/Users/Nalyd/Desktop/Current Projects/Github/Solving-TSP-using-GA-ACO/TravellingSalesmanProblem/TSP/TSPInstances/berlin52.tsp";
            var          tspInstance = new TspInstance(testingPath);

            var stoppingCriteriaOptions = new StoppingCriteriaOptions
            {
                StoppingCriteriaType = StoppingCriteriaType.SpecifiedIterations,
                MaximumIterations    = 500
            };

            var gaOptions           = new GAOptions(1000, EncodingType.Permutation, SelectionType.Tos, CrossoverType.Cycle, MutationType.SingleSwap, 0.1, 0.3, stoppingCriteriaOptions);
            var tspGeneticAlgorithm = new TspGeneticAlgorithm(gaOptions, tspInstance);
            tspGeneticAlgorithm.Compute(false);

            //var acoOptions = new ACOOptions(4, 3, 2, 0.01, 2.00, stoppingCriteriaOptions);
            //var aco = new TspAntColonyOptimization(acoOptions, tspInstance);
            //aco.Compute();

            Console.ReadLine();
#else
            Parser.Default.ParseArguments <TspOptions>(args).WithParsed(SolveTsp);
#endif
        }
        /// <summary>
        /// Default constructor.
        /// </summary>
        public GAOptions()
        {
            PopulationSize = 100;
            EncodingType   = EncodingType.Permutation;
            SelectionType  = SelectionType.Rws;
            CrossoverType  = CrossoverType.Pmx;
            MutationType   = MutationType.SingleSwap;
            MutationRate   = 0.3f;
            Elitism        = 0;

            // if not specified the GA will use an iteration based stopping criteria, set to a maximum iteration of 1000.
            StoppingCriteriaOptions = new StoppingCriteriaOptions
            {
                StoppingCriteriaType = StoppingCriteriaType.SpecifiedIterations,
                MaximumIterations    = 1000
            };
        }
        /// <summary>
        /// Constructor with parameters.
        /// </summary>
        /// <param name="totalAnts">The total number of ants used in the ACO.</param>
        /// <param name="alpha">Pheromone influence.</param>
        /// <param name="beta">Local node influence.</param>
        /// <param name="rho">Pheromone evaportation coefficient.</param>
        /// <param name="q">Pheromone deposit factor.</param>
        /// <param name="stoppingCriteriaOptions">The stopping critieria options used to stop the algorithm from executing forever.
        /// Optional if not specified, it will use the default which is set to an iteration threshold with maximum of 1000 iterations.</param>
        public ACOOptions(int totalAnts, int alpha, int beta, double rho, double q, StoppingCriteriaOptions stoppingCriteriaOptions = null)
        {
            TotalAnts = totalAnts;
            Alpha     = alpha;
            Beta      = beta;
            Rho       = rho;
            Q         = q;

            if (stoppingCriteriaOptions == null)
            {
                // if not specified the GA will use an iteration based stopping criteria, set to a maximum iteration of 1000.
                StoppingCriteriaOptions = new StoppingCriteriaOptions
                {
                    StoppingCriteriaType = StoppingCriteriaType.SpecifiedIterations,
                    MaximumIterations    = 1000
                };
                return;
            }

            StoppingCriteriaOptions = stoppingCriteriaOptions;
        }
        /// <summary>
        /// Constructor with parameters.
        /// </summary>
        /// <param name="populationSize">The population size.</param>
        /// <param name="encodingType">The encoding type used in the chromosome.</param>
        /// <param name="selectionType">The selection type.</param>
        /// <param name="crossoverType">The crossover type.</param>
        /// <param name="mutationType">The mutation type.</param>
        /// <param name="mutationRate">The mutation rate.</param>
        /// <param name="elitisim">The elistism rate.</param>
        /// <param name="stoppingCriteriaOptions">The stopping critieria options used to stop the algorithm from executing forever.
        /// Optional if not specified, it will use the default which is set to an iteration threshold with maximum of 1000 iterations.</param>
        public GAOptions(int populationSize, EncodingType encodingType, SelectionType selectionType, CrossoverType crossoverType, MutationType mutationType,
                         double mutationRate, double elitisim, StoppingCriteriaOptions stoppingCriteriaOptions = null)
        {
            PopulationSize = populationSize;
            EncodingType   = encodingType;
            SelectionType  = selectionType;
            CrossoverType  = crossoverType;
            MutationType   = mutationType;
            MutationRate   = mutationRate;
            Elitism        = elitisim;

            if (stoppingCriteriaOptions == null)
            {
                // if not specified the GA will use an iteration based stopping criteria, set to a maximum iteration of 1000.
                StoppingCriteriaOptions = new StoppingCriteriaOptions
                {
                    StoppingCriteriaType = StoppingCriteriaType.SpecifiedIterations,
                    MaximumIterations    = 1000
                };
                return;
            }

            StoppingCriteriaOptions = stoppingCriteriaOptions;
        }
        /// <summary>
        /// Solves the TSP problem with the arguments passed from the console.
        /// </summary>
        /// <param name="options">The parsed arguments as <see cref="TspOptions"/> .</param>
        private static void SolveTsp(TspOptions options)
        {
            var tspInstancePath = options.TspInstancePath;
            var tspInstance     = new TspInstance(tspInstancePath);

            var algorithmValue = options.Algorithm;
            EvolutionaryComputationType algorithm;

            if (Enum.TryParse(algorithmValue, true, out algorithm))
            {
                var stoppingCriteriaValue = options.StoppingCriteriaType;
                StoppingCriteriaType stoppingCriteriaType;

                if (Enum.TryParse(stoppingCriteriaValue, true, out stoppingCriteriaType))
                {
                    var stoppingCriteriaOptions = new StoppingCriteriaOptions
                    {
                        StoppingCriteriaType = stoppingCriteriaType
                    };

                    switch (stoppingCriteriaType)
                    {
                    case StoppingCriteriaType.TimeBased:
                        stoppingCriteriaOptions.MinutesPassed = options.StoppingCriteriaTimeMinutes;
                        break;

                    case StoppingCriteriaType.SpecifiedIterations:
                        stoppingCriteriaOptions.MaximumIterations = options.StoppingCriteriaIteration;
                        break;
                    }

                    TimeSpan timeSpan;
                    long     memoryConsumed;
                    long     processMemoryConsumed;
                    var      stopWatch = new Stopwatch();

                    var population = options.Population;
                    switch (algorithm)
                    {
                    // using GA to solve TSP
                    case EvolutionaryComputationType.GeneticAlgorithm:

                        var           selectionOperatorValue = options.SelectionOperator;
                        SelectionType selectionType;
                        if (!Enum.TryParse(selectionOperatorValue, true, out selectionType))
                        {
                            selectionType = SelectionType.Rws;
                        }

                        var           crossoverOperatorType = options.CrossoverOperator;
                        CrossoverType crossoverType;
                        if (!Enum.TryParse(crossoverOperatorType, true, out crossoverType))
                        {
                            crossoverType = CrossoverType.Cycle;
                        }

                        var          mutationOperatorType = options.MutationOperator;
                        MutationType mutationType;
                        if (!Enum.TryParse(mutationOperatorType, true, out mutationType))
                        {
                            mutationType = MutationType.SingleSwap;
                        }

                        var mutationRate = options.MutationRate;
                        var elitisimRate = options.ElitismRate;

                        var genticAlgorithmOptions = new GAOptions(population, EncodingType.Permutation, selectionType, crossoverType, mutationType, mutationRate,
                                                                   elitisimRate, stoppingCriteriaOptions);
                        var tspGeneticAlgorithm = new TspGeneticAlgorithm(genticAlgorithmOptions, tspInstance);

                        var showProgression = options.ShowProgressionComments;

                        stopWatch.Start();
                        tspGeneticAlgorithm.Compute(showProgression);

                        memoryConsumed        = GC.GetTotalMemory(false);
                        processMemoryConsumed = Process.GetCurrentProcess().WorkingSet64;
                        stopWatch.Stop();

                        timeSpan = stopWatch.Elapsed;

                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine("Time_Elapsed: {0}\nGC_Memory_Consumed: {1}\nProcess_Memory_Consumed: {2}\nTotal_Cities: {3}",
                                          timeSpan.ToString("mm\\:ss\\.ff"), memoryConsumed, processMemoryConsumed, tspInstance.CitiesLength);
                        break;

                    // using ACO to solve TSP
                    case EvolutionaryComputationType.AntColonyOptimization:
                        var alpha = options.Alpha;
                        var beta  = options.Beta;
                        var rho   = options.Rho;
                        var q     = options.Q;

                        var antColonyOptimizationOptions = new ACOOptions(population, alpha, beta, rho, q, stoppingCriteriaOptions);
                        var tspAntColonyOptimization     = new TspAntColonyOptimization(antColonyOptimizationOptions,
                                                                                        tspInstance);

                        stopWatch.Start();
                        tspAntColonyOptimization.Compute();

                        memoryConsumed        = GC.GetTotalMemory(false);
                        processMemoryConsumed = Process.GetCurrentProcess().WorkingSet64;
                        stopWatch.Stop();

                        timeSpan = stopWatch.Elapsed;

                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine("Time_Elapsed: {0}\nGC_Memory_Consumed: {1}\nProcess_Memory_Consumed: {2}\nTotal_Cities: {3}",
                                          timeSpan.ToString("mm\\:ss\\.ff"), memoryConsumed, processMemoryConsumed, tspInstance.CitiesLength);
                        break;
                    }
                }
                else
                {
                    throw new Exception("Stopping Criteria specified does not exist. Use --help for more information.");
                }
            }
            else
            {
                throw new Exception("Algorithm specified does not exist. Use --help for more information.");
            }

            Console.ReadLine();
        }