Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Algorithms/CSA/CSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,4 @@ class CSA {

Profiler profiler;
};
}
}
2 changes: 1 addition & 1 deletion Algorithms/CSA/ULTRACSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,4 +249,4 @@ class ULTRACSA {
Profiler profiler;

};
}
}
412 changes: 412 additions & 0 deletions Algorithms/RAPTOR/RAPTOR.h

Large diffs are not rendered by default.

470 changes: 470 additions & 0 deletions Algorithms/RAPTOR/ULTRARAPTOR.h

Large diffs are not rendered by default.

14 changes: 12 additions & 2 deletions DataStructures/RAPTOR/Data.h
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,13 @@ class Data {
}
}

// ---
inline void sortTransferGraphEdgesByTravelTime() noexcept {
transferGraph.sortEdges(TravelTime);
}

// ---

inline void applyVertexPermutation(const Permutation& permutation, const bool permutateStops = true) noexcept {
Permutation splitPermutation = permutation.splitAt(numberOfStops());
if (!permutateStops) {
Expand Down Expand Up @@ -773,20 +780,23 @@ class Data {
std::ofstream file(fileName);
Assert(file, "cannot open file: " << fileName);
Assert(file.is_open(), "cannot open file: " << fileName);
file << "LineId,TripId,StopIndex,ArrivalTime,DepartureTime\n";
file << "LineId,TripId,StopIndex,StopId,ArrivalTime,DepartureTime\n";
for (const RouteId route : routes()) {
const StopId* stops = stopArrayOfRoute(route); // Get the array of StopIds for the current route
const StopEvent* stopEvents = firstTripOfRoute(route);
const size_t tripLength = numberOfStopsInRoute(route);
for (size_t i = 0; i < numberOfTripsInRoute(route); i++) {
for (size_t j = 0; j < tripLength; j++) {
const StopEvent& stopEvent = stopEvents[(i * tripLength) + j];
file << route.value() << "," << i << "," << j << "," << stopEvent.arrivalTime << "," << stopEvent.departureTime << "\n";
const StopId stopId = stops[j]; // Get the StopId corresponding to the StopIndex
file << route.value() << "," << i << "," << j << "," << stopId.value() << "," << stopEvent.arrivalTime << "," << stopEvent.departureTime << "\n";
}
}
}
file.close();
}


inline void writeFootpathCSV(const std::string& fileName) const noexcept {
std::ofstream file(fileName);
Assert(file, "cannot open file: " << fileName);
Expand Down
266 changes: 256 additions & 10 deletions Runnables/Commands/BenchmarkULTRA.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ using namespace Shell;
#include "../../Algorithms/RAPTOR/ULTRARAPTOR.h"
#include "../../Algorithms/TripBased/Query/Query.h"
#include "../../Algorithms/TripBased/Query/TransitiveQuery.h"
#include "../../DataStructures/RAPTOR/Entities/Journey.h"
#include "../../DataStructures/CSA/Entities/Journey.h"

#include "../../DataStructures/Queries/Queries.h"
#include "../../DataStructures/CSA/Data.h"
Expand Down Expand Up @@ -107,7 +109,6 @@ class RunHLCSAQueries : public ParameterizedCommand {
algorithm.getProfiler().printStatistics();
}
};

class RunULTRACSAQueries : public ParameterizedCommand {

public:
Expand Down Expand Up @@ -142,25 +143,165 @@ class RunTransitiveRAPTORQueries : public ParameterizedCommand {
ParameterizedCommand(shell, "runTransitiveRAPTORQueries", "Runs the given number of random transitive RAPTOR queries.") {
addParameter("RAPTOR input file");
addParameter("Number of queries");
addParameter("Pruning rule (0 or 1)");
}

virtual void execute() noexcept {
RAPTOR::Data raptorData = RAPTOR::Data::FromBinary(getParameter("RAPTOR input file"));
raptorData.useImplicitDepartureBufferTimes();
raptorData.writeCSV("");
raptorData.printInfo();
RAPTOR::RAPTOR<true, RAPTOR::AggregateProfiler, true, false> algorithm(raptorData);

const size_t n = getParameter<size_t>("Number of queries");
const std::vector<StopQuery> queries = generateRandomStopQueries(raptorData.numberOfStops(), n);

double numJourneys = 0;
for (const StopQuery& query : queries) {
algorithm.run(query.source, query.departureTime, query.target);
numJourneys += algorithm.getJourneys().size();
// READ THE NEW INTEGER PARAMETER
const int pruningRule = getParameter<int>("Pruning rule (0 or 1)");

// We use an if-else block to instantiate the correct version of the algorithm,
// as the `ENABLE_PRUNING` template parameter must be a compile-time constant.
if (pruningRule == 1) {
// Instantiate with TARGET_PRUNING=true and ENABLE_PRUNING=1
RAPTOR::RAPTOR<true, RAPTOR::AggregateProfiler, true, false, false> algorithm(raptorData);

double numJourneys = 0;
for (const StopQuery& query : queries) {
algorithm.run(query.source, query.departureTime, query.target);
numJourneys += algorithm.getJourneys().size();
}
algorithm.getProfiler().printStatistics();
std::cout << "Avg. journeys: " << String::prettyDouble(numJourneys / n) << std::endl;
} else {
// Instantiate with TARGET_PRUNING=true and ENABLE_PRUNING=0 (default)
RAPTOR::RAPTOR_prune<true, RAPTOR::AggregateProfiler, true, false, false> algorithm(raptorData);

double numJourneys = 0;
for (const StopQuery& query : queries) {
algorithm.run(query.source, query.departureTime, query.target);
numJourneys += algorithm.getJourneys().size();
}
algorithm.getProfiler().printStatistics();
std::cout << "Avg. journeys: " << String::prettyDouble(numJourneys / n) << std::endl;
}
algorithm.getProfiler().printStatistics();
std::cout << "Avg. journeys: " << String::prettyDouble(numJourneys/n) << std::endl;
}
};

class TestTransitiveRAPTORQueries : public ParameterizedCommand {

public:
TestTransitiveRAPTORQueries(BasicShell& shell) :
ParameterizedCommand(shell, "testTransitiveRAPTORQueries", "Tests a specific transitive RAPTOR query.") {
addParameter("RAPTOR input file");
addParameter("sourceStop");
addParameter("targetStop");
addParameter("startTime");
}

virtual void execute() noexcept {
RAPTOR::Data raptorData = RAPTOR::Data::FromBinary(getParameter("RAPTOR input file"));
raptorData.useImplicitDepartureBufferTimes();
raptorData.printInfo();

const StopId sourceStop = StopId(getParameter<int>("sourceStop"));
const StopId targetStop = StopId(getParameter<int>("targetStop"));

const int startTime = getParameter<int>("startTime");

std::cout << "Running query from stop " << sourceStop << " to stop " << targetStop << " at time " << startTime << std::endl;

RAPTOR::RAPTOR<true, RAPTOR::AggregateProfiler, true, false, false> algorithm(raptorData);
algorithm.run(sourceStop, startTime, targetStop);

// Corrected line: calling the existing getEarliestJourney function
const RAPTOR::Journey journey = algorithm.getEarliestJourney(targetStop);
std::cout << "Journey: " << journey << std::endl;

}
};

class TestTransitiveCSAQueries : public ParameterizedCommand {

public:
TestTransitiveCSAQueries(BasicShell& shell) :
ParameterizedCommand(shell, "testTransitiveCSAQueries", "Tests a specific transitive CSA query.") {
addParameter("CSA input file");
addParameter("sourceStop");
addParameter("targetStop");
addParameter("startTime");
}

virtual void execute() noexcept {
CSA::Data csaData = CSA::Data::FromBinary(getParameter("CSA input file"));
csaData.sortConnectionsAscending();
csaData.printInfo();

const StopId sourceStop = StopId(getParameter<int>("sourceStop"));
const StopId targetStop = StopId(getParameter<int>("targetStop"));
const int startTime = getParameter<int>("startTime");

std::cout << "Running query from stop " << sourceStop << " to stop " << targetStop << " at time " << startTime << std::endl;

CSA::CSA<true, CSA::AggregateProfiler> algorithm(csaData);
algorithm.run(sourceStop, startTime, targetStop);

const int arrivalTime = algorithm.getEarliestArrivalTime(targetStop);
std::cout << "Earliest Arrival Time: " << arrivalTime << std::endl;

const CSA::Journey journey = algorithm.getJourney(targetStop);
std::cout << "Journey: " << journey << std::endl;
}
};

class CheckRAPTORPruning : public ParameterizedCommand {

public:
CheckRAPTORPruning(BasicShell& shell) :
ParameterizedCommand(shell, "checkRAPTORPruning", "Checks if RAPTOR pruning rules yield the same results as no pruning.") {
addParameter("RAPTOR input file");
addParameter("Number of queries");
}

virtual void execute() noexcept {
RAPTOR::Data raptorData = RAPTOR::Data::FromBinary(getParameter("RAPTOR input file"));
raptorData.useImplicitDepartureBufferTimes();

const size_t n = getParameter<size_t>("Number of queries");
// Generate StopQueries, not VertexQueries
const std::vector<StopQuery> queries = generateRandomStopQueries(raptorData.numberOfStops(), n);

std::vector<int> results_no_pruning;
std::vector<int> results_pruning_1;

// Run with pruning rule 0 (no pruning)
std::cout << "--- Running with No Pruning (Rule 0) ---" << std::endl;
RAPTOR::RAPTOR<true, RAPTOR::AggregateProfiler, true, false, false> algo_no_pruning(raptorData);
for (const StopQuery& query : queries) {
algo_no_pruning.run(query.source, query.departureTime, query.target);
results_no_pruning.push_back(algo_no_pruning.getEarliestArrivalTime(query.target));
}
std::cout << "--- Statistics for No Pruning (Rule 0) ---" << std::endl;
algo_no_pruning.getProfiler().printStatistics();

// Run with pruning rule 1
std::cout << "\n--- Running with Pruning Rule 1 ---" << std::endl;
// The transfer graph must be sorted for pruning rule 1 to be effective
raptorData.sortTransferGraphEdgesByTravelTime();
RAPTOR::RAPTOR_prune<true, RAPTOR::AggregateProfiler, true, false, false> algo_pruning_1(raptorData);
for (const StopQuery& query : queries) {
algo_pruning_1.run(query.source, query.departureTime, query.target);
results_pruning_1.push_back(algo_pruning_1.getEarliestArrivalTime(query.target));
}
std::cout << "--- Statistics for Pruning Rule 1 ---" << std::endl;
algo_pruning_1.getProfiler().printStatistics();

// Compare the results
bool pruning_1_correct = (results_no_pruning == results_pruning_1);
std::cout << "\n--- Comparison Results ---" << std::endl;
if (pruning_1_correct) {
std::cout << "Pruning rule 1 results match no-pruning results. The pruning is correct." << std::endl;
} else {
std::cout << "ERROR: Pruning rule 1 failed comparison. Results are not identical." << std::endl;
}
}
};

Expand Down Expand Up @@ -234,18 +375,124 @@ class RunULTRARAPTORQueries : public ParameterizedCommand {
addParameter("RAPTOR input file");
addParameter("CH data");
addParameter("Number of queries");
addParameter("Pruning rule (0 or 1)");
}

virtual void execute() noexcept {
RAPTOR::Data raptorData = RAPTOR::Data::FromBinary(getParameter("RAPTOR input file"));
raptorData.useImplicitDepartureBufferTimes();
raptorData.sortTransferGraphEdgesByTravelTime(); // Call to sort the transfer graph edges
raptorData.printInfo();
CH::CH ch(getParameter("CH data"));
RAPTOR::ULTRARAPTOR<RAPTOR::AggregateProfiler, false> algorithm(raptorData, ch);
// RAPTOR::ULTRARAPTOR<RAPTOR::AggregateProfiler, false> algorithm(raptorData, ch);
const size_t n = getParameter<size_t>("Number of queries");
// Read the pruning rule from the user
const int pruningRule = getParameter<int>("Pruning rule (0 or 1)");
const std::vector<VertexQuery> queries = generateRandomVertexQueries(ch.numVertices(), n);
// double numJourneys = 0;
//for (const VertexQuery& query : queries) {
// algorithm.run(query.source, query.departureTime, query.target);
// numJourneys += algorithm.getJourneys().size();
//}
//algorithm.getProfiler().printStatistics();
auto runAndProfile = [&](auto& algorithm) {
double numJourneys = 0;
for (const VertexQuery& query : queries) {
algorithm.run(query.source, query.departureTime, query.target);
numJourneys += algorithm.getJourneys().size();
}
algorithm.getProfiler().printStatistics();
std::cout << "Avg. journeys: " << String::prettyDouble(numJourneys/n) << std::endl;
};

switch (pruningRule) {
case 0: {
RAPTOR::ULTRARAPTOR<RAPTOR::AggregateProfiler, false> algorithm(raptorData, ch);
runAndProfile(algorithm);
break;
}
case 1: {
RAPTOR::ULTRARAPTOR_prune<RAPTOR::AggregateProfiler, false> algorithm(raptorData, ch);
runAndProfile(algorithm);
break;
}
default: {
std::cout << "Invalid pruning rule. Please choose 0 or 1" << std::endl;
break;
}
}
}
};

class CheckULTRARAPTORPruning : public ParameterizedCommand {

public:
CheckULTRARAPTORPruning(BasicShell& shell) :
ParameterizedCommand(shell, "checkULTRARAPTORPruning", "Checks if pruning rules yield the same results as no pruning.") {
addParameter("RAPTOR input file");
addParameter("CH data");
addParameter("Number of queries");
}

virtual void execute() noexcept {
RAPTOR::Data raptorData = RAPTOR::Data::FromBinary(getParameter("RAPTOR input file"));
raptorData.useImplicitDepartureBufferTimes();
CH::CH ch(getParameter("CH data"));

const size_t n = getParameter<size_t>("Number of queries");
const std::vector<VertexQuery> queries = generateRandomVertexQueries(ch.numVertices(), n);

std::vector<int> results_no_pruning;
std::vector<int> results_pruning_1;
std::vector<int> results_pruning_2;

// Run with pruning rule 0 (no pruning)
RAPTOR::ULTRARAPTOR<RAPTOR::AggregateProfiler, false> algo_no_pruning(raptorData, ch);
for (const VertexQuery& query : queries) {
algo_no_pruning.run(query.source, query.departureTime, query.target);
results_no_pruning.push_back(algo_no_pruning.getEarliestArrivalTime());
}
std::cout << "--- Statistics for No Pruning (Rule 0) ---" << std::endl;
algo_no_pruning.getProfiler().printStatistics();


// Run with pruning rule 1
raptorData.sortTransferGraphEdgesByTravelTime();
RAPTOR::ULTRARAPTOR_prune<RAPTOR::AggregateProfiler, false> algo_pruning_1(raptorData, ch);
for (const VertexQuery& query : queries) {
algo_pruning_1.run(query.source, query.departureTime, query.target);
results_pruning_1.push_back(algo_pruning_1.getEarliestArrivalTime());
}
std::cout << "--- Statistics for Pruning Rule 1 ---" << std::endl;
algo_pruning_1.getProfiler().printStatistics();

// Compare the results
bool pruning_1_correct = (results_no_pruning == results_pruning_1);

if (!pruning_1_correct) {
std::cout << "Pruning rule 1 failed comparison." << std::endl;
}
}
};

class RunULTRARAPTORQueries_updated : public ParameterizedCommand {

public:
RunULTRARAPTORQueries_updated(BasicShell& shell) :
ParameterizedCommand(shell, "runULTRARAPTORQueries", "Runs the given number of random ULTRA-RAPTOR queries.") {
addParameter("RAPTOR input file");
addParameter("CH data");
addParameter("Number of queries");
}

virtual void execute() noexcept {
RAPTOR::Data raptorData = RAPTOR::Data::FromBinary(getParameter("RAPTOR input file"));
raptorData.useImplicitDepartureBufferTimes();
raptorData.printInfo();
CH::CH ch(getParameter("CH data"));
RAPTOR::ULTRARAPTOR<RAPTOR::AggregateProfiler, false> algorithm(raptorData, ch);
const size_t n = getParameter<size_t>("Number of queries");
const std::vector<VertexQuery> queries = generateRandomVertexQueries(ch.numVertices(), n);
double numJourneys = 0;
for (const VertexQuery& query : queries) {
algorithm.run(query.source, query.departureTime, query.target);
Expand Down Expand Up @@ -284,7 +531,6 @@ class RunTransitiveTBQueries : public ParameterizedCommand {
};

class RunULTRATBQueries : public ParameterizedCommand {

public:
RunULTRATBQueries(BasicShell& shell) :
ParameterizedCommand(shell, "runULTRATBQueries", "Runs the given number of random ULTRA-TB queries.") {
Expand Down
4 changes: 4 additions & 0 deletions Runnables/ULTRA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ int main(int argc, char** argv) {
new RunDijkstraRAPTORQueries(shell);
new RunHLRAPTORQueries(shell);
new RunULTRARAPTORQueries(shell);
new CheckULTRARAPTORPruning(shell);
new CheckRAPTORPruning(shell);
new TestTransitiveRAPTORQueries(shell);
new TestTransitiveCSAQueries(shell);
new RunTransitiveTBQueries(shell);
new RunULTRATBQueries(shell);

Expand Down