private static void ExecuteTabuSearch()
        {
            TSPEnvironment tspEnvironment = new TSPEnvironment();

            tspEnvironment.distances = //Distance matrix, 5x5, used to represent distances
                                       new int[, ] {
                { 0, 1, 3, 4, 5 },
                { 1, 0, 1, 4, 8 },
                { 3, 1, 0, 5, 1 },
                { 4, 4, 5, 0, 2 },
                { 5, 8, 1, 2, 0 }
            };

            //Between cities. 0,1 represents distance between cities 0 and 1, and so on.

            int[] currSolution = new int[] { 0, 1, 2, 3, 4, 0 };   //initial solution
                                                                   //city numbers start from 0
                                                                   // the first and last cities' positions do not change

            int     numberOfIterations = 100;
            int     tabuLength         = 5;
            TspList tabuList           = new TspList(tabuLength);

            int[] bestSol = new int[currSolution.Length]; //this is the best Solution So Far
            Array.Copy(currSolution, 0, bestSol, 0, bestSol.Length);
            int bestCost = tspEnvironment.GetObjectiveFunctionValue(bestSol);

            for (int i = 0; i < numberOfIterations; i++)
            { // perform iterations here
                currSolution = TabuSearch.GetBestNeighbour(tabuList, tspEnvironment, currSolution);
                //printSolution(currSolution);
                int currCost = tspEnvironment.GetObjectiveFunctionValue(currSolution);

                //System.out.println("Current best cost = " + tspEnvironment.getObjectiveFunctionValue(currSolution));

                if (currCost < bestCost)
                {
                    Array.Copy(currSolution, 0, bestSol, 0, bestSol.Length);
                    bestCost = currCost;
                }
            }

            Console.WriteLine("Search done! \nBest Solution cost found = " + bestCost + "\nBest Solution :");

            PrintSolution(bestSol);
        }
        public static int[] GetBestNeighbour(TspList tabuList,
                                             TSPEnvironment tspEnviromnet,
                                             int[] initSolution)
        {
            int[] bestSol = new int[initSolution.Length]; //this is the best Solution So Far
            Array.Copy(initSolution, 0, bestSol, 0, bestSol.Length);
            int  bestCost      = tspEnviromnet.GetObjectiveFunctionValue(initSolution);
            int  city1         = 0;
            int  city2         = 0;
            bool firstNeighbor = true;

            for (int i = 1; i < bestSol.Length - 1; i++)
            {
                for (int j = 2; j < bestSol.Length - 1; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }

                    int[] newBestSol = new int[bestSol.Length]; //this is the best Solution So Far
                    Array.Copy(bestSol, 0, newBestSol, 0, newBestSol.Length);

                    newBestSol = SwapOperator(i, j, initSolution); //Try swapping cities i and j
                                                                   // , maybe we get a bettersolution
                    int newBestCost = tspEnviromnet.GetObjectiveFunctionValue(newBestSol);

                    if ((newBestCost > bestCost || firstNeighbor) && tabuList.tabuList[i, j] == 0)
                    { //if better move found, store it
                        firstNeighbor = false;
                        city1         = i;
                        city2         = j;
                        Array.Copy(newBestSol, 0, bestSol, 0, newBestSol.Length);
                        bestCost = newBestCost;
                    }
                }
            }

            if (city1 != 0)
            {
                tabuList.decrementTabu();
                tabuList.tabuMove(city1, city2);
            }
            return(bestSol);
        }