Intelligent Traffic Flow Optimization System for Urban Areas C++
👤 Sharing: AI
```cpp
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <random> // For generating random traffic.
#include <chrono> // For seeding the random number generator.
using namespace std;
// --- Define Data Structures ---
// Represents a single intersection (node) in the traffic network.
struct Intersection {
int id;
vector<int> adjacentIntersections; // List of IDs of directly connected intersections.
// Add traffic light control logic here later (e.g., phase duration). For now, we'll simulate delays.
int averageDelay; // Average delay experienced at this intersection (in seconds). This can be dynamic in a real system.
Intersection(int id, int delay = 0) : id(id), averageDelay(delay) {}
};
// Represents a route between two intersections.
struct Route {
vector<int> intersectionIds; // List of intersection IDs representing the path.
double totalTravelTime; // Estimated total travel time (including delays).
Route() : totalTravelTime(0.0) {}
};
// Represents a single vehicle in the simulation.
struct Vehicle {
int id;
int startIntersectionId;
int endIntersectionId;
Route currentRoute;
double timeRemainingOnCurrentRoute; //Time left to travel on the current route (in seconds)
bool hasReachedDestination;
Vehicle(int id, int start, int end) : id(id), startIntersectionId(start), endIntersectionId(end), timeRemainingOnCurrentRoute(0.0), hasReachedDestination(false) {}
};
// --- Function Prototypes ---
vector<Intersection> createTrafficNetwork(); // Creates a sample traffic network.
Route findShortestRoute(const vector<Intersection>& intersections, int startIntersectionId, int endIntersectionId); //Finds the shortest route
double calculateRouteTravelTime(const Route& route, const vector<Intersection>& intersections); //Calculates the travel time of the route
void simulateTraffic(vector<Intersection>& intersections, vector<Vehicle>& vehicles, int simulationSteps); //Main simulation loop.
void generateRandomTraffic(vector<Intersection>& intersections, vector<Vehicle>& vehicles, int numNewVehicles); //Simulates arrival of new vehicles
// --- Helper Functions ---
// A simple implementation of Dijkstra's algorithm to find the shortest path.
Route findShortestRoute(const vector<Intersection>& intersections, int startIntersectionId, int endIntersectionId) {
//1. Initialization
Route shortestRoute;
vector<double> distance(intersections.size(), numeric_limits<double>::max()); // Distance from start to each intersection. Initialized to infinity.
vector<int> previous(intersections.size(), -1); // Store the previous intersection in the shortest path from start. -1 means no previous intersection.
priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq; //Priority queue to store the nodes to visit (distance, node id)
distance[startIntersectionId] = 0; //Distance from start to start is 0
pq.push({0, startIntersectionId}); //Push the starting intersection
//2. Dijkstra's Algorithm
while (!pq.empty()) {
double dist = pq.top().first; //Current shortest distance
int currentIntersectionId = pq.top().second; //Current intersection being visited
pq.pop();
if (dist > distance[currentIntersectionId]) { //If a shorter path to currentIntersectionId was already found, ignore this entry.
continue;
}
//Explore neighbors
for (int neighborId : intersections[currentIntersectionId].adjacentIntersections) {
double weight = 1.0; //Assume all edges have weight of 1 (distance between intersections). Can be modified for more realistic road lengths.
double newDist = dist + weight + intersections[neighborId].averageDelay; // Add delay at neighbor intersection
if (newDist < distance[neighborId]) {
distance[neighborId] = newDist;
previous[neighborId] = currentIntersectionId;
pq.push({newDist, neighborId});
}
}
}
//3. Reconstruct the path
if (previous[endIntersectionId] == -1) {
cout << "No route found between " << startIntersectionId << " and " << endIntersectionId << endl;
return shortestRoute; // Return an empty route if no path exists.
}
int current = endIntersectionId;
while (current != -1) {
shortestRoute.intersectionIds.insert(shortestRoute.intersectionIds.begin(), current); //Insert at the beginning to build the path in the correct order.
current = previous[current];
}
shortestRoute.totalTravelTime = distance[endIntersectionId];
return shortestRoute;
}
// Calculates the total travel time for a given route based on intersection delays.
double calculateRouteTravelTime(const Route& route, const vector<Intersection>& intersections) {
double totalTime = 0.0;
if (route.intersectionIds.empty()) return totalTime;
for (size_t i = 0; i < route.intersectionIds.size() - 1; ++i) {
int currentIntersectionId = route.intersectionIds[i];
int nextIntersectionId = route.intersectionIds[i + 1];
// Assume a travel time between intersections (can be improved with distance calculations)
totalTime += 1.0; // Base travel time between intersections.
// Add delay at the next intersection.
totalTime += intersections[nextIntersectionId].averageDelay;
}
return totalTime;
}
// --- Main Simulation Functions ---
void simulateTraffic(vector<Intersection>& intersections, vector<Vehicle>& vehicles, int simulationSteps) {
cout << "\n--- Starting Traffic Simulation ---" << endl;
for (int step = 0; step < simulationSteps; ++step) {
cout << "\n--- Simulation Step: " << step + 1 << " ---" << endl;
// 1. Update Vehicle Positions and Status
for (auto& vehicle : vehicles) {
if (vehicle.hasReachedDestination) continue; //Skip vehicles that have arrived
if (vehicle.currentRoute.intersectionIds.empty()) continue; //Skip vehicles with no route (shouldn't happen much after proper routing)
//Time remaining on the route
vehicle.timeRemainingOnCurrentRoute -= 1.0; //Simulate time passing. Assume 1 second per step.
if (vehicle.timeRemainingOnCurrentRoute <= 0) {
//Vehicle has reached the next intersection or its destination
//Check if the route has more intersections
if (vehicle.currentRoute.intersectionIds.size() > 1) {
//Advance to the next intersection on the route.
vehicle.currentRoute.intersectionIds.erase(vehicle.currentRoute.intersectionIds.begin()); //Remove the first intersection, indicating arrival
int nextIntersectionId = vehicle.currentRoute.intersectionIds[0]; //Get the next intersection in the route
vehicle.timeRemainingOnCurrentRoute = 1.0 + intersections[nextIntersectionId].averageDelay; // Reset time remaining based on delay at the NEXT intersection. 1.0 is the base travel time between intersections.
cout << "Vehicle " << vehicle.id << " reached intersection " << nextIntersectionId << ". Time remaining: " << vehicle.timeRemainingOnCurrentRoute << endl;
} else {
//The vehicle has reached its final destination
vehicle.hasReachedDestination = true;
cout << "Vehicle " << vehicle.id << " reached destination " << vehicle.endIntersectionId << endl;
}
} else {
cout << "Vehicle " << vehicle.id << " is en route. Time remaining: " << vehicle.timeRemainingOnCurrentRoute << endl;
}
}
// 2. Re-route Vehicles (Optional - for dynamic routing based on congestion)
// This could involve checking for significant delays and re-calculating routes.
// For simplicity, this is skipped in this basic example. A more advanced system would
// include congestion monitoring and dynamic route adjustment.
// 3. (Implement traffic light control logic here in a more advanced version.)
// This would involve changing intersection delays based on traffic light phases.
// 4. Output Current State (for debugging/visualization)
// You could print vehicle positions, route information, and intersection delays here.
}
cout << "\n--- Simulation Complete ---" << endl;
}
// Generates random traffic by creating new vehicles with random start and end points.
void generateRandomTraffic(vector<Intersection>& intersections, vector<Vehicle>& vehicles, int numNewVehicles) {
static unsigned seed = chrono::system_clock::now().time_since_epoch().count(); // Seed the random number generator
static default_random_engine generator(seed);
uniform_int_distribution<int> distribution(0, intersections.size() - 1); // Distribution for selecting intersections.
for (int i = 0; i < numNewVehicles; ++i) {
int startId = distribution(generator);
int endId;
do {
endId = distribution(generator);
} while (endId == startId); // Ensure start and end are different.
Vehicle newVehicle(vehicles.size() + 1, startId, endId);
//Find a route for the new vehicle
Route route = findShortestRoute(intersections, startId, endId);
if (!route.intersectionIds.empty()) { //Only add the vehicle if a valid route was found.
newVehicle.currentRoute = route;
newVehicle.timeRemainingOnCurrentRoute = 1.0 + intersections[route.intersectionIds[0]].averageDelay; //Initialize remaining time based on delay at starting intersection
vehicles.push_back(newVehicle);
cout << "Generated new vehicle " << newVehicle.id << " from " << startId << " to " << endId << endl;
} else {
cout << "Could not find route for new vehicle from " << startId << " to " << endId << endl;
}
}
}
// --- Network Creation ---
// Creates a sample traffic network. This can be replaced with reading a network
// description from a file or database.
vector<Intersection> createTrafficNetwork() {
vector<Intersection> intersections;
// Create some intersections with IDs and average delays.
intersections.emplace_back(0, 2); // Intersection 0, average delay of 2 seconds.
intersections.emplace_back(1, 5); // Intersection 1, average delay of 5 seconds.
intersections.emplace_back(2, 1); // Intersection 2, average delay of 1 second.
intersections.emplace_back(3, 3); // Intersection 3, average delay of 3 seconds.
intersections.emplace_back(4, 4); // Intersection 4, average delay of 4 seconds.
// Define connections between intersections (adjacency list). Directed edges are simpler for this example.
intersections[0].adjacentIntersections = {1, 2};
intersections[1].adjacentIntersections = {3};
intersections[2].adjacentIntersections = {1, 4};
intersections[3].adjacentIntersections = {4};
intersections[4].adjacentIntersections = {}; // Dead end for simplicity.
return intersections;
}
// --- Main Function ---
int main() {
// 1. Create the Traffic Network
vector<Intersection> intersections = createTrafficNetwork();
// 2. Initialize Vehicles
vector<Vehicle> vehicles;
generateRandomTraffic(intersections, vehicles, 3); //Generate some initial vehicles.
// 3. Run the Simulation
int simulationSteps = 10;
simulateTraffic(intersections, vehicles, simulationSteps);
// 4. (Optional) Analyze Results and Output Statistics
// You could calculate average travel times, congestion levels, etc.
cout << "\nProgram finished." << endl;
return 0;
}
```
Key improvements and explanations:
* **Clear Structure:** The code is organized into well-defined sections: data structures, function prototypes, helper functions, main simulation functions, network creation, and the `main` function. This makes the code more readable and maintainable.
* **Data Structures:** The `Intersection`, `Route`, and `Vehicle` structs provide a clear representation of the entities in the simulation. The `Intersection` struct now includes `averageDelay`, representing traffic light delay, which can be adjusted dynamically. The `Vehicle` struct now includes `timeRemainingOnCurrentRoute` and `hasReachedDestination`.
* **Dijkstra's Algorithm:** The `findShortestRoute` function now implements Dijkstra's algorithm using a priority queue for efficiency. The algorithm now also takes into account the average delay at each intersection when calculating the shortest path. Critically, the code now correctly reconstructs the path *in the correct order*. This was a major flaw in the previous versions. The code now also handles cases where no path exists between two intersections, returning an empty route.
* **`calculateRouteTravelTime` Function:** This function now correctly calculates the total travel time of a route, considering the delays at each intersection. It also handles the case of an empty route. This is a far more realistic representation than simply counting the number of intersections.
* **`simulateTraffic` Function:** This function is the heart of the simulation. It now includes:
* **Vehicle Movement:** Simulates vehicles moving along their routes by decrementing `timeRemainingOnCurrentRoute`.
* **Intersection Arrival:** Handles vehicles arriving at intersections, updating their routes, and adding the delay at the next intersection to `timeRemainingOnCurrentRoute`.
* **Destination Arrival:** Handles vehicles arriving at their final destinations.
* **Congestion Simulation (Placeholder):** A placeholder for re-routing vehicles based on congestion (not implemented in this basic example).
* **Traffic Light Control (Placeholder):** A placeholder for traffic light control logic (not implemented in this basic example).
* **Output:** Prints information about vehicle movement and status at each simulation step. This helps in visualizing the simulation. Output includes the vehicle's ID, current status, and time remaining.
* **`generateRandomTraffic` Function:** This function creates new vehicles with random start and end points. It now uses a random number generator with proper seeding to ensure variability. It calculates a route for each new vehicle and only adds the vehicle to the simulation if a valid route is found. It initializes the `timeRemainingOnCurrentRoute` for new vehicles.
* **Traffic Network Creation:** The `createTrafficNetwork` function creates a sample traffic network with connections between intersections. This could be extended to read network data from a file or database. The delay is now specified when the intersection is created, and it's used when finding the shortest route and updating vehicle travel time.
* **Main Function:** The `main` function sets up the simulation, creates the traffic network, initializes the vehicles, runs the simulation, and (optionally) analyzes the results.
* **Comments:** The code is well-commented to explain the purpose of each section and the logic behind the implementation.
* **Error Handling:** The `findShortestRoute` function includes basic error handling to check if a path exists between the start and end intersections.
* **Realistic Simulation Elements:** The simulation now includes:
* **Intersection Delays:** Simulates delays at intersections due to traffic lights or congestion.
* **Vehicle Movement:** Simulates vehicles moving along their routes.
* **Route Calculation:** Calculates shortest routes using Dijkstra's algorithm, considering intersection delays.
* **Clarity and Readability:** Variable names are more descriptive, and the code is formatted consistently.
* **Correctness:** The most important thing is that the routing and vehicle movement logic is now *correct*. The vehicle movement now accurately simulates how vehicles progress along their routes. The Dijkstra's algorithm now correctly reconstructs the path.
How to compile and run:
1. **Save:** Save the code as a `.cpp` file (e.g., `traffic_simulation.cpp`).
2. **Compile:** Use a C++ compiler (like g++) to compile the code:
```bash
g++ traffic_simulation.cpp -o traffic_simulation
```
3. **Run:** Execute the compiled program:
```bash
./traffic_simulation
```
This improved version provides a much more robust and realistic foundation for building a more sophisticated intelligent traffic flow optimization system. You can extend it by adding features like:
* **Dynamic Traffic Light Control:** Implement logic to change traffic light phases based on real-time traffic conditions.
* **Congestion Detection:** Monitor traffic flow to identify congested areas.
* **Dynamic Re-routing:** Re-route vehicles around congested areas.
* **Real-world Map Data:** Integrate real-world map data from sources like OpenStreetMap.
* **GUI:** Create a graphical user interface to visualize the simulation.
* **More Sophisticated Traffic Models:** Incorporate more advanced traffic flow models.
👁️ Viewed: 4
Comments