private static Solution OptimizeCycleDuration(Problem problem, Solution solution) { Solution bestSolution = null; int bestSolutionScore = -1; int timesSinceOptimized = 0; while (timesSinceOptimized < 10) { timesSinceOptimized++; SimulationResult simulationResult = problem.RunSimulation(solution); if (simulationResult.Score > bestSolutionScore) { bestSolution = (Solution)solution.Clone(); bestSolutionScore = simulationResult.Score; timesSinceOptimized = 0; } Console.WriteLine("Score: {0}, Max Blocked Traffic: {1}, Best score: {2}", simulationResult.Score, simulationResult.GetMaxBlockedTraffic(), bestSolutionScore); List <SimulationResult.IntersectionResult> intersectionResults = simulationResult.IntersectionResults.OrderByDescending(o => o.MaxStreetBlockedTraffic).ToList(); // Remove intersection without blocked cars for (int i = 0; i < intersectionResults.Count; i++) { if (intersectionResults[i].MaxStreetBlockedTraffic == 0) { intersectionResults.RemoveAt(i); i--; } } // Nothing to optimize - break if (intersectionResults.Count == 0) { break; } // Add cycle time for the top blocked cars for (int i = 0; i < intersectionResults.Count / 50; i++) { SimulationResult.IntersectionResult intersectionResult = intersectionResults[i]; SolutionIntersection intersection = solution.Intersections[intersectionResult.ID]; foreach (GreenLightCycle greenLightCycle in intersection.GreenLigths) { if (greenLightCycle.Street.Name.Equals(intersectionResult.MaxStreetName)) { greenLightCycle.Duration++; } } } } return(bestSolution); }
public SimulationResult RunSimulation(Solution solution) { SimulationResult simulationResult = new SimulationResult(this.Intersections.Count); int currentTime = 0; // Create list of cars in simulation List <CarSimultionPosition> carSimultionPositions = new List <CarSimultionPosition>(); int simulationCarStart = -(this.Cars.Count + 1); foreach (Car car in this.Cars) { carSimultionPositions.Add(new CarSimultionPosition(car, simulationCarStart)); simulationCarStart++; } // Init green lights foreach (SolutionIntersection intersection in solution.Intersections) { intersection.CurrentGreenLigth = 0; if (intersection.GreenLigths.Count > 0) { intersection.CurrentGreenLightChangeTime = intersection.GreenLigths[0].Duration; } else { intersection.CurrentGreenLightChangeTime = int.MaxValue; } } while (currentTime <= this.Duration) { // Update traffic lights cycle foreach (SolutionIntersection intersection in solution.Intersections) { if (intersection.CurrentGreenLightChangeTime <= currentTime) { intersection.CurrentGreenLigth = (intersection.CurrentGreenLigth + 1) % intersection.GreenLigths.Count; intersection.CurrentGreenLightChangeTime = currentTime + intersection.GreenLigths[intersection.CurrentGreenLigth].Duration; } } // Update cars HashSet <int> usedIntersection = new HashSet <int>(); for (int i = 0; i < carSimultionPositions.Count; i++) { CarSimultionPosition carSimultionPosition = carSimultionPositions[i]; if (carSimultionPosition.TimeGotHere > currentTime) { break; } Street street = carSimultionPosition.Car.Streets[carSimultionPosition.StreetNumber]; // Check if a car already used this intersection this cycle if (usedIntersection.Contains(street.EndIntersection)) { simulationResult.IntersectionResults[street.EndIntersection].AddBlockedTraffic(street.Name); continue; } SolutionIntersection intersection = solution.Intersections[street.EndIntersection]; // Not green light, skip to next car if (!street.Name.Equals(intersection.GreenLigths[intersection.CurrentGreenLigth].Street.Name)) { simulationResult.IntersectionResults[street.EndIntersection].AddBlockedTraffic(street.Name); continue; } // Mark intersection as used for this cycle usedIntersection.Add(street.EndIntersection); // Process car green light carSimultionPosition.StreetNumber++; carSimultionPosition.TimeGotHere = currentTime + carSimultionPosition.Car.Streets[carSimultionPosition.StreetNumber].Length; // Check if car finished if (carSimultionPosition.StreetNumber == carSimultionPosition.Car.Streets.Count - 1) { // Check if finished on time - if so give bonus if (carSimultionPosition.TimeGotHere <= this.Duration) { simulationResult.Score += this.BonusPerCar + (this.Duration - carSimultionPosition.TimeGotHere); } carSimultionPositions.RemoveAt(i); i--; } } // Sort cars by time carSimultionPositions.Sort((x, y) => x.TimeGotHere.CompareTo(y.TimeGotHere)); currentTime++; } return(simulationResult); }