public int RemoveUnusedStreets() { int removeStreets = 0; foreach (Intersection intersection in Intersections) { for (int i = intersection.IncomingStreets.Count - 1; i >= 0; i--) { Street inStreet = intersection.IncomingStreets[i]; if (inStreet.IncomingUsageCount > 0) { continue; } removeStreets++; intersection.IncomingStreets.RemoveAt(i); } } return(removeStreets); }
public GreenLightCycle(Street street) { this.Street = street; this.Duration = 0; }
/// <summary> /// Optimize green light by runnig full simulation & try to change the order of the green lights /// to make the cars pass intersections without waiting. /// </summary> /// <returns></returns> public int OptimizeGreenLightOrder(Solution solution) { int score = 0; int currentTime = 0; foreach (SolutionIntersection intersetion in solution.Intersections) { foreach (GreenLightCycle greenLightCycle in intersetion.GreenLigths) { greenLightCycle.GreenLightUsed = false; } } // 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)) { continue; } SolutionIntersection intersection = solution.Intersections[street.EndIntersection]; // Not green light, try swapping to green light if (!street.Name.Equals(intersection.GreenLigths[intersection.CurrentGreenLigth].Street.Name)) { // Green light already used - can't do it if (intersection.GreenLigths[intersection.CurrentGreenLigth].GreenLightUsed) { continue; } // Find required green light int requiredGreenLight = -1; for (int g = 0; g < intersection.GreenLigths.Count; g++) { if (street.Name.Equals(intersection.GreenLigths[g].Street.Name)) { requiredGreenLight = g; break; } } // Required green light not found - skip if (requiredGreenLight == -1) { continue; } // Required green light already used - skip if (intersection.GreenLigths[requiredGreenLight].GreenLightUsed) { continue; } // Swap possible only if it's the same green light duration if (intersection.GreenLigths[requiredGreenLight].Duration != intersection.GreenLigths[intersection.CurrentGreenLigth].Duration) { continue; } // Swap green lights - now the car can continue! GreenLightCycle tmp = intersection.GreenLigths[requiredGreenLight]; intersection.GreenLigths[requiredGreenLight] = intersection.GreenLigths[intersection.CurrentGreenLigth]; intersection.GreenLigths[intersection.CurrentGreenLigth] = tmp; } // Mark intersection as used for this cycle usedIntersection.Add(street.EndIntersection); // Mark green light used - changing no longer possible intersection.GreenLigths[intersection.CurrentGreenLigth].GreenLightUsed = true; // 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) { 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(score); }
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); }