Corect Form

You might also like

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 7

#include <iostream>

#include <fstream>
#include <string>
#include <vector>
#include <iomanip>
#include "Constant.h"
#include <random>
#include <unordered_map>
#include<algorithm>
using namespace std;

class ChargingStation
{
public:
int cityId;
string cityName;
int distanceToLastCity;
int numberOfChargers;
int queueLength;

public:
ChargingStation(int id, string name, int chargers)
: cityId(id), cityName(name), numberOfChargers(chargers), queueLength(0) {}

int distanceToSydney(int cityId)


{
int distance = 0;
for (int i = 0; i < cityId; i++)
{
distance += distanceMap[i + 1];
}
return distance;
}

void displayInfo()
{
cout << left << setw(4) << cityId;
cout << left << setw(25) << cityName;
cout << left << setw(25) << distanceToSydney(cityId);
cout << left << setw(20) << numberOfChargers;
cout << left << setw(15) << queueLength;
cout << left << setw(40) << fixed << setprecision(2) << (queueLength > 0 ?
(0.5 * static_cast<double>(queueLength) / numberOfChargers) : 0.0) << " hours" <<
endl;
}
};

class Vehicle
{
public:
int vehicleId; // can be any integer
int currentCityId; // initialised with 0 for Sydney
int destinationId; // any city other than Sydney
int capacityRange; // in kilometers
int remainRange; // in kilometers
vector<int> rechargeCities; // Vector to store recharge cities
int secondRecharge; // Variable to store the second recharge city if needed

public:
Vehicle(int id, int dest, int capacity, int remain)
: vehicleId(id), destinationId(dest), capacityRange(capacity),
remainRange(remain), currentCityId(0), secondRecharge(-1) {}

void calculateRechargeCities()
{
int remain = remainRange;
int distance = 0;
bool firstRechargeFound = false;

for (int i = currentCityId; i < destinationId; i++)


{
distance = distanceMap[i];
remain -= distance;

if (remain < 0)
{
if (!firstRechargeFound)
{
rechargeCities.push_back(i);
firstRechargeFound = true;
}
else if (secondRecharge == -1)
{
secondRecharge = i;
}

remain = capacityRange;
}
}
}

void displayInfo() const


{
string originName = nameMap[currentCityId];
string destinationName = nameMap[destinationId];
string firstRechargeName = (rechargeCities.size() >= 1) ?
nameMap[rechargeCities[0]] : "----";
string secondRechargeName = (secondRecharge != -1) ?
nameMap[secondRecharge] : "----";

cout << left << setw(4) << vehicleId;


cout << left << setw(20) << originName;
cout << left << setw(20) << destinationName;
cout << left << setw(20) << capacityRange;
cout << left << setw(15) << remainRange;
cout << left << setw(15) << firstRechargeName;
cout << left << setw(20) << secondRechargeName << endl;
}
};

class DemandGenerator
{
public:
void generateDemandsToFile(const std::string &fileName, int numDemands)
{
std::ofstream file(fileName);
if (!file.is_open())
{
std::cerr << "File creation failed!" << std::endl;
return;
}

std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> destDistribution(1, NUM_CITIES - 1); //
Destination ID range (1 to NUM_CITIES - 1)
std::uniform_int_distribution<int> capacityDistribution(MIN_CAPACITY,
MAX_CAPACITY);
std::uniform_int_distribution<int> remainDistribution(0, MAX_CAPACITY);

int vehicleId = 200;


for (int i = 0; i < numDemands; ++i)
{
vehicleId++;
int destinationId = destDistribution(gen);
int capacityRange = capacityDistribution(gen);
int remainRange = std::min(capacityRange, remainDistribution(gen));

file << "[" << vehicleId << "," << destinationId << "," <<
capacityRange << "," << remainRange << "]\n";
}

file.close();
}
};

class ChargingAllocation
{
public:
void allocateChargingStations(const vector<Vehicle> &vehicles,
vector<ChargingStation> &stations)
{
// Initialize queue lengths for each charging station to 0
vector<int> queueLengths(NUM_CITIES, 0);

// Calculate queue lengths and waiting times for each vehicle


for (const Vehicle &vehicle : vehicles)
{
int remainingRange = vehicle.remainRange;
int currentCity = vehicle.currentCityId;

for (int i = 0; i < vehicle.rechargeCities.size(); i++)


{
int rechargeCity = vehicle.rechargeCities[i];
int queueLength = queueLengths[rechargeCity];

queueLength++;
queueLengths[rechargeCity] = queueLength;
}
}

// Display charging station information and waiting times


cout << left << setw(4) << "Location ID";
cout << left << setw(20) << "Location Name";
cout << left << setw(20) << "Distance to Sydney";
cout << left << setw(20) << "Number of Chargers";
cout << left << setw(15) << "Queue Length";
cout << left << setw(15) << "Waiting Hours" << endl;

double totalWaitingHours = 0.0;

for (int i = 0; i < NUM_CITIES; i++)


{
stations[i].queueLength = queueLengths[i];
stations[i].displayInfo();
totalWaitingHours += (0.5 * static_cast<double>(queueLengths[i]) /
stations[i].numberOfChargers);
}

cout << "Overall average waiting time per vehicle = " << fixed <<
setprecision(2) << (totalWaitingHours / vehicles.size()) << " hours" << endl;
}

void chargingAllocationLogic(const vector<Vehicle> &vehicles,


vector<ChargingStation> &stations)
{
// Sort stations based on queue length in ascending order
sort(stations.begin(), stations.end(), [](const ChargingStation &a, const
ChargingStation &b) {
return a.queueLength < b.queueLength;
});

// Iterate through vehicles and allocate them to stations with the shortest
queues
for (const Vehicle &vehicle : vehicles)
{
int minQueueLength = INT_MAX;
int selectedStationIndex = -1;

// Find the station with the shortest queue


for (int i = 0; i < stations.size(); i++)
{
if (stations[i].queueLength < minQueueLength)
{
minQueueLength = stations[i].queueLength;
selectedStationIndex = i;
}
}

// Allocate the vehicle to the selected station


stations[selectedStationIndex].queueLength++;
}
}

void balanceWaitingQueues(const vector<Vehicle> &vehicles,


vector<ChargingStation> &stations)
{
const int numSimulations = 5000;
double bestOverallAvgWaitTime = numeric_limits<double>::max();

for (int simulation = 1; simulation <= 8; simulation++)


{
// Make a copy of the original station queue lengths
vector<int> originalQueueLengths(NUM_CITIES);
for (int i = 0; i < NUM_CITIES; i++)
{
originalQueueLengths[i] = stations[i].queueLength;
}

// Randomly shuffle the vehicles


vector<Vehicle> shuffledVehicles = vehicles;
random_shuffle(shuffledVehicles.begin(), shuffledVehicles.end());

// Allocate vehicles using the charging allocation logic


chargingAllocationLogic(shuffledVehicles, stations);

// Calculate the overall average waiting time


double totalWaitingHours = 0.0;

for (int i = 0; i < NUM_CITIES; i++)


{
totalWaitingHours += (0.5 *
static_cast<double>(stations[i].queueLength) / stations[i].numberOfChargers);
}

double overallAvgWaitTime = totalWaitingHours / vehicles.size();

// If the current allocation is better, update the best allocation


if (overallAvgWaitTime < bestOverallAvgWaitTime)
{
bestOverallAvgWaitTime = overallAvgWaitTime;
}
else
{
// Revert to the original queue lengths if the current allocation
is not better
for (int i = 0; i < NUM_CITIES; i++)
{
stations[i].queueLength = originalQueueLengths[i];
}
}

cout << "Improved overall average waiting time = " << fixed <<
setprecision(2) << bestOverallAvgWaitTime << " hours at simulation " << simulation
<< endl;
}

cout << "\nCharging allocation after balancing:" << endl;


cout << left << setw(4) << "Vehicle ID";
cout << left << setw(20) << "Destination";
cout << left << setw(20) << "Capacity Range";
cout << left << setw(20) << "Remaining Range";
cout << left << setw(20) << "First Recharge";
cout << left << setw(20) << "Second Recharge" << endl;

for (const Vehicle &vehicle : vehicles)


{
vehicle.displayInfo();
}
}
};

int main()
{
// Load charging station data
vector<ChargingStation> stations;

for (int i = 0; i < NUM_CITIES; i++)


{
ChargingStation station(i, nameMap[i], chargersMap[i]);
stations.push_back(station);
}

// Generate charging demands and write to a file


DemandGenerator demandGenerator;
const std::string fileName = "ChargingDemands.txt";
const int numDemands = 150 + (std::rand() % 51); // Random number of demands
between 150 and 200

demandGenerator.generateDemandsToFile(fileName, numDemands);

// Read vehicle data from the file


ifstream file(fileName);
if (!file.is_open())
{
cout << "File not found!" << endl;
return 0;
}

vector<Vehicle> vehicles;

string line;
while (getline(file, line))
{
int id, dest, capacity, remain;
if (sscanf(line.c_str(), "[%d,%d,%d,%d]", &id, &dest, &capacity, &remain)
== 4)
{
Vehicle vehicle(id, dest, capacity, remain);
vehicle.calculateRechargeCities();
vehicles.push_back(vehicle);
}
}

file.close();

// Display vehicle information


cout << "Vehicle Information:" << endl;
cout << left << setw(4) << "Vehicle ID";
cout << left << setw(20) << "Origin";
cout << left << setw(20) << "Destination";
cout << left << setw(20) << "Capacity Range";
cout << left << setw(20) << "Remaining Range" << endl;

for (const Vehicle &vehicle : vehicles)


{
vehicle.displayInfo();
}

// Display initial charging allocation


cout << "\nInitial Charging Allocation:" << endl;
cout << left << setw(4) << "Vehicle ID";
cout << left << setw(20) << "Destination";
cout << left << setw(20) << "Capacity Range";
cout << left << setw(20) << "Remaining Range";
cout << left << setw(20) << "First Recharge";
cout << left << setw(20) << "Second Recharge" << endl;

for (const Vehicle &vehicle : vehicles)


{
vehicle.displayInfo();
}

ChargingAllocation chargingAllocation;
chargingAllocation.allocateChargingStations(vehicles, stations);
const int numSimulations=8;
// Balance waiting queues with Monte-Carlo simulations
cout << "\nBalancing waiting queues with Monte-Carlo simulations." << endl;
cout << "Number of simulations = " << numSimulations << endl;
chargingAllocation.balanceWaitingQueues(vehicles, stations);

return 0;
}

You might also like