コード例 #1
0
        public List <Package> AssignPackagesToCouriers(List <Package> packages, List <User> couriers, Dictionary <int, int> vehiclesLoadCapacity)
        {
            var todaysPackages             = new List <Package>();
            var vehicleRange               = GetAllVehiclesRange();
            var courierLocationAlongTheWay = GetAllCouriersLocationCoordinates();

            foreach (var package in packages)
            {
                var distances = _locationService.CountDistancesFromPackageToCouriers(couriers, package);         //każdej paczce, która oczekuje na nadanie obliczam odległości od wszystkich kurierów
                if (distances.Count == 0)
                {
                    continue;
                }

                Vehicle vehicle;
                int     courierId;
                do
                {
                    courierId = FindTheNearestCourier(distances);                                           //wybieram kuriera, który jest najbliżej nadanej paczki

                    vehicle = _vehicleService.GetVehicle(courierId);                                        //jeśli mam kuriera, który jest najbliżej, odnajduję jego samochód
                    if (vehicle == null)                                                                    //zabezpieczam się też na wypadek gdyby kurier był na tyle nowy, że jeszcze nie dano mu samochodu
                    {
                        distances.Remove(courierId);
                    }
                    if (distances.Count == 0)                                                                   //warunek, który zadziała jeśli z jakiegoś powodu żaden kurier nie będzie miał przypisanego samochodu
                    {
                        Console.WriteLine();
                        Console.WriteLine($"\tWaybill info for {package.Id}: We are very sorry, our company is just developing in your region.");
                        break;
                    }
                } while (vehicle == null);

                if (vehicle == null)
                {
                    continue;
                }

                var currentLoadCapacity = vehiclesLoadCapacity[vehicle.Id];
                if (currentLoadCapacity < (int)package.Size)                                                    //jeśli paczka nie miesci się do samochodu, zostawiam ją na kolejny dzień
                {
                    continue;
                }

                var currentCuriersLocation = courierLocationAlongTheWay[courierId];
                if (currentCuriersLocation.FirstPackageForCourier == true)
                {
                    var firstPackageSender = new LocationCoordinates()
                    {
                        Lat = package.Sender.lat, Lon = package.Sender.lon
                    };
                    var firstPackageRecipient = new LocationCoordinates()
                    {
                        Lat = package.RecipientLat, Lon = package.RecipientLon
                    };

                    var vehicleRangeWithPackage = AddedDistancesBetweenTwoPlacesForFirstPackage(currentCuriersLocation, firstPackageSender, firstPackageRecipient);

                    var distance = vehicleRangeWithPackage.Sum();
                    if (distance > vehicleRange[vehicle.Id])
                    {
                        continue;
                    }

                    vehicleRange[vehicle.Id] -= vehicleRangeWithPackage[0];

                    UpdateCourierLocationsAlongTheWayForFirstPackage(courierLocationAlongTheWay, courierId, firstPackageSender, firstPackageRecipient);
                }
                else
                {
                    var packageSender = new LocationCoordinates()
                    {
                        Lat = package.Sender.lat, Lon = package.Sender.lon
                    };
                    var packageRecipient = new LocationCoordinates()
                    {
                        Lat = package.RecipientLat, Lon = package.RecipientLon
                    };

                    List <double> vehicleRangeWithPackage = AddedDistancesBetweenTwoPlaces(currentCuriersLocation, packageSender, packageRecipient);

                    var distance = vehicleRangeWithPackage.Sum();
                    if (distance > vehicleRange[vehicle.Id])
                    {
                        continue;
                    }

                    ReductionVehicleRange(vehicleRange, vehicle, vehicleRangeWithPackage);
                    UpdateCourierLocationsAlongTheWay(courierLocationAlongTheWay, courierId, packageSender, packageRecipient);
                }

                vehiclesLoadCapacity[vehicle.Id] -= (int)package.Size;                                          //jeśli się paczka mieści to zmniejszam dzisiejszą wolną przestrzeń w samochodzie

                package.VehicleNumber = vehicle.Id;                                                             //wszystko jest ok, paczka ma przypisany nr samochodu, którym będzie podróżowała

                todaysPackages.Add(package);                                                                    //tworzę listę paczek, które dzisiaj będą podróżowały
            }

            return(todaysPackages);
        }