public object Clone() { GreenLightCycle newCycle = new GreenLightCycle(this.Street); newCycle.Duration = this.Duration; return(newCycle); }
private static void InitBasicSolution(Problem problem, Solution solution) { foreach (Intersection i in problem.Intersections) { solution.Intersections[i.ID].GreenLigths = new List <GreenLightCycle>(); foreach (Street street in i.IncomingStreets) { GreenLightCycle cycle = new GreenLightCycle(street); cycle.Duration = 1; solution.Intersections[i.ID].GreenLigths.Add(cycle); } } }
/// <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); }