Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
 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();
 }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }