Ejemplo n.º 1
0
        private int?SelectX(
            IProblem problem, FixedSymmetricRoute route, EdgeSet X, EdgeSet Y, EdgeList x, int customer, HashSet <int> exceptions)
        {
            // select the only two edges that have the given customer in the given route.
            int[] neigbours = route.GetNeigbours(customer);
            int   previous  = neigbours[0];
            int   next      = neigbours[1];

            int?   best_neighour = null;
            double best_weight   = double.MinValue;

            if (previous > 0 && (exceptions == null || !exceptions.Contains(previous)) &&
                !x.Contains(customer, previous))
            //&& !X.Contains(customer, previous))
            //&& !Y.Contains(customer, previous))
            {
                //if (x.Count > 2)
                //{
                double weight = problem.Weight(customer, previous);
                if (weight > best_weight)
                {
                    best_neighour = previous;
                    best_weight   = weight;
                }
                //}
                //else
                //{
                return(previous);
                //}
            }
            if (next > 0 && (exceptions == null || !exceptions.Contains(next)) &&
                !x.Contains(customer, next))
            //&& !X.Contains(customer, previous))
            //&& !Y.Contains(customer, previous))
            {
                //if (x.Count > 2)
                //{
                double weight = problem.Weight(customer, next);
                if (weight > best_weight)
                {
                    best_neighour = next;
                    best_weight   = weight;
                }
                //}
                //else
                //{
                return(next);
                //}
            }
            return(best_neighour);
        }
Ejemplo n.º 2
0
        ///// <summary>
        ///// A naive selection method.
        ///// </summary>
        ///// <param name="problem"></param>
        ///// <param name="route"></param>
        ///// <param name="X"></param>
        ///// <param name="Y"></param>
        ///// <param name="x"></param>
        ///// <param name="y"></param>
        ///// <param name="exceptions"></param>
        ///// <returns></returns>
        //private int? SelectY(
        //    IProblem problem, FixedSymmetricRoute route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y, HashSet<int> exceptions)
        //{
        //    int from = x.Last.To;

        //    // search an edge with weight smaller than g.
        //    // VERY NAIVE METHOD!
        //    List<int> test_list = new List<int>();
        //    float best_extra = float.MaxValue;
        //    int? best_customer = null;
        //    for (int other_customer = 0; other_customer < problem.Size; other_customer++)
        //    {
        //        if (other_customer != from && exceptions != null && !exceptions.Contains(other_customer))
        //        {
        //            if (!x.Contains(from, other_customer)
        //                && !route.Contains(from, other_customer))
        //            //&& !Y.Contains(from, other_customer))
        //            //&& !X.Contains(from, other_customer))
        //            {
        //                float extra = problem.Weight(from, other_customer);
        //                if (y.Weight + extra < x.Weight)
        //                {
        //                    if (x.Count < 3)
        //                    {
        //                        best_customer = other_customer;
        //                        best_extra = extra;
        //                        break;
        //                    }
        //                    test_list.Add(other_customer);
        //                    if (extra < best_extra)
        //                    {
        //                        best_customer = other_customer;
        //                        best_extra = extra;
        //                        if (x.Count < 3)
        //                        {
        //                            break;
        //                        }
        //                    }
        //                }
        //            }
        //        }
        //    }
        //    return best_customer;
        //}

        /// <summary>
        /// Selects with special priority.
        /// </summary>
        /// <param name="problem"></param>
        /// <param name="route"></param>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="exceptions"></param>
        /// <returns></returns>
        private int?SelectY(
            IProblem problem, FixedSymmetricRoute route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y, HashSet <int> exceptions)
        {
            int from = x.Last.To;

            // search an edge with weight smaller than g.
            //float best_priority = float.MinValue;
            int?best_customer = null;

            foreach (Edge edge in _sparse_set.GetFor(from))
            {
                if (exceptions == null ||
                    !exceptions.Contains(edge.To))
                {
                    if (edge.From != edge.To &&
                        !x.Contains(edge) &&
                        !y.Contains(edge) &&
                        !route.Contains(edge.From, edge.To)
                        //&& !Y.Contains(from, other_customer))
                        && !X.Contains(from, edge.To))
                    {
                        double extra = edge.Weight;
                        if (y.Weight + extra < x.Weight)
                        {
                            //if (x.Count < 2)
                            //{
                            best_customer = edge.To;
                            break;
                            //}

                            //// calculate priority.
                            //int? x_other = this.SelectX(problem, route, X, Y, x, edge.To, null);
                            //float priority = float.MinValue;
                            //if (x_other != null)
                            //{
                            //    float x_other_weight = problem.Weight(edge.To, x_other.Value);
                            //    priority = x_other_weight - extra;
                            //}
                            //if (priority > best_priority)
                            //{
                            //    best_customer = edge.To;
                            //    best_priority = priority;
                            //}
                        }
                    }
                }
            }
            return(best_customer);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Replaces some edges with a list of other edges.
        /// </summary>
        /// <param name="route"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        private FixedSymmetricRoute Replace(FixedSymmetricRoute route, EdgeList x, EdgeList y)
        {
            FixedSymmetricRoute route_new = route.Clone() as FixedSymmetricRoute;

            for (int idx = 0; idx < x.Count; idx++)
            {
                Edge x_edge = x[idx];
                route_new.Remove(x_edge.From, x_edge.To);
            }
            for (int idx = 0; idx < x.Count; idx++)
            {
                Edge y_edge = y[idx];
                route_new.Add(y_edge.From, y_edge.To);
            }
            //if (!route_new.IsValidNew() && route_new.IsValid())
            //{
            //    Debug.Write(string.Empty);
            //}
            //else
            //{
            //    Debug.Write(string.Empty);
            //}
            return(route_new);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Does the actual solving.
        /// </summary>
        /// <param name="problem"></param>
        /// <returns></returns>
        protected override IRoute DoSolve(IProblem problem)
        {
            // convert to a symetric problem if needed.
            IProblem _problem = problem;
            if (!_problem.Symmetric)
            {
                _problem = Convertor.ConvertToSymmetric(_problem);
                _was_asym = true;
            }

            // create the list of customers.
            _customers = new List<int>();
            for (int customer = 0; customer < _problem.Size; customer++)
            {
                _customers.Add(customer);
            }
            _sparse_set = SparseSetHelper.CreateNearestNeighourSet(_problem, _customers, _customers.Count / 10);
            //_sparse_set = SparseSetHelper.CreateNonSparseSet(_problem, _customers);
            // construct a route from the customers.
            //FixedSymmetricRoute init_route = new FixedSymmetricRoute(_customers);

            // construct a random route using best-placement.
            ArbitraryInsertionSolver bp_solver = new ArbitraryInsertionSolver();
            IRoute bp_route = bp_solver.Solve(_problem);
            FixedSymmetricRoute init_route = new FixedSymmetricRoute(bp_route);

            double init_route_weight = LinKernighanSolver.Weight(_problem, init_route);
            RouteFound route = new RouteFound()
            {
                Route = init_route,
                RouteWeight = init_route_weight
            };
            OsmSharp.Logging.Log.TraceEvent("LinKernighanSolver", Logging.TraceEventType.Information, "Route {0}:{1}",
                route.Route.ToString(),
                route.RouteWeight);

            // step 2.
            EdgeSet X = new EdgeSet();
            EdgeSet Y = new EdgeSet();
            IList<int> untried_t_1 = new List<int>(route.Route);
            while (untried_t_1.Count > 0)
            {
                // select t1.
                int t_1 = untried_t_1[0];
                untried_t_1.RemoveAt(0);

                // search route with t_1.
                RouteFound t_1_route = this.AfterSelectt1(_problem, route, X, Y, t_1);

                // select the better route.
                if (t_1_route.RouteWeight < route.RouteWeight)
                {
                    untried_t_1 = new List<int>(route.Route);
                    route = RouteFound.SelectBest(route, t_1_route);
                    X = new EdgeSet();
                    Y = new EdgeSet();
                }
            } // step 2 and step 12.

            // convert back to asym solution if needed.
            //result.RemoveAt(result.Count - 1);
            if (_was_asym)
            {
                return this.ConvertToASymRoute(new List<int>(route.Route));
            }
            return route.Route;
        }
Ejemplo n.º 5
0
        ///// <summary>
        ///// A naive selection method.
        ///// </summary>
        ///// <param name="problem"></param>
        ///// <param name="route"></param>
        ///// <param name="X"></param>
        ///// <param name="Y"></param>
        ///// <param name="x"></param>
        ///// <param name="y"></param>
        ///// <param name="exceptions"></param>
        ///// <returns></returns>
        //private int? SelectY(
        //    IProblem problem, FixedSymmetricRoute route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y, HashSet<int> exceptions)
        //{
        //    int from = x.Last.To;
        //    // search an edge with weight smaller than g.
        //    // VERY NAIVE METHOD!
        //    List<int> test_list = new List<int>();
        //    float best_extra = float.MaxValue;
        //    int? best_customer = null;
        //    for (int other_customer = 0; other_customer < problem.Size; other_customer++)
        //    {
        //        if (other_customer != from && exceptions != null && !exceptions.Contains(other_customer))
        //        {
        //            if (!x.Contains(from, other_customer)
        //                && !route.Contains(from, other_customer))
        //            //&& !Y.Contains(from, other_customer))
        //            //&& !X.Contains(from, other_customer))
        //            {
        //                float extra = problem.Weight(from, other_customer);
        //                if (y.Weight + extra < x.Weight)
        //                {
        //                    if (x.Count < 3)
        //                    {
        //                        best_customer = other_customer;
        //                        best_extra = extra;
        //                        break;
        //                    }
        //                    test_list.Add(other_customer);
        //                    if (extra < best_extra)
        //                    {
        //                        best_customer = other_customer;
        //                        best_extra = extra;
        //                        if (x.Count < 3)
        //                        {
        //                            break;
        //                        }
        //                    }
        //                }
        //            }
        //        }
        //    }
        //    return best_customer;
        //}
        /// <summary>
        /// Selects with special priority.
        /// </summary>
        /// <param name="problem"></param>
        /// <param name="route"></param>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="exceptions"></param>
        /// <returns></returns>
        private int? SelectY(
            IProblem problem, FixedSymmetricRoute route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y, HashSet<int> exceptions)
        {
            int from = x.Last.To;

            // search an edge with weight smaller than g.
            //float best_priority = float.MinValue;
            int? best_customer = null;
            foreach (Edge edge in _sparse_set.GetFor(from))
            {
                if (exceptions == null ||
                    !exceptions.Contains(edge.To))
                {
                    if (edge.From != edge.To
                        && !x.Contains(edge)
                        && !y.Contains(edge)
                        && !route.Contains(edge.From, edge.To)
                        //&& !Y.Contains(from, other_customer))
                        && !X.Contains(from, edge.To))
                    {
                        double extra = edge.Weight;
                        if (y.Weight + extra < x.Weight)
                        {
                            //if (x.Count < 2)
                            //{
                                best_customer = edge.To;
                                break;
                            //}

                            //// calculate priority.
                            //int? x_other = this.SelectX(problem, route, X, Y, x, edge.To, null);
                            //float priority = float.MinValue;
                            //if (x_other != null)
                            //{
                            //    float x_other_weight = problem.Weight(edge.To, x_other.Value);
                            //    priority = x_other_weight - extra;
                            //}
                            //if (priority > best_priority)
                            //{
                            //    best_customer = edge.To;
                            //    best_priority = priority;
                            //}
                        }
                    }
                }
            }
            return best_customer;
        }
Ejemplo n.º 6
0
        private int? SelectX(
            IProblem problem, FixedSymmetricRoute route, EdgeSet X, EdgeSet Y, EdgeList x, int customer, HashSet<int> exceptions)
        {
            // select the only two edges that have the given customer in the given route.
            int[] neigbours = route.GetNeigbours(customer);
            int previous = neigbours[0];
            int next = neigbours[1];

            int? best_neighour = null;
            double best_weight = double.MinValue;
            if (previous > 0 && (exceptions == null || !exceptions.Contains(previous))
                && !x.Contains(customer, previous))
                //&& !X.Contains(customer, previous))
                //&& !Y.Contains(customer, previous))
            {
                //if (x.Count > 2)
                //{
                double weight = problem.Weight(customer, previous);
                if (weight > best_weight)
                {
                    best_neighour = previous;
                    best_weight = weight;
                }
                //}
                //else
                //{
                    return previous;
                //}
            }
            if (next > 0 && (exceptions == null || !exceptions.Contains(next))
                && !x.Contains(customer, next))
                //&& !X.Contains(customer, previous))
                //&& !Y.Contains(customer, previous))
            {
                //if (x.Count > 2)
                //{
                double weight = problem.Weight(customer, next);
                if (weight > best_weight)
                {
                    best_neighour = next;
                    best_weight = weight;
                }
                //}
                //else
                //{
                    return next;
                //}
            }
            return best_neighour;
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Replaces some edges with a list of other edges.
 /// </summary>
 /// <param name="route"></param>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <returns></returns>
 private FixedSymmetricRoute Replace(FixedSymmetricRoute route, EdgeList x, EdgeList y)
 {
     FixedSymmetricRoute route_new = route.Clone() as FixedSymmetricRoute;
     for (int idx = 0; idx < x.Count; idx++)
     {
         Edge x_edge = x[idx];
         route_new.Remove(x_edge.From, x_edge.To);
     }
     for (int idx = 0; idx < x.Count; idx++)
     {
         Edge y_edge = y[idx];
         route_new.Add(y_edge.From, y_edge.To);
     }
     //if (!route_new.IsValidNew() && route_new.IsValid())
     //{
     //    Debug.Write(string.Empty);
     //}
     //else
     //{
     //    Debug.Write(string.Empty);
     //}
     return route_new;
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Does the actual solving.
        /// </summary>
        /// <param name="problem"></param>
        /// <returns></returns>
        protected override IRoute DoSolve(IProblem problem)
        {
            // convert to a symetric problem if needed.
            IProblem _problem = problem;

            if (!_problem.Symmetric)
            {
                _problem  = Convertor.ConvertToSymmetric(_problem);
                _was_asym = true;
            }

            // create the list of customers.
            _customers = new List <int>();
            for (int customer = 0; customer < _problem.Size; customer++)
            {
                _customers.Add(customer);
            }
            _sparse_set = SparseSetHelper.CreateNearestNeighourSet(_problem, _customers, _customers.Count / 10);
            //_sparse_set = SparseSetHelper.CreateNonSparseSet(_problem, _customers);
            // construct a route from the customers.
            //FixedSymmetricRoute init_route = new FixedSymmetricRoute(_customers);

            // construct a random route using best-placement.
            ArbitraryInsertionSolver bp_solver = new ArbitraryInsertionSolver();
            IRoute bp_route = bp_solver.Solve(_problem);
            FixedSymmetricRoute init_route = new FixedSymmetricRoute(bp_route);

            double     init_route_weight = LinKernighanSolver.Weight(_problem, init_route);
            RouteFound route             = new RouteFound()
            {
                Route       = init_route,
                RouteWeight = init_route_weight
            };

            Console.WriteLine("Route {0}:{1}",
                              route.Route.ToString(),
                              route.RouteWeight);

            // step 2.
            EdgeSet     X           = new EdgeSet();
            EdgeSet     Y           = new EdgeSet();
            IList <int> untried_t_1 = new List <int>(route.Route);

            while (untried_t_1.Count > 0)
            {
                // select t1.
                int t_1 = untried_t_1[0];
                untried_t_1.RemoveAt(0);

                // search route with t_1.
                RouteFound t_1_route = this.AfterSelectt1(_problem, route, X, Y, t_1);

                // select the better route.
                if (t_1_route.RouteWeight < route.RouteWeight)
                {
                    untried_t_1 = new List <int>(route.Route);
                    route       = RouteFound.SelectBest(route, t_1_route);
                    X           = new EdgeSet();
                    Y           = new EdgeSet();
                }
            } // step 2 and step 12.

            // convert back to asym solution if needed.
            //result.RemoveAt(result.Count - 1);
            if (_was_asym)
            {
                return(this.ConvertToASymRoute(new List <int>(route.Route)));
            }
            return(route.Route);
        }