public object Clone()
        {
            GreenLightCycle newCycle = new GreenLightCycle(this.Street);

            newCycle.Duration = this.Duration;

            return(newCycle);
        }
Exemple #2
0
 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);
         }
     }
 }
Exemple #3
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);
        }