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); }
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); } }
public int GetDistanceToRide(Ride ride) { return(Math.Abs(CurrentPosition.X - ride.ColumnStart) + Math.Abs(CurrentPosition.Y - ride.RowStart)); }
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."); }