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; } }