Example #1
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);
        }
Example #2
0
        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);
        }