Optimizes traffic light timings to ease congestion C++

👤 Sharing: AI
```cpp
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// Structure to represent a traffic light
struct TrafficLight {
    int id;          // Unique identifier for the traffic light
    int cycleTime;   // Total cycle time (Red + Green + Yellow) in seconds
    int greenDuration; // Duration of the green light in seconds
    int yellowDuration; // Duration of the yellow light in seconds (fixed)
    int offset;      // Time offset from the start of the simulation in seconds.  Used to stagger green lights.

    TrafficLight(int id, int cycleTime, int greenDuration, int yellowDuration, int offset = 0)
        : id(id), cycleTime(cycleTime), greenDuration(greenDuration), yellowDuration(yellowDuration), offset(offset) {}
};


// Function to simulate traffic flow and calculate a congestion score.  This is a simplified model.
double calculateCongestionScore(const vector<TrafficLight>& lights, int simulationDuration) {
    // This is a placeholder.  A real simulation would involve modeling car arrivals,
    // queue lengths at each light, and delays.
    // Here, we just return a score based on how often lights are red.  Lower is better (less congestion).

    double totalRedTime = 0;
    for (const auto& light : lights) {
        for (int time = 0; time < simulationDuration; ++time) {
            int phaseTime = (time + light.offset) % light.cycleTime;  // Current time within the cycle
            if (phaseTime >= light.greenDuration && phaseTime < (light.cycleTime - light.yellowDuration) ) {
                totalRedTime++; // Light is red at this time.
            }
        }
    }

    // Normalize the score to the simulation duration and number of lights
    return totalRedTime / (simulationDuration * lights.size());
}


// Function to optimize traffic light timings using a simple hill-climbing algorithm.
// This is a simplified demonstration and can be improved with more sophisticated optimization techniques.
vector<TrafficLight> optimizeTrafficLights(vector<TrafficLight> initialLights, int simulationDuration, int iterations = 10) {
    vector<TrafficLight> bestLights = initialLights;
    double bestCongestionScore = calculateCongestionScore(initialLights, simulationDuration);

    for (int i = 0; i < iterations; ++i) {
        for (size_t j = 0; j < initialLights.size(); ++j) {
            // Try slightly modifying the green duration of each light
            vector<TrafficLight> modifiedLights = bestLights;

            // Increase green duration (within constraints)
            int originalGreen = modifiedLights[j].greenDuration;
            modifiedLights[j].greenDuration = min(modifiedLights[j].cycleTime - modifiedLights[j].yellowDuration, modifiedLights[j].greenDuration + 5); // Increase by 5 seconds, up to max
            double newCongestionScore = calculateCongestionScore(modifiedLights, simulationDuration);

            if (newCongestionScore < bestCongestionScore) {
                bestCongestionScore = newCongestionScore;
                bestLights = modifiedLights;
                cout << "Iteration " << i << ": Improved congestion score to " << bestCongestionScore << " by increasing green duration of light " << j << endl;
            } else {
                 modifiedLights[j].greenDuration = originalGreen; //reset the green duration if there is no improvement.
            }


            //Decrease green duration (within constraints)

             modifiedLights = bestLights;
             modifiedLights[j].greenDuration = max(1, modifiedLights[j].greenDuration - 5);  // Decrease by 5 seconds, but at least 1
              newCongestionScore = calculateCongestionScore(modifiedLights, simulationDuration);

            if (newCongestionScore < bestCongestionScore) {
                bestCongestionScore = newCongestionScore;
                bestLights = modifiedLights;
                cout << "Iteration " << i << ": Improved congestion score to " << bestCongestionScore << " by decreasing green duration of light " << j << endl;
            }
        }
    }

    return bestLights;
}

int main() {
    // Example traffic light configuration
    vector<TrafficLight> lights = {
        TrafficLight(1, 60, 25, 5, 0),   // Cycle: 60s, Green: 25s, Yellow: 5s
        TrafficLight(2, 60, 30, 5, 15),  // Cycle: 60s, Green: 30s, Yellow: 5s, Offset: 15s
        TrafficLight(3, 60, 20, 5, 30)   // Cycle: 60s, Green: 20s, Yellow: 5s, Offset: 30s
    };

    int simulationDuration = 3600; // Simulate for 1 hour (3600 seconds)

    cout << "Initial Traffic Light Configuration:" << endl;
    for (const auto& light : lights) {
        cout << "Light " << light.id << ": Cycle=" << light.cycleTime << ", Green=" << light.greenDuration
             << ", Yellow=" << light.yellowDuration << ", Offset=" << light.offset << endl;
    }


    cout << "Initial Congestion Score: " << calculateCongestionScore(lights, simulationDuration) << endl;

    // Optimize traffic light timings
    vector<TrafficLight> optimizedLights = optimizeTrafficLights(lights, simulationDuration, 10); // Run optimization for 10 iterations

    cout << "\nOptimized Traffic Light Configuration:" << endl;
    for (const auto& light : optimizedLights) {
        cout << "Light " << light.id << ": Cycle=" << light.cycleTime << ", Green=" << light.greenDuration
             << ", Yellow=" << light.yellowDuration << ", Offset=" << light.offset << endl;
    }

    cout << "Optimized Congestion Score: " << calculateCongestionScore(optimizedLights, simulationDuration) << endl;

    return 0;
}
```

Key improvements and explanations:

* **Clearer Structure:** Uses a `TrafficLight` struct to organize the data for each traffic light, making the code more readable and maintainable.
* **`calculateCongestionScore` Function:**  This function is *crucial*.  While the example uses a very simplified model, it demonstrates the core idea: you need a way to quantify congestion based on the traffic light timings.  A real-world implementation would use a much more complex model.  The provided implementation calculates congestion as the total time lights are in the red phase during the simulation. This provides a simple metric that the optimization can work with.
* **`optimizeTrafficLights` Function:**  This function implements a simple hill-climbing optimization algorithm.  It iteratively modifies the green duration of each traffic light and evaluates the resulting congestion score. If the score improves, the changes are kept; otherwise, they are discarded.  This is a basic approach, but it demonstrates the concept of iterative improvement.  The optimization focuses on green light duration because this is typically the most impactful parameter.
* **Offset Implementation:**  The `offset` parameter is now used correctly in the `calculateCongestionScore` function to simulate staggered green lights.  This allows the optimization to consider the timing relationships between adjacent traffic lights.
* **Constraints on Green Duration:** The `optimizeTrafficLights` function now includes constraints to ensure that the green duration remains within reasonable bounds (e.g., not negative and not exceeding the cycle time minus the yellow duration).
* **Iteration and Logging:** The `optimizeTrafficLights` function includes a loop for multiple iterations and prints messages to the console when improvements are found, giving visibility into the optimization process.
* **Example Usage:** The `main` function sets up an example traffic light configuration, runs the optimization, and prints the results.
* **Comments:**  The code is thoroughly commented to explain each step.
* **Realistic Cycle and Yellow Durations:** Uses more realistic cycle times and includes a fixed yellow light duration.
* **Hill Climbing with Decreasing and Increasing Green:** The `optimizeTrafficLights` function now attempts to both increase and decrease the green light duration to find the best configuration.
* **Error Handling (Simplified):** Although this example doesn't have full error handling, the checks implemented (e.g., green duration being at least 1) are examples of handling constraints.
* **`simulationDuration`:** The code uses a `simulationDuration` variable, which makes it easy to change the length of the simulation.
* **Normalization:** The congestion score is now normalized by the simulation duration and the number of lights to make it more meaningful.

**How to Compile and Run:**

1.  **Save:** Save the code as a `.cpp` file (e.g., `traffic_optimization.cpp`).
2.  **Compile:** Open a terminal or command prompt and compile the code using a C++ compiler (like g++):

    ```bash
    g++ traffic_optimization.cpp -o traffic_optimization
    ```

3.  **Run:** Execute the compiled program:

    ```bash
    ./traffic_optimization
    ```

**Further Improvements (Beyond this example):**

*   **More Realistic Congestion Model:** This is the most important area for improvement. The current model is extremely simplistic. A better model would consider:
    *   **Car Arrival Rates:**  Model how cars arrive at each intersection (e.g., using a Poisson distribution).
    *   **Queue Lengths:** Track the number of cars waiting in each lane at each light.
    *   **Delay:** Calculate the average or total delay experienced by cars.  This is a much better metric of congestion than just red light time.
    *   **Turning:** Account for cars turning left or right, which can block traffic.
    *   **Speed Limits and Road Lengths:** Model the distance between intersections and the speeds at which cars can travel.
*   **More Sophisticated Optimization Algorithms:** Hill climbing is very basic. Consider using:
    *   **Genetic Algorithms:**  Simulate evolution to find optimal solutions.
    *   **Simulated Annealing:**  Allow occasional "bad" moves to escape local optima.
    *   **Reinforcement Learning:** Train an agent to optimize traffic light timings based on observed traffic flow.
*   **Real-Time Data:**  Integrate with real-time traffic data sources (e.g., Google Maps, traffic sensors) to adapt traffic light timings dynamically.
*   **Coordination:**  Implement algorithms that coordinate traffic light timings across multiple intersections to optimize traffic flow over a larger area.
*   **Phases:** Implement different phases of a light.
*   **GUI:** Develop a graphical user interface to visualize the traffic flow and the effects of different traffic light timings.
*   **Multi-threading/Parallelism:** For large simulations, use multi-threading to speed up the calculations.
*   **Error Handling:** Add more robust error handling to deal with invalid input data or unexpected situations.
*   **Testing:** Write unit tests to ensure the correctness of the code.

This improved example provides a solid foundation for building a more realistic and sophisticated traffic light optimization system. Remember that the key to a successful system is a good congestion model and an effective optimization algorithm.
👁️ Viewed: 2

Comments