public Solution NearestNeighbour(Customer[] customers, int deliverers) { Deliveryman[] d = new Deliveryman[deliverers]; for (int t = 0; t < d.Length; t++) { d[t] = new Deliveryman(); } Point cur_pos = new Point(0, 0); for (int x = 0; x < customers.Length / deliverers; x++) { int nearest_neighbour = -1; int best_dist = int.MaxValue; for (int t = 0; t < customers.Length; t++) { if (!visited[t]) { int dist = Math.Abs(customers[t].X - cur_pos.X) + Math.Abs(customers[t].Y - cur_pos.Y); if (dist < best_dist) { nearest_neighbour = customers[t].ID; best_dist = dist; } } } d[0].route.Add(nearest_neighbour); visited[nearest_neighbour - 1] = true; cur_pos = new Point(customers[nearest_neighbour - 1].X, customers[nearest_neighbour - 1].Y); } return new Solution(customers, d); }
public Solution EqualNeighbour(Customer[] customers, int deliverers) { Deliveryman[] ds = new Deliveryman[deliverers]; for (int t = 0; t < ds.Length; t++) { ds[t] = new Deliveryman(); } for (int x = 0; x < customers.Length; x++) { int laziest = int.MaxValue; Deliveryman l = null; foreach (Deliveryman d in ds) { int score = 0; Point cur_pos = new Point(0, 0); foreach (int z in d.route) { int dist = Math.Abs(cs[z - 1].X - cur_pos.X) + Math.Abs(cs[z - 1].Y - cur_pos.Y); score += dist; cur_pos = new Point(cs[z - 1].X, cs[z - 1].Y); } score += Math.Abs(cur_pos.X - 0) + Math.Abs(cur_pos.Y - 0); if (score < laziest) { laziest = score; l = d; } } for (int t = 0; t < ds.Length; t++) { if (ds[t] == l) ds[t].route.Add(customers[x].ID); } } return new Solution(customers, ds); }
public Solution(Customer[] customers, Deliveryman[] d) { // customers, or 'map' of the problem cs = customers; // representation of the routes, by customer id's rs = d; // number of deliverymen n = d.Length; // rnd rnd = new Random(); }
public Solution NextNeighbor(int g) { //Swap two nodes in the same route if (g == 0) { Deliveryman[] rx = new Deliveryman[rs.Length]; for (int i = 0; i < rs.Length; i++) { rx[i] = new Deliveryman(); foreach (int c in rs[i].route) rx[i].route.Add(c); } // Rnd route and nodes int rnd_route = rnd.Next(0, n); int rnd_nodeA = rnd.Next(0, rx[rnd_route].route.Count); int rnd_nodeB = rnd.Next(0, rx[rnd_route].route.Count); // Swap nodes int a = rx[rnd_route].route[rnd_nodeA]; rx[rnd_route].route[rnd_nodeA] = rx[rnd_route].route[rnd_nodeB]; rx[rnd_route].route[rnd_nodeB] = a; // Return new Solution return new Solution(cs, rx); } //Move a node from one route to another else if (g == 1) { Random r2 = new Random(); Deliveryman[] rx = new Deliveryman[rs.Length]; for (int i = 0; i < rs.Length; i++) { rx[i] = new Deliveryman(); foreach (int c in rs[i].route) rx[i].route.Add(c); } int rnd_first = r2.Next(0, n); //Deliveryman to take customer from int l_first = rx[rnd_first].route.Count(); int rnd_second = r2.Next(0, n); //Deliveryman to put customer in int node_first = r2.Next(0, l_first); //Customer to move //Add customer to new route and remove from initial one only if first route would not end up empty if (rx[rnd_first].route.Count() - 1 > 1) { int r = rnd.Next(0, rx[rnd_second].route.Count); rx[rnd_second].route.Insert(r, rx[rnd_first].route[node_first]); //rx[rnd_second].route.Add(rx[rnd_first].route[node_first]); rx[rnd_first].route.RemoveAt(node_first); } //Return new solution return new Solution(cs, rx); } //Move node from one route to closest node from another route in the route else if (g == 2) { Deliveryman[] rx = new Deliveryman[rs.Length]; for (int i = 0; i < rs.Length; i++) { rx[i] = new Deliveryman(); foreach (int c in rs[i].route) rx[i].route.Add(c); } // randomly select two different routes int route_a = rnd.Next(0, rx.Length); int route_b = rnd.Next(0, rx.Length); if (rx[route_a].route.Count > 0 && rx[route_b].route.Count > 0) { // select random node from route a int index = rnd.Next(0, rx[route_a].route.Count - 1); int node_a = rx[route_a].route.ElementAt(index); // select node from route b that is closest to node a int closest_node = 0; int closest_value = int.MaxValue; foreach (int node in rx[route_b].route) { int dist = (Math.Abs(cs[node_a - 1].X - cs[node - 1].X) + Math.Abs(cs[node_a - 1].Y - cs[node - 1].Y)); if (closest_value > dist && node != node_a) { closest_node = node; closest_value = dist; } } // add this node to route a rx[route_a].route.Insert(index, closest_node); rx[route_b].route.Remove(closest_node); } // return solution return new Solution(cs, rx); } else return new Solution(cs, rs); }
public Solution RandomMultiple(Customer[] customers, int amount) { Deliveryman[] work = new Deliveryman[amount]; int path_length = 0; if (customers.Length % amount == 0) path_length = customers.Length / amount; else path_length = customers.Length / amount + 1; for (int t = 0; t < work.Length; t++) { work[t] = new Deliveryman(); } //Random r = new Random(); for (int t = 0; t < customers.Length; t++) { int x = r.Next(0, work.Length); work[x].route.Add(customers[t].ID); } return new Solution(customers, work); }