Beispiel #1
0
        private double GetWeightedValue(Ride r, Vehicle vehicle)
        {
            var bonus = (r.EarliestStart - vehicle.CurrentSteps) > 0 ? (r.EarliestStart - vehicle.CurrentSteps) : 0;

            return(r.GetDistance() * 0.65 + vehicle.GetDistanceToRide(r) * 0.35 + bonus * 0.175);
        }
Beispiel #2
0
        static void FindRide(ref Car[] cars, int carIndex, ref List <Ride> rides, int index, int step, int bonus, ref int totalScore)
        {
            Car   car         = cars[carIndex];
            int   count       = 0;
            int   bestRide    = -1;
            float bestScore   = System.Int32.MinValue;
            int   availableAt = 0;
            int   tempScore   = 0;

            for (int i = index; i < rides.Count; ++i)
            {
                Ride ride      = rides[i];
                int  startStep = Math.Max(step + GetDistance(car.posx, car.posy, ride.startx, ride.starty), ride.start);
                int  endStep   = startStep + ride.duration;
                if (endStep < ride.finish)
                {
                    int waitTime = Math.Max(ride.start - (step + GetDistance(car.posx, car.posy, ride.startx, ride.starty)), 0);

                    /* Weights
                     * nohurry    : 1 1 1 0.809 1
                     * metropolis : 1 1 1.75 1 1
                     * highbonus  : 1 1 1 1 1
                     */
                    int counttemp = 0;

                    float score = 50000 + ride.duration + ((startStep <= ride.start) ? bonus : 0) - waitTime * weightWait - GetDistance(car.posx, car.posy, ride.startx, ride.starty) * weightDistance - (endStep - step) - counttemp * 50;
                    if (score > bestScore || (score >= bestScore && endStep < availableAt))
                    {
                        int bestOther = carIndex;
                        for (int temp = carIndex + 1; temp < cars.Length; ++temp)
                        {
                            if (cars[temp].availableAt < step + 2)
                            {
                                continue;
                            }
                            Car   _car       = cars[temp];
                            int   _startStep = Math.Max(step + GetDistance(_car.posx, _car.posy, ride.startx, ride.starty), ride.start);
                            int   _endStep   = _startStep + ride.duration;
                            int   _waitTime  = Math.Max(ride.start - (step + GetDistance(_car.posx, _car.posy, ride.startx, ride.starty)), 0);
                            float _score     = 50000 + ride.duration + ((_startStep <= ride.start) ? bonus : 0) - _waitTime - GetDistance(_car.posx, _car.posy, ride.startx, ride.starty) - (_endStep - step);
                            if (_score > score)
                            {
                                bestOther = temp;
                            }
                        }
                        if (bestOther > carIndex)
                        {
                            FindRide(ref cars, bestOther, ref rides, index, step, bonus, ref totalScore);
                        }
                        else
                        {
                            bestRide    = i;
                            bestScore   = score;
                            availableAt = endStep;
                            tempScore   = ride.duration + ((startStep <= ride.start) ? bonus : 0);
                        }
                    }
                }
            }
            if (bestRide != -1)
            {
                Ride ride = rides[bestRide];
                car.ridesTaken.Add(ride);
                car.posx        = ride.endx;
                car.posy        = ride.endy;
                car.availableAt = availableAt;
                totalScore     += tempScore;
                rides.RemoveAt(bestRide);
            }
        }
Beispiel #3
0
 public int GetDistanceToRide(Ride ride)
 {
     return(Math.Abs(CurrentPosition.X - ride.ColumnStart) + Math.Abs(CurrentPosition.Y - ride.RowStart));
 }
Beispiel #4
0
        static void Main(string[] args)
        {
            /**************************************************************************************
            *  Input loading
            **************************************************************************************/

            Debug.WriteLine("Input loading...");

            string inputFilePath = Path.Combine(Directory.GetCurrentDirectory(), inputFileName);

            string[] lines = File.ReadAllLines(inputFilePath);

            string[] firstLine = lines[0].Split(delimiter);

            int R = int.Parse(firstLine[0]); // number of rows
            int C = int.Parse(firstLine[1]); // number of columns
            int F = int.Parse(firstLine[2]); // number of vehicles
            int N = int.Parse(firstLine[3]); // number of rides
            int B = int.Parse(firstLine[4]); // per-ride bonus
            int T = int.Parse(firstLine[5]); // number of steps

            List <Ride> availableRides = new List <Ride>();

            for (int i = 1; i < lines.Length; i++)
            {
                string[] splittedLine = lines[i].Split(delimiter);

                Ride ride = new Ride()
                {
                    id    = (i - 1),
                    Start = new Intersection()
                    {
                        r = int.Parse(splittedLine[0]),
                        c = int.Parse(splittedLine[1])
                    },
                    Finish = new Intersection()
                    {
                        r = int.Parse(splittedLine[2]),
                        c = int.Parse(splittedLine[3])
                    },
                    earliestStart = int.Parse(splittedLine[4]),
                    latestFinish  = int.Parse(splittedLine[5]),
                    startTime     = -1
                };
                availableRides.Add(ride);
            }

            List <Vehicle> fleet = new List <Vehicle>();

            for (int i = 0; i < F; i++)
            {
                fleet.Add(new Vehicle()
                {
                    available = true,
                    position  = new Intersection()
                    {
                        r = 0,
                        c = 0
                    },
                    assignedRides = new List <Ride>()
                });
            }

            /**************************************************************************************
            *  Solver
            **************************************************************************************/

            Debug.WriteLine("Solving the problem...");

            for (int t = 0; t < T; t++)
            {
                int availableVehicles = 0;

                foreach (Vehicle vehicle in fleet)
                {
                    // Update the vehicle position if the current ride (if any) has ended
                    if (!vehicle.available && vehicle.lastRide.PlannedEndTime() == t)
                    {
                        vehicle.available = true;
                        vehicle.position  = vehicle.assignedRides.Last().Finish;
                    }

                    // Search for a new ride
                    if (vehicle.available && !vehicle.fired && availableRides.Count > 0)
                    {
                        availableVehicles++;

                        // Find nearest ride
                        // TODO : consider to seach for the nearest in distance + TIME
                        ///Ride nearestRide = availableRides.Aggregate((r1, r2) => (Utils.Distance(vehicle.position, r1.Start) < Utils.Distance(vehicle.position, r2.Start)) ? r1 : r2);

                        //availableRides.Sort((r1, r2) =>
                        //{
                        //    if (r1 != null && r2 != null)
                        //    {
                        //        // Sort from the nearest ride to the farest
                        //        int dist1 = Utils.Distance(vehicle.position, r1.Start);
                        //        int dist2 = Utils.Distance(vehicle.position, r2.Start);

                        //        return (dist1 < dist2 ? -1 : +1);
                        //    }

                        //    if (r1 == null && r2 == null)
                        //        return 0;

                        //    if (r1 != null)
                        //        return -1;

                        //    return 1;
                        //});

                        availableRides.Sort((r1, r2) =>
                        {
                            if (r1 != null && r2 != null)
                            {
                                // Sort from the biggest distance to the smallest
                                int dist1 = Utils.Distance(r1.Start, r1.Finish);
                                int dist2 = Utils.Distance(r2.Start, r2.Finish);

                                return(dist1 < dist2 ? +1 : -1);
                            }

                            if (r1 == null && r2 == null)
                            {
                                return(0);
                            }

                            if (r1 != null)
                            {
                                return(-1);
                            }

                            return(1);
                        });

                        foreach (Ride nearestRide in availableRides)
                        {
                            // Don't take the ride if not possible to be on time at finish
                            int tempDistance = Utils.Distance(vehicle.position, nearestRide.Start);
                            if (t + tempDistance <= nearestRide.LastestStart())
                            {
                                // Asign vehicle to this ride
                                nearestRide.startTime = t + tempDistance;

                                vehicle.assignedRides.Add(nearestRide);
                                vehicle.lastRide  = nearestRide;
                                vehicle.available = false;
                                availableRides.Remove(nearestRide);

                                break;
                            }
                        }

                        if (vehicle.available)
                        {
                            // Fired!
                            vehicle.fired = true;
                        }
                    }
                }

                Console.WriteLine("t: " + t + " availableRides:" + availableRides.Count + " availableVehicles:" + availableVehicles);
            }

            /**************************************************************************************
            *  Output
            **************************************************************************************/

            Debug.WriteLine("Output to file...");

            using (StreamWriter outputFile = new StreamWriter(Path.Combine(Directory.GetCurrentDirectory(), outputFileName)))
            {
                foreach (Vehicle vehicle in fleet)
                {
                    outputFile.WriteLine(vehicle.ToString());
                }
            }

            Debug.WriteLine("Done.");
        }