private static void Swap(NodeInfo[] nodes, int i, int j)
 {
     var temp = nodes[i];
     nodes[i] = nodes[j];
     nodes[j] = temp;
 }
        static void ReadVRP(string fName)
        {
            string[] lines = File.ReadAllLines(fName);
            string[] header = lines[0].Split(' ');
            numNodes = int.Parse(header[0]);
            numTrucks = int.Parse(header[1]);
            truckCapacity = int.Parse(header[2]);

            string[] whStr = lines[1].Split(' ');
            wareHouseLoc = new Point() {
                x = double.Parse(whStr[1]),
                y = double.Parse(whStr[2])
            };

            /*nodes[0] always refers to the warehouse location
             the actual nodes begin from nodes[1]*/
            nodes = new NodeInfo[numNodes];
            demands = new int[numNodes];
            nodes[0] = new NodeInfo() {
                demand = 0,
                point = wareHouseLoc,
                id = 0
            };

            int currNode = 1;
            for (int i = 2; i <= numNodes; i++) {
                string[] nodeStr = lines[i].Split(' ');
                Point p = new Point() {
                    x = double.Parse(nodeStr[1]),
                    y = double.Parse(nodeStr[2])
                };
                NodeInfo n = new NodeInfo() {
                    id = currNode,
                    demand = int.Parse(nodeStr[0]),
                    point = p
                };
                demands[currNode] = n.demand;
                nodes[currNode] = n;
                currNode++;
            }

            distMatrix = new double[numNodes, numNodes];

            /*calculate the distance between every pair of nodes*/
            for (int i = 0; i < numNodes; i++) {
                for (int j = 0; j < numNodes; j++) {
                    if (i != j) {
                        distMatrix[i, j] = Dist(nodes[i].point, nodes[j].point);
                    }
                }
            }
        }
 private static void Shuffle(NodeInfo[] nodes)
 {
     Random rnd = new Random();
     int numNodes = nodes.Length;
     for (int i = 0; i < nodes.Length; i++)
         Swap(nodes, i, rnd.Next(i, numNodes));
 }
        private static Solution GetInitialFeasibleSolution(NodeInfo[] nodes)
        {
            Solution soln = new Solution();

            int currTruck = 1;
            bool allDemandSatisfied = false;
            HashSet<int> assignedNodes = new HashSet<int>();
            while (!allDemandSatisfied && currTruck <= numTrucks) {
                int availableCap = truckCapacity;
                //iterate over each of the nodes and if any node has not been assigned yet
                //to any truck and the capacity constraints of the truck are satisfied, then
                //assign this node to this truck.
                Route thisRoute = new Route();
                thisRoute.ids.Add(0);
                thisRoute.truckId = currTruck;
                thisRoute.unusedDemand = availableCap;

                for (int i = 0; i < nodes.Length; i++) {
                    if (nodes[i].id != 0) {
                        int thisNodeId = nodes[i].id;
                        int thisNodeDemand = demands[thisNodeId];
                        if (!assignedNodes.Contains(thisNodeId) && availableCap >= thisNodeDemand) {
                            availableCap -= thisNodeDemand;
                            assignedNodes.Add(thisNodeId);

                            thisRoute.ids.Add(thisNodeId);
                            thisRoute.unusedDemand = availableCap;

                            if (assignedNodes.Count == nodes.Length - 1) {
                                allDemandSatisfied = true;
                                break;
                            }
                        }
                    }
                }
                //thisRoute.ids.Add(0); /*to keep it consistent with tsp routines*/
                CalculateRouteDistance(thisRoute);
                soln.routes.Add(thisRoute);
                currTruck++;
            }

            if (!allDemandSatisfied) {
                return null;
            } else {

                //fill up additional trucks with path : 0-0
                int usedTrucks = soln.routes.Count;
                for (int i = 0; i < numTrucks - usedTrucks; i++) {
                    soln.routes.Add(new Route() {
                        ids = new List<int>() {0},
                        totalDist = 0,
                        unusedDemand = truckCapacity,
                        truckId = currTruck++
                    });
                }

                return soln;
            }
        }