예제 #1
0
        /// <summary>
        /// Test removing adding every customer at every position.
        /// </summary>
        public void DoTestAddRemoveComplete()
        {
            // create a new empty route.
            const int count = 10;

            for (int customerToRemove = 0; customerToRemove < count; customerToRemove++)
            {
                for (int customerToPlaceAfter = 0; customerToPlaceAfter < count; customerToPlaceAfter++)
                {
                    if (customerToRemove != customerToPlaceAfter)
                    {
                        IRoute route = this.BuildRoute(true);
                        if (route != null)
                        { // this part needs testing.
                            for (int customer = 0; customer < count; customer++)
                            {
                                route.InsertAfter(customer - 1, customer);
                                //route.InsertAfterAndRemove(customer - 1, customer, -1);
                            }

                            route.Remove(customerToRemove);
                            route.InsertAfter(customerToPlaceAfter, customerToRemove);
                            //route.InsertAfterAndRemove(customer_to_place_after, customer_to_remove, -1);

                            Assert.IsTrue(route.Contains(customerToPlaceAfter, customerToRemove));
                            Assert.AreEqual(count, route.Count);
                            var customersInRoute = new HashSet <int>(route);
                            Assert.AreEqual(customersInRoute.Count, route.Count);
                        }
                    }
                }
            }
        }
예제 #2
0
 /// <summary>
 /// Removes a given customer.
 /// </summary>
 /// <param name="customer"></param>
 /// <returns></returns>
 public bool Remove(int customer)
 {
     if (customer == 0)
     {
         throw new Exception("Cannot remove depot from depot routes.");
     }
     return(_route.Remove(customer));
 }
예제 #3
0
        /// <summary>
        /// Tests adding customers.
        /// </summary>
        public void DoTestRemove()
        {
            IMultiRoute multiRoute = this.BuildRoute(true);

            Assert.AreEqual(0, multiRoute.Count);
            int count  = 10;
            int routes = 3;

            // test with initializing the routes empty.
            var customersPerRoute = new List <List <int> >();

            Assert.AreEqual(0, multiRoute.Count);
            for (int routeIdx = 0; routeIdx < routes; routeIdx++)
            {
                customersPerRoute.Add(new List <int>());
                int    customerStart = (routeIdx * count);
                IRoute route         = multiRoute.Add();

                for (int customer = customerStart; customer < customerStart + count; customer++)
                {
                    customersPerRoute[routeIdx].Add(customer);
                    route.InsertAfter(customer - 1, customer);
                    //route.InsertAfterAndRemove(customer - 1, customer, -1);
                }
            }

            // remove all the customers.
            while (customersPerRoute.Count > 0)
            {
                int routeIdx    = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(customersPerRoute.Count);
                int customerIdx = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(customersPerRoute[routeIdx].Count);

                int customer = customersPerRoute[routeIdx][customerIdx];
                customersPerRoute[routeIdx].RemoveAt(customerIdx);

                IRoute route = multiRoute.Route(routeIdx);
                route.Remove(customer);

                Assert.AreEqual(customersPerRoute[routeIdx].Count, route.Count);
                Assert.AreEqual(customersPerRoute[routeIdx].Count == 0, route.IsEmpty);
                Assert.AreEqual(true, route.IsRound);
                Assert.AreEqual(route.First, route.Last);

                if (customersPerRoute[routeIdx].Count == 0)
                {
                    customersPerRoute.RemoveAt(routeIdx);
                    multiRoute.Remove(routeIdx);
                }
            }
        }
        /// <summary>
        /// Tries to improve the existing route using CI and return true if succesful.
        /// </summary>
        /// <param name="problem"></param>
        /// <param name="route"></param>
        /// <param name="difference"></param>
        /// <returns></returns>
        public bool Improve(IProblemWeights problem, IRoute route, out double difference)
        {
            bool improvement = false;

            difference = 0;
            if (route.Count > 3)
            {
                // loop over all customers and try cheapest insertion.
                for (int customer = 0; customer < problem.Size; customer++)
                {
                    //string route_string = route.ToString();
                    //IRoute previous = route.Clone() as IRoute;
                    if (route.Contains(customer))
                    {
                        // remove customer and keep position.
                        int next = route.GetNeigbours(customer)[0];
                        route.Remove(customer);

                        // insert again.
                        ArbitraryInsertionSolver.InsertOne(problem, route, customer, out difference);

                        if (!route.IsValid())
                        {
                            throw new Exception();
                        }
                        if (route.GetNeigbours(customer)[0] != next &&
                            difference < 0)
                        { // another customer was found as the best, improvement is succesful.
                            improvement = true;
                            break;
                        }
                    }
                }
            }
            return(improvement);
        }
예제 #5
0
        /// <summary>
        /// Test removing customers.
        /// </summary>
        public void DoTestRemove()
        {
            // create a new empty route.
            const int count     = 100;
            IRoute    route     = this.BuildRoute(0, true);
            var       customers = new List <int>();

            if (route != null)
            { // this part needs testing!
                customers.Add(0);
                for (int customer = 1; customer < count; customer++)
                {
                    route.InsertAfter(customer - 1, customer);
                    //route.InsertAfterAndRemove(customer - 1, customer, -1);
                    customers.Add(customer);
                }

                // remove customers.
                while (customers.Count > 0)
                {
                    int customerIdx = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(
                        customers.Count);
                    int customer = customers[customerIdx];
                    customers.RemoveAt(customerIdx);

                    route.Remove(customer);

                    Assert.AreEqual(customers.Count, route.Count);
                    Assert.AreEqual(customers.Count == 0, route.IsEmpty);
                    Assert.AreEqual(true, route.IsRound);
                    Assert.AreEqual(route.Last, route.First);
                }
            }

            route     = this.BuildRoute(true);
            customers = new List <int>();
            if (route != null)
            { // this part needs testing!
                for (int customer = 0; customer < count; customer++)
                {
                    route.InsertAfter(customer - 1, customer);
                    //route.InsertAfterAndRemove(customer - 1, customer, -1);
                    customers.Add(customer);
                }

                // remove customers.
                while (customers.Count > 0)
                {
                    int customerIdx = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(
                        customers.Count);
                    int customer = customers[customerIdx];
                    customers.RemoveAt(customerIdx);

                    route.Remove(customer);

                    Assert.AreEqual(customers.Count, route.Count);
                    Assert.AreEqual(customers.Count == 0, route.IsEmpty);
                    Assert.AreEqual(true, route.IsRound);
                    Assert.AreEqual(route.Last, route.First);
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Applies a local search strategy.
        /// </summary>
        /// <param name="problem"></param>
        /// <param name="route"></param>
        /// <returns></returns>
        public static void CalculateRePlaceOptHelper(
            IProblemWeights problem, IRoute route)
        {
            //bool improvement = true;
            //while (improvement)
            //{
            //// reset improvement flag.
            //improvement = false;

            // try re-placement of one customer.
            int before = -1;
            //int after = -1;
            int found_customer = -1;

            // loop over all customers and try to place it better.
            HashSet <int> customers_to_place = new HashSet <int>(route);

            foreach (int customer_to_place in customers_to_place)
            {
                // find the best place.
                double current_cost    = -1;
                double other_cost      = double.MaxValue;
                int    previous_before = -1;
                int    previous        = -1;
                foreach (int customer in route)
                {
                    if (previous >= 0 && previous_before >= 0)
                    {
                        if (previous == customer_to_place)
                        {
                            current_cost = problem.Weight(previous_before, previous) +
                                           problem.Weight(previous, customer);
                        }
                        else if (previous_before != customer_to_place &&
                                 customer != customer_to_place)
                        { // calculate the cost.
                            double cost = problem.Weight(previous_before, customer_to_place) +
                                          problem.Weight(customer_to_place, previous);
                            if (cost < other_cost)
                            {
                                other_cost = cost;

                                before = previous_before;
                                //after = previous;
                                found_customer = customer;
                            }
                        }
                    }

                    previous_before = previous;
                    previous        = customer;
                }

                // determine if the cost is better.
                if (current_cost > other_cost)
                { // the current cost is better.
                    route.Remove(found_customer);
                    //route.InsertAfterAndRemove(before, found_customer, after);
                    route.InsertAfter(before, found_customer);
                    break;
                }
                else
                { // current cost is not better.
                    before = -1;
                    //after = -1;
                    found_customer = -1;
                }
            }

            //if (found_customer >= 0)
            //{ // a found customer.
            //    improvement = true;
            //}
            //}
        }
예제 #7
0
        /// <summary>
        /// Tries to improve the existing route using CI and return true if succesful.
        /// </summary>
        /// <param name="problem"></param>
        /// <param name="route"></param>
        /// <param name="difference"></param>
        /// <returns></returns>
        public bool Improve(IProblemWeights problem, IRoute route, out double difference)
        {
            bool improvement = false;

            difference = 0;
            if (route.Count > 3)
            {
                // loop over all customers and try cheapest insertion.
                for (int customer = 0; customer < problem.Size; customer++)
                {
                    //string route_string = route.ToString();
                    //IRoute previous = route.Clone() as IRoute;
                    if (route.Contains(customer))
                    {
                        // remove customer and keep position.
                        int next = route.GetNeigbours(customer)[0];
                        route.Remove(customer);

                        // insert again.
                        ArbitraryInsertionSolver.InsertOne(problem, route, customer, out difference);

                        if (!route.IsValid())
                        {
                            throw new Exception();
                        }
                        if (route.GetNeigbours(customer)[0] != next
                            && difference < 0)
                        { // another customer was found as the best, improvement is succesful.
                            improvement = true;
                            break;
                        }
                    }
                }
            }
            return improvement;
        }
예제 #8
0
        /// <summary>
        /// Applies a local search strategy.
        /// </summary>
        /// <param name="problem"></param>
        /// <param name="route"></param>
        /// <returns></returns>
        public static void CalculateRePlaceOptHelper(
            IProblemWeights problem, IRoute route)
        {
            //bool improvement = true;
            //while (improvement)
            //{
            //// reset improvement flag.
            //improvement = false;

            // try re-placement of one customer.
            int before = -1;
            int after = -1;
            int found_customer = -1;

            // loop over all customers and try to place it better.
            HashSet<int> customers_to_place = new HashSet<int>(route);
            foreach (int customer_to_place in customers_to_place)
            {
                // find the best place.
                double current_cost = -1;
                double other_cost = double.MaxValue;
                int previous_before = -1;
                int previous = -1;
                foreach (int customer in route)
                {
                    if (previous >= 0 && previous_before >= 0)
                    {
                        if (previous == customer_to_place)
                        {
                            current_cost = problem.Weight(previous_before, previous) +
                                problem.Weight(previous, customer);
                        }
                        else if (previous_before != customer_to_place &&
                            customer != customer_to_place)
                        { // calculate the cost.
                            double cost = problem.Weight(previous_before, customer_to_place) +
                                problem.Weight(customer_to_place, previous);
                            if (cost < other_cost)
                            {
                                other_cost = cost;

                                before = previous_before;
                                after = previous;
                                found_customer = customer;
                            }
                        }
                    }

                    previous_before = previous;
                    previous = customer;
                }

                // determine if the cost is better.
                if (current_cost > other_cost)
                { // the current cost is better.
                    route.Remove(found_customer);
                    //route.InsertAfterAndRemove(before, found_customer, after);
                    route.InsertAfter(before, found_customer);
                    break;
                }
                else
                { // current cost is not better.
                    before = -1;
                    after = -1;
                    found_customer = -1;
                }
            }

            //if (found_customer >= 0)
            //{ // a found customer.
            //    improvement = true;
            //}
            //}
        }