Exemplo n.º 1
0
        public override long Run(int first_index, int second_index)
        {
            if (first_index > Nodes.Length || second_index > Nodes.Length || first_index < 0 || second_index < 0)
            {
                logger.Error($"Get Distance {first_index} -> {second_index} out of orders ({Nodes.Length})");
                return(0);
            }

            if (first_index == second_index)
            {
                return(0);
            }

            long distance;

            if (first_index == 0)
            {
                distance = distanceCalculator.DistanceFromBaseMeter(Nodes[second_index - 1].ShippingBase, Nodes[second_index - 1].Order.DeliveryPoint);
            }
            else if (second_index == 0)
            {
                distance = distanceCalculator.DistanceToBaseMeter(Nodes[first_index - 1].Order.DeliveryPoint, Nodes[first_index - 1].ShippingBase);
            }
            else
            {
                distance = distanceCalculator.DistanceMeter(Nodes[first_index - 1].Order.DeliveryPoint, Nodes[second_index - 1].Order.DeliveryPoint);
            }

            return(distance);
        }
Exemplo n.º 2
0
        private long Calculate(int first_index, int second_index)
        {
            if (first_index > Nodes.Length || second_index > Nodes.Length || first_index < 0 || second_index < 0)
            {
                logger.Error($"Get Distance {first_index} -> {second_index} out of orders ({Nodes.Length})");
                return(0);
            }

            //Возвращаем 0 при запросе расстояния из одной и тоже же точки, в нее же.
            //Такой запрос приходит обычно на точку склада, когда мы считаем больше 1 маршрута.
            if (first_index == second_index)
            {
                return(0);
            }

            //Просто возвращаем расстояние до базы от точки на которой находимся.
            if (second_index == 0)
            {
#if DEBUG
                SGoToBase[Trip]++;
#endif
                return(distanceCalculator.DistanceToBaseMeter(Nodes[first_index - 1].Order.DeliveryPoint));
            }

            bool fromExistRoute = false;
            if (Nodes[second_index - 1].ExistRoute != null)
            {
                //Если этот адрес в предварительно заданном маршруте у другого водителя, добавлям расстояние со штрафом.
                if (Trip.OldRoute != Nodes[second_index - 1].ExistRoute)
                {
#if DEBUG
                    SFromExistPenality[Trip]++;
#endif
                    return(RouteOptimizer.RemoveOrderFromExistRLPenalty + GetSimpleDistance(first_index, second_index));
                }
                fromExistRoute = true;
            }

            //Это адрес в приоритете для ларгусов.
            bool addressForLargus = Nodes[second_index - 1].Bootles <= RouteOptimizer.MaxBottlesInOrderForLargus;
            long distance         = 0;

            //Если у нас ларгус, а адрес большой, ларгусу вкатываем оромный штраф.
            if (Trip.Car.TypeOfUse == CarTypeOfUse.Largus && !addressForLargus)
            {
#if DEBUG
                SLargusPenality[Trip]++;
#endif
                return(RouteOptimizer.LargusMaxBottlePenalty);
            }

            //Если адрес для ларгуса, то обычным водителям добавляем штраф.
            if (Trip.Car.TypeOfUse != CarTypeOfUse.Largus && addressForLargus)
            {
                distance += RouteOptimizer.SmallOrderNotLargusPenalty;
            }

            var aria = Nodes[second_index - 1].District;

            // Если адрес из уже существующего маршрута, не учитываем приоритеты районов.
            // Иначе добавляем штрафы за приоритеты по району.
            if (!fromExistRoute)
            {
                if (priorites.ContainsKey(aria))
                {
                    distance += priorites[aria] * RouteOptimizer.DistrictPriorityPenalty;
                }
                else
                {
#if DEBUG
                    SUnlikeDistrictPenality[Trip]++;
#endif
                    distance += RouteOptimizer.UnlikeDistrictPenalty;
                }
            }

            //Возвращаем расстояние в метрах либо от базы до первого адреса, либо между адресами.
            if (first_index == 0)
            {
                distance += distanceCalculator.DistanceFromBaseMeter(Nodes[second_index - 1].Order.DeliveryPoint);
            }
            else
            {
                distance += distanceCalculator.DistanceMeter(Nodes[first_index - 1].Order.DeliveryPoint, Nodes[second_index - 1].Order.DeliveryPoint);
            }

            return(distance + fixedAddressPenality);
        }
Exemplo n.º 3
0
        private long Calculate(int first_index, int second_index)
        {
            if (first_index > Nodes.Length || second_index > Nodes.Length || first_index < 0 || second_index < 0)
            {
                logger.Error($"Get Distance {first_index} -> {second_index} out of orders ({Nodes.Length})");
                return(0);
            }

            //Возвращаем 0 при запросе расстояния из одной и тоже же точки, в нее же.
            //Такой запрос приходит обычно на точку склада, когда мы считаем больше 1 маршрута.
            if (first_index == second_index)
            {
                return(0);
            }

            //Просто возвращаем расстояние до базы от точки на которой находимся.
            if (second_index == 0)
            {
#if DEBUG
                SGoToBase[Trip]++;
#endif
                return(distanceCalculator.DistanceToBaseMeter(Nodes[first_index - 1].Order.DeliveryPoint, Nodes[first_index - 1].ShippingBase));
            }

            bool fromExistRoute = false;
            if (Nodes[second_index - 1].ExistRoute != null)
            {
                //Если этот адрес в предварительно заданном маршруте у другого водителя, добавлям расстояние со штрафом.
                if (Trip.OldRoute != Nodes[second_index - 1].ExistRoute)
                {
#if DEBUG
                    SFromExistPenality[Trip]++;
#endif
                    return(RouteOptimizer.RemoveOrderFromExistRLPenalty + GetSimpleDistance(first_index, second_index));
                }
                fromExistRoute = true;
            }

            // малотоннажник
            bool isLightTonnage = Trip.Car.MaxBottles <= 55;

            bool isRightAddress = Nodes[second_index - 1].Bottles >= Trip.Car.MinBottlesFromAddress &&
                                  Nodes[second_index - 1].Bottles <= Trip.Car.MaxBottlesFromAddress;

            long distance = 0;

            //Если у нас малотоннажник, а адрес большой, то вкатываем оромный штраф.
            if (isLightTonnage && !isRightAddress)
            {
#if DEBUG
                SLargusPenality[Trip]++;
#endif
                return(RouteOptimizer.LargusMaxBottlePenalty);
            }

            //Если не малотоннажник и адрес неподходящий, то вкатываем штраф.
            if (!isLightTonnage && !isRightAddress)
            {
                return(RouteOptimizer.LargusMaxBottlePenalty);
            }

            var area = Nodes[second_index - 1].District;

            // Если адрес из уже существующего маршрута, не учитываем приоритеты районов.
            // Иначе добавляем штрафы за приоритеты по району.
            if (!fromExistRoute)
            {
                if (priorites.ContainsKey(area))
                {
                    distance += priorites[area] * RouteOptimizer.DistrictPriorityPenalty;
                }
                else
                {
#if DEBUG
                    SUnlikeDistrictPenality[Trip]++;
#endif
                    distance += RouteOptimizer.UnlikeDistrictPenalty;
                }
            }

            bool isAddressFromForeignGeographicGroup = Nodes[second_index - 1].ShippingBase.Id != Trip.GeographicGroup.Id;
            if (isAddressFromForeignGeographicGroup)
            {
                distance += RouteOptimizer.AddressFromForeignGeographicGroupPenalty;
            }

            //Возвращаем расстояние в метрах либо от базы до первого адреса, либо между адресами.
            if (first_index == 0)
            {
                distance += distanceCalculator.DistanceFromBaseMeter(Nodes[second_index - 1].ShippingBase, Nodes[second_index - 1].Order.DeliveryPoint);
            }
            else
            {
                distance += distanceCalculator.DistanceMeter(Nodes[first_index - 1].Order.DeliveryPoint, Nodes[second_index - 1].Order.DeliveryPoint);
            }

            return(distance + fixedAddressPenality);
        }