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); }
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); }
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); }