1#ifndef NeTrainSim_Network_h
2#define NeTrainSim_Network_h
11#include "../util/vector.h"
12#include <unordered_set>
17#include "../traindefinition/train.h"
18#include "../util/utils.h"
19#include "../util/error.h"
35 std::map<int, std::shared_ptr<NetNode>>
nodes;
61 Network(
const string& nodesFile,
const string& linksFile,
62 std::string netName =
"") {
68 this->networkName = netName;
79 this->networkSignals = generateSignals();
95 std::string,
double,
double>> nodesRecords,
96 Vector<tuple<
int,
int,
int,
double,
97 int,
double,
double,
int,
double,
98 bool, std::string, std::string,
99 double>> linksRecords,
100 std::string netName =
"") {
103 this->networkName =
"Unnamed Network";
106 this->networkName = netName;
115 this->networkSignals = generateSignals();
130 Vector<std::shared_ptr<NetLink>> theLinks,
131 std::string netName =
"") {
133 this->networkName =
"Unnamed Network";
136 this->networkName = netName;
138 this->theFileNodes = theNodes;
139 this->links = theLinks;
144 this->networkSignals = generateSignals();
155 std::map<int, std::shared_ptr<NetNode>> nodesMap;
156 for (std::shared_ptr<NetNode> &n : (this->theFileNodes)) {
172 for (
int i = 0; i < userDefinedTrainPath.size(); i++) {
174 userDefinedTrainPath)[i]));
176 return simulatorTrainPath;
190 double catenaryCumConsumed = 0.0;
191 double catenaryCumRegenerated = 0.0;
192 int nuOfCatenaryLinks = 0;
193 double totalLength = 0.0;
194 double totalLinkLengthsWithCatenary = 0.0;
195 for (
auto& link: this->
links) {
196 if (link->hasCatenary) {
197 nuOfCatenaryLinks += 1;
198 totalLinkLengthsWithCatenary += link->length;
200 catenaryCumConsumed += link->catenaryCumConsumedEnergy;
201 catenaryCumRegenerated += link->catenaryCumRegeneratedEnergy;
202 totalLength += link->length;
204 double percOfCatenaryLinks = (nuOfCatenaryLinks / this->links.size()) *
206 return std::make_tuple(percOfCatenaryLinks, catenaryCumConsumed,
207 catenaryCumRegenerated, totalLength,
208 totalLinkLengthsWithCatenary);
221 if (this->nodes.count(
id)) {
222 return this->nodes[id];
224 throw std::runtime_error(std::string(
"Error: ") +
225 std::to_string(
static_cast<int>(
227 "\nCould not find the simulator node ID: " +
228 std::to_string(
id) +
"\n");
243 std::shared_ptr<NetNode> node1,
244 std::shared_ptr<NetNode> node2) {
245 if (node1 == node2) {
return 0.0; }
246 int i1 = train->trainPathNodes.index(node1);
247 int i2 = train->trainPathNodes.index(node2);
248 if (i1 > i2) { swap(i1, i2); }
250 for (
int i = i1; i < i2; i++) {
253 train->trainPathNodes.at(i)->id,
254 train->trainPathNodes.at(nextI)->id,
271 std::shared_ptr<NetNode> node1,
272 std::shared_ptr<NetNode> node2) {
274 int n1 = train->trainPathNodes.index(node1);
275 int n2 = train->trainPathNodes.index(node2);
278 if (n1 > n2) { swap(n1, n2); }
280 for (
int i = n1; i < n2; i++) {
284 train->trainPathNodes.at(
285 i)->linkTo[train->trainPathNodes.at(nextI)];
287 train->trainPathNodes.at(
288 nextI)->linkTo[train->trainPathNodes.at(i)];
291 std::set<std::shared_ptr<NetLink>> temp;
292 if (l1.size() > 0) { temp.insert(l1.begin(), l1.end()); }
293 if (l2.size() > 0){ temp.insert(l2.begin(), l2.end()); }
296 if (temp.size() <= 1) {
return true; }
317 const std::shared_ptr <NetLink> link,
318 const std::shared_ptr <Train> train)
321 std::set<double> distanceToOtherTrains;
324 for (std::shared_ptr <Train>& t : link->currentTrains) {
326 distanceToOtherTrains.insert(
328 t->startEndPoints[1],
329 train->currentCoordinates));
333 return std::find_if(distanceToOtherTrains.begin(),
334 distanceToOtherTrains.end(),
337 }) == distanceToOtherTrains.end();
373 std::shared_ptr <Train> train,
374 double &travelledDistance) {
378 if (travelledDistance <= 0.0) {
379 return train->trainPathNodes[0]->coordinates();
384 if (travelledDistance >= train->trainTotalPathLength) {
385 return train->trainPathNodes.back()->coordinates();
389 for (
int i = 0; i < train->trainPath.size() - 1; i++) {
392 if (travelledDistance > train->linksCumLengths[i] &&
393 (i == train->trainPath.size() - 2 ||
394 travelledDistance <= train->linksCumLengths[i+1])) {
399 std::shared_ptr<NetNode> startNode = train->trainPathNodes[i];
400 std::shared_ptr<NetLink> link =
402 train->trainPath[nextI],
true);
405 double travelledDistanceOnLink =
406 travelledDistance - train->linksCumLengths[i];
410 return link->findPositionOnLink(travelledDistanceOnLink,
416 return std::make_pair(0.0, 0.0);
438 std::pair<double, double>
normalize(std::pair<double, double> vec) {
439 double length = sqrt(vec.first * vec.first + vec.second * vec.second);
442 return {vec.first / length, vec.second / length};
461 const std::vector<std::shared_ptr<NetNode>> nodeList) {
463 for (
const auto& node : nodeList) {
465 if (s->currentNode.lock() == node) {
492 const std::shared_ptr<Train> train,
494 int endID,
bool calcExact =
true) {
497 if (betweenNodesLinks.size() == 1) {
498 return betweenNodesLinks.at(0);
503 for (std::shared_ptr<NetLink> l : betweenNodesLinks) {
504 if (l->currentTrains.exist(train)) {
512 betweenNodesLinks.begin(),
513 betweenNodesLinks.end());
514 std::sort(betweenNLinks.begin(), betweenNLinks.end(),
515 [](std::shared_ptr<NetLink> a, std::shared_ptr<NetLink> b) {
516 return a->cost < b->cost; });
518 return betweenNLinks[0];
523 for (std::shared_ptr <NetLink> l : betweenNLinks) {
524 if (l->currentTrains.empty() || (isSameDirection(l, train) &&
529 return betweenNLinks[0];
547 std::shared_ptr<NetNode> startNode,
548 std::shared_ptr<NetNode> endNode) {
549 return startNode->linkTo.at(endNode);
566 for (
int i = 1; i < train->trainPath.size(); i++) {
569 train->trainPath.at(i),
589 const std::shared_ptr <Train> train,
591 int i = train->trainPath.index(startNodeID);
592 if (i < train->trainPath.size() - 1) {
594 int EndNodeID = train->trainPath.at(indx);
612 const std::shared_ptr <Train> train) {
613 if (train->trainPath.size() == 0) {
614 throw std::runtime_error(
"Error: " +
619 std::to_string(train->id) +
620 " path cannot be null!\n");
623 int strartID = train->trainPath.at(0);
641 int n = train->trainPath.size();
643 for (
int i = 1; i < n; i++) {
645 getDistanceToSpecificNodeFromStart(train,
646 train->trainPath.at(i));
648 return linksCumLengths;
667 std::shared_ptr<Train> train,
668 double travelledDistance,
669 int &previousNodeID) {
671 for (
int i = train->trainPath.index(previousNodeID);
672 train->trainPath.size(); i++) {
673 if (train->linksCumLengths.at(i) > travelledDistance) {
678 if (nextI == -1) { nextI = train->trainPath.size(); }
679 int prevI = nextI - 1;
680 return train->trainPathNodes.at(prevI);
699 double &travelledDistance,
700 int &previousNodeID) {
702 for (
int i = train->trainPath.index(previousNodeID);
703 train->trainPath.size(); i++) {
704 if (train->linksCumLengths.at(i) > travelledDistance) {
709 if (nextI == -1) { nextI = train->trainPath.size(); }
710 int prevI = nextI - 1;
712 train->trainPath.at(prevI),
713 train->trainPath.at(nextI),
731 for (
const std::shared_ptr<NetNode>& n : this->theFileNodes) {
732 if (n->userID == oldID) {
736 throw std::runtime_error(std::string(
"Error: ") +
737 std::to_string(
static_cast<int>(
739 "\nCould not find the node ID: " +
740 std::to_string(oldID) +
"\n");
758 std::shared_ptr<Train> train,
759 double& travelledDistance,
761 int endNodeIndex = train->trainPath.index(nodeID);
762 return train->linksCumLengths[endNodeIndex] - travelledDistance;
779 bool ccw(
const std::pair<double, double>& A,
780 const std::pair<double, double>& B,
781 const std::pair<double, double>& C) {
782 return (C.second - A.second) *
783 (B.first - A.first) > (B.second - A.second) *
801 const std::pair<double, double>& B,
802 const std::pair<double, double>& C,
803 const std::pair<double, double>& D) {
804 return (
ccw(A, C, D) !=
ccw(B, C, D)) && (
ccw(A, B, C) !=
ccw(A, B, D));
825 int startNodeID,
int targetNodeID) {
827 for (
auto& n : this->
nodes) {
828 n.second->clearGraphSearchParams();
831 std::shared_ptr<NetNode> startNode = this->
getNodeByID(startNodeID);
832 std::shared_ptr<NetNode> targetNode = this->
getNodeByID(targetNodeID);
834 startNode->graphSearchDistanceFromStart = 0.0;
837 while (! targetNode->graphSearchVisited) {
839 std::shared_ptr<NetNode> currentNode = minimumDistance();
841 if (currentNode ==
nullptr) {
break; }
843 currentNode->graphSearchVisited =
true;
845 for (
auto& connectedNode : currentNode->getNeighbors()) {
847 if ((currentNode->graphSearchDistanceFromStart +
848 currentNode->linkTo.at(connectedNode).at(0)->length) <
849 connectedNode->graphSearchDistanceFromStart) {
851 connectedNode->graphSearchDistanceFromStart =
852 currentNode->graphSearchDistanceFromStart +
853 currentNode->linkTo.at(connectedNode).at(0)->length;
854 connectedNode->graphSearchPreviousNode = currentNode;
860 path.push_back(targetNode);
862 std::shared_ptr<NetNode> node = path.back();
863 if (node->graphSearchPreviousNode ==
nullptr) {
break; }
865 path.push_back(node->graphSearchPreviousNode);
867 std::reverse(path.begin(), path.end());
868 return std::make_pair(path, targetNode->graphSearchDistanceFromStart);
884 std::shared_ptr<NetNode> minimumDistance() {
885 std::shared_ptr<NetNode> nextNode = std::shared_ptr<NetNode>();
886 double minValue = INFINITY;
887 for (
auto& node : this->
nodes) {
888 if (node.second->graphSearchDistanceFromStart < minValue &&
889 node.second->graphSearchVisited ==
false) {
890 minValue = node.second->graphSearchDistanceFromStart;
891 nextNode = node.second;
910 for (
const std::shared_ptr<NetLink> &l : this->
links) {
911 if (l->trafficSignalNo != 0 && l->trafficSignalNo != 10001) {
912 if (l->direction == 1) {
914 if (l->trafficSignalAtEnd.exist(l->toLoc->userID)) {
919 std::shared_ptr<NetSignal> sharedSignal =
920 std::make_shared<NetSignal>(networkSignal);
921 l->toLoc->addSignal(sharedSignal);
925 if (l->trafficSignalAtEnd.exist(l->fromLoc->userID)) {
930 std::shared_ptr<NetSignal> sharedSignal =
931 std::make_shared<NetSignal>(networkSignal);
932 l->fromLoc->addSignal(sharedSignal);
938 if (l->trafficSignalAtEnd.exist(l->toLoc->userID)) {
943 std::shared_ptr<NetSignal> sharedSignal1 =
944 std::make_shared<NetSignal>(networkSignal1);
945 l->toLoc->addSignal(sharedSignal1);
949 if (l->trafficSignalAtEnd.exist(l->fromLoc->userID)) {
954 std::shared_ptr<NetSignal> sharedSignal2 =
955 std::make_shared<NetSignal>(networkSignal2);
956 l->fromLoc->addSignal(sharedSignal2);
963 else if (l->trafficSignalNo == 10001){
964 l->toLoc->isDepot =
true;
975 void defineNodesLinks() {
976 for (std::shared_ptr<NetLink>& l : this->
links) {
977 if (l->direction == 1){
978 l->fromLoc.get()->linkTo[l->toLoc].push_back(l);
982 l->fromLoc.get()->linkTo[l->toLoc].push_back(l);
983 l->toLoc.get()->linkTo[l->fromLoc].push_back(l);
997 void updateLinksLength() {
998 for (std::shared_ptr<NetLink> &l : this->
links) {
999 std::shared_ptr<NetNode> n1 = l->fromLoc;
1000 std::shared_ptr<NetNode> n2 = l->toLoc;
1001 double dx = n2->x - n1->x;
1002 double dy = n2->y - n1->y;
1003 double lLength = sqrt(dx * dx + dy * dy);
1005 throw std::runtime_error(
"Error: " +
1006 std::to_string(
static_cast<int>(
1008 "\nHorizontal distance between nodes" +
1009 " should be greater than 0!" +
1010 "\nReview the nodes file!... " +
1011 std::to_string(l->id) +
1012 "'s length is equal to zero!\n");
1014 l->length = lLength;
1030 bool isSameDirection(std::shared_ptr<NetLink> link,
1031 std::shared_ptr <Train> train) {
1032 std::set<bool> allTrainsAreInSameDirection;
1033 for (
const std::shared_ptr<Train>& t : link->currentTrains) {
1035 allTrainsAreInSameDirection.insert(
1036 std::is_permutation(t->trainPath.begin(),
1038 train->trainPath.begin(),
1039 train->trainPath.end()));
1042 return !allTrainsAreInSameDirection.count(
false);
1053 double getDistanceToSpecificNodeFromStart(std::shared_ptr<Train> train,
1056 for (
int i = 1; i < train->trainPath.size(); i++) {
1059 train->trainPath.at(prevI),
1060 train->trainPath.at(i),
1062 if (train->trainPath.at(i) == nodeID) {
1078 ostr <<
"the network has " << stud.
nodes.size() <<
" nodes and " <<
1079 stud.
links.size() <<
"links." << endl;
The NetSignal class represents a network signal in a simulation.
Definition netsignal.h:35
This class defined a network for trains.
Definition network.h:27
bool DistanceToEndOfAllLinkTrainsIsLarge(const std::shared_ptr< NetLink > link, const std::shared_ptr< Train > train)
Checks if the distance to the end of all leading trains on a link is larger than a certain threshold ...
Definition network.h:316
std::shared_ptr< NetNode > getNodeByID(int &id)
Gets node by identifier.
Definition network.h:220
friend ostream & operator<<(ostream &ostr, Network &stud)
Stream insertion operator.
Definition network.h:1077
std::pair< Vector< std::shared_ptr< NetNode > >, double > shortestPathSearch(int startNodeID, int targetNodeID)
Performs a shortest path search between two nodes.
Definition network.h:824
Network(Vector< tuple< int, double, double, std::string, double, double > > nodesRecords, Vector< tuple< int, int, int, double, int, double, double, int, double, bool, std::string, std::string, double > > linksRecords, std::string netName="")
Constructor for the Network class.
Definition network.h:94
Vector< std::shared_ptr< NetLink > > links
The links.
Definition network.h:37
std::shared_ptr< NetNode > getPreviousNodeByDistance(std::shared_ptr< Train > train, double travelledDistance, int &previousNodeID)
Retrieves the previous node in the train's path given a travelled distance.
Definition network.h:666
Vector< std::shared_ptr< NetSignal > > getSignalsByCurrentNodeList(const std::vector< std::shared_ptr< NetNode > > nodeList)
Fetches the network signals associated with the list of given nodes.
Definition network.h:460
std::shared_ptr< NetLink > getLinkByStartandEndNodeID(const std::shared_ptr< Train > train, int startID, int endID, bool calcExact=true)
Fetches the network link by start and end node identifiers.
Definition network.h:491
bool ccw(const std::pair< double, double > &A, const std::pair< double, double > &B, const std::pair< double, double > &C)
Checks if three points make a counter-clockwise turn.
Definition network.h:779
Vector< int > getSimulatorTrainPath(Vector< int > userDefinedTrainPath)
Gets simulator train path.
Definition network.h:170
Network()
Default constructor.
Definition network.h:47
bool isConflictZone(std::shared_ptr< Train > train, std::shared_ptr< NetNode > node1, std::shared_ptr< NetNode > node2)
Checks if there's a conflict zone between two nodes for the given train.
Definition network.h:270
std::string networkName
Holds the name of the network.
Definition network.h:33
std::shared_ptr< NetLink > getLinkFromDistance(std::shared_ptr< Train > train, double &travelledDistance, int &previousNodeID)
Retrieves the link in the train's path that includes a specified travelled distance.
Definition network.h:698
tuple< double, double, double, double, double > getNetworkStats()
Gets the network statistics.
Definition network.h:189
std::shared_ptr< NetLink > getLinkByStartNodeID(const std::shared_ptr< Train > train, int startNodeID)
Retrieves a network link originating from a specified start node.
Definition network.h:588
double getDistanceBetweenTwoNodes(std::shared_ptr< Train > train, std::shared_ptr< NetNode > node1, std::shared_ptr< NetNode > node2)
Computes the distance between two nodes on a given train's path.
Definition network.h:242
std::shared_ptr< NetLink > getFirstTrainLink(const std::shared_ptr< Train > train)
Retrieves the first link in a train's path.
Definition network.h:611
double getDistanceToSpecificNodeByTravelledDistance(std::shared_ptr< Train > train, double &travelledDistance, int &nodeID)
Calculates the distance to a specific node given a travelled distance.
Definition network.h:757
Vector< std::shared_ptr< NetLink > > getLinksByStartandEndNode(std::shared_ptr< NetNode > startNode, std::shared_ptr< NetNode > endNode)
Retrieves the network links between a specified start node and end node.
Definition network.h:546
std::map< int, std::shared_ptr< NetNode > > defineNodes()
Define nodes.
Definition network.h:154
Network(const string &nodesFile, const string &linksFile, std::string netName="")
Constructor for the Network class.
Definition network.h:61
Vector< double > generateCumLinksLengths(std::shared_ptr< Train > train)
Generates a vector containing the cumulative lengths of the train's path.
Definition network.h:640
std::pair< double, double > normalize(std::pair< double, double > vec)
Normalize a 2D vector.
Definition network.h:438
std::map< int, std::shared_ptr< NetNode > > nodes
The nodes mapped by its simulator id.
Definition network.h:35
int getSimulatorNodeIDByUserID(int oldID)
Translates a user-provided node identifier to a simulator-specific node identifier.
Definition network.h:730
pair< double, double > getPositionbyTravelledDistance(std::shared_ptr< Train > train, double &travelledDistance)
Computes the position of a train based on its travelled distance along a path.
Definition network.h:372
double getFullPathLength(std::shared_ptr< Train > train)
Calculates the total length of the train's path.
Definition network.h:563
bool twoLinesIntersect(const std::pair< double, double > &A, const std::pair< double, double > &B, const std::pair< double, double > &C, const std::pair< double, double > &D)
Checks if two lines intersect.
Definition network.h:800
Vector< std::shared_ptr< NetSignal > > networkSignals
The signals.
Definition network.h:39
Network(Vector< std::shared_ptr< NetNode > > theNodes, Vector< std::shared_ptr< NetLink > > theLinks, std::string netName="")
Constructor for the Network class.
Definition network.h:129
A vector.
Definition vector.h:24
Vector< std::tuple< int, double, double, std::string, double, double > > readNodesFile(const std::string &fileName)
Reads the nodes file.
Definition readwritenetwork.cpp:24
Vector< std::shared_ptr< NetLink > > generateLinks(Vector< std::shared_ptr< NetNode > > theFileNodes, Vector< std::tuple< int, int, int, double, int, double, double, int, double, bool, string, string, double > > linksRecords)
Generates NetLink objects from the nodes and links records.
Vector< std::tuple< int, int, int, double, int, double, double, int, double, bool, string, string, double > > readLinksFile(const std::string &fileName)
Reads the links file.
Definition readwritenetwork.cpp:134
Vector< std::shared_ptr< NetNode > > generateNodes(Vector< std::tuple< int, double, double, std::string, double, double > > nodesRecords)
Generates NetNode objects from the nodes records.
Definition readwritenetwork.cpp:266
std::string getPrefix(std::string str)
Definition utils.h:210
std::string trim(const std::string &str)
This function trim takes in a string str and returns a copy of it with leading and trailing white spa...
Definition utils.h:328
double getDistanceByTwoCoordinates(const std::pair< double, double > &position1, const std::pair< double, double > &position2)
Computes the Euclidean distance between two coordinates.
Definition utils.h:83
std::string getFilenameWithoutExtension(std::string path)
Definition utils.h:200
This file contains the declaration of the NetLink class.
This file contains the declaration of the NetNode class.
This file contains the declaration of the NetSignal class.
This file contains the declaration of the ReadWriteNetwork namespace.