Skip to content
This repository has been archived by the owner on Jan 24, 2024. It is now read-only.

Get best airflights with airport code and name #33

Merged
merged 5 commits into from
Dec 28, 2023
Merged
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
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ add_executable(feup_aed2 main.cpp
include/Flight.h
src/Program.cpp
include/Program.h
src/FlightPath.cpp
include/FlightPath.h
)

add_subdirectory(docs)
Expand All @@ -47,6 +49,8 @@ add_executable(tests test/tests.cpp
include/Flight.h
src/Program.cpp
include/Program.h
src/FlightPath.cpp
include/FlightPath.h
)
target_link_libraries(
tests
Expand Down
6 changes: 6 additions & 0 deletions include/Dataset.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <unordered_set>
#include "City.h"
#include "FlightPath.h"

typedef Graph<AirportInfo, FlightInfo, AirportInfoHash> Network;
typedef VertexSet<AirportInfo, FlightInfo, AirportInfoHash> AirportSet;
Expand Down Expand Up @@ -45,6 +46,9 @@ class Dataset {
std::vector<CityRef> getReachableCitiesfromAirport(AirportRef airport, int x);
std::vector<CountryRef> getReachableCountriesfromAirport(AirportRef airport, int x);

FlightPath getBestFlightPath(const AirportRef &src, const AirportRef &dest) const;
std::vector<FlightPath> getBestFlightPaths(const std::vector<AirportRef> &srcs, const std::vector<AirportRef> &dests) const;

private:
CountrySet countrySet_;
CitySet citySet_;
Expand All @@ -53,6 +57,8 @@ class Dataset {

CityRef getOrInsertCity(const std::string& name, const std::string& country);
CountryRef getOrInsertCountry(const std::string& name);

static double calculateDistance(double lat1, double lon1, double lat2, double lon2);
};


Expand Down
4 changes: 1 addition & 3 deletions include/Flight.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,14 @@ class AirportInfo;

class FlightInfo {
public:
explicit FlightInfo(AirlineRef airline, const AirportInfo& src, const AirportInfo& dest);
explicit FlightInfo(AirlineRef airline, double distance);

const AirlineRef &getAirline() const;
double getDistance() const;

private:
AirlineRef airline_;
double distance_;

static double calculateDistance(const AirportInfo& src, const AirportInfo& dest);
};

typedef Edge<AirportInfo, FlightInfo> Flight;
Expand Down
26 changes: 26 additions & 0 deletions include/FlightPath.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef FEUP_AED2_FLIGHTPATH_H
#define FEUP_AED2_FLIGHTPATH_H


#include <vector>
#include "Airport.h"

class FlightPath {
public:
FlightPath();

FlightPath(const std::vector<AirportRef> &airports, double distance);

const std::vector<AirportRef> &getAirports() const;
std::vector<AirportRef> &getAirports();
double getDistance() const;
void setDistance(double distance);
int getFlights() const;

private:
std::vector<AirportRef> airports_;
double distance_;
};


#endif //FEUP_AED2_FLIGHTPATH_H
13 changes: 13 additions & 0 deletions include/Graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class Vertex {
void setNum(int num);
int getLow() const;
void setLow(int low);
VertexRef<VertexInfo, EdgeInfo> getParent();
void setParent(VertexRef<VertexInfo, EdgeInfo> parent);
const std::vector<Edge<VertexInfo, EdgeInfo>> &getAdj() const;
void addEdge(VertexRef<VertexInfo, EdgeInfo> dest, const EdgeInfo &info);

Expand All @@ -55,6 +57,7 @@ class Vertex {
int indegree_;
int num_;
int low_;
VertexRef<VertexInfo, EdgeInfo> parent_;
};


Expand Down Expand Up @@ -168,6 +171,16 @@ void Vertex<VertexInfo, EdgeInfo>::setLow(int low) {
low_ = low;
}

template<class VertexInfo, class EdgeInfo>
VertexRef<VertexInfo, EdgeInfo> Vertex<VertexInfo, EdgeInfo>::getParent() {
return parent_;
}

template<class VertexInfo, class EdgeInfo>
void Vertex<VertexInfo, EdgeInfo>::setParent(VertexRef<VertexInfo, EdgeInfo> parent) {
parent_ = parent;
}

template<class VertexInfo, class EdgeInfo>
const std::vector<Edge<VertexInfo, EdgeInfo>> &Vertex<VertexInfo, EdgeInfo>::getAdj() const {
return adj_;
Expand Down
3 changes: 3 additions & 0 deletions include/Program.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ class Program {
Dataset dataset_;

void displayMainMenu();
void chooseBestFlight();
std::vector<AirportRef> chooseAirportsForBestFlight();
static void displayBestFlight(const std::vector<FlightPath> &paths);

static int receiveOption(int max);
CountryRef receiveCountry() const;
Expand Down
89 changes: 88 additions & 1 deletion src/Dataset.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <fstream>
#include <limits>
#include <sstream>
#include <queue>
#include <cmath>
#include "Dataset.h"

using namespace std;
Expand Down Expand Up @@ -80,7 +82,9 @@ void Dataset::readFlights() {
AirportInfo sourceAirport = getAirport(source).lock()->getInfo();
AirportInfo targetAirport = getAirport(target).lock()->getInfo();
AirlineRef airline = getAirline(airlineCode);
FlightInfo flightInfo(airline, sourceAirport, targetAirport);
double distance = calculateDistance(sourceAirport.getLatitude(), sourceAirport.getLongitude(),
targetAirport.getLatitude(), targetAirport.getLongitude());
FlightInfo flightInfo(airline, distance);
network_.addEdge(sourceAirport, targetAirport, flightInfo);
}
}
Expand Down Expand Up @@ -232,3 +236,86 @@ const CitySet &Dataset::getCities() const {
const AirportSet &Dataset::getAirports() const {
return network_.getVertexSet();
}

FlightPath Dataset::getBestFlightPath(const AirportRef &src, const AirportRef &dest) const {
for (AirportRef airport: network_.getVertexSet()) {
airport.lock()->setVisited(false);
airport.lock()->setParent(AirportRef());
}
queue<AirportRef> airportQueue;
airportQueue.push(src);
src.lock()->setVisited(true);
while (!airportQueue.empty()) {
AirportRef parent = airportQueue.front();
airportQueue.pop();
if (parent.lock()->getInfo().getCode() == dest.lock()->getInfo().getCode())
break;

for (const Flight& flight: parent.lock()->getAdj()) {
AirportRef child = flight.getDest();
if (!child.lock()->isVisited()) {
airportQueue.push(child);
child.lock()->setVisited(true);
child.lock()->setParent(parent);
}
}
}

if (!dest.lock()->isVisited())
return {};

FlightPath path;
double distance = 0.0;
path.getAirports().push_back(dest);
AirportRef curr = dest;
while (curr.lock()->getInfo().getCode() != src.lock()->getInfo().getCode()) {
AirportRef next = curr.lock()->getParent();
distance += calculateDistance(
curr.lock()->getInfo().getLatitude(),
curr.lock()->getInfo().getLongitude(),
next.lock()->getInfo().getLatitude(),
next.lock()->getInfo().getLongitude()
);
curr = next;
path.getAirports().push_back(curr);
}
reverse(path.getAirports().begin(), path.getAirports().end());
path.setDistance(distance);
return path;
}

vector<FlightPath> Dataset::getBestFlightPaths(const vector<AirportRef> &srcs, const vector<AirportRef> &dests) const {
int minFlights = numeric_limits<int>::max();
vector<FlightPath> paths;

for (const AirportRef &src: srcs) {
for (const AirportRef &dest: dests) {
FlightPath path = getBestFlightPath(src, dest);
int flights = path.getFlights();

if (flights < minFlights) {
paths.clear();
paths.push_back(path);
minFlights = flights;
} else if (flights == minFlights) {
paths.push_back(path);
}
}
}

return paths;
}

double hav(double x) {
double sinVal = sin(x / 2);
return sinVal * sinVal;
}

double Dataset::calculateDistance(double lat1, double lon1, double lat2, double lon2) {
static const double EARTH_DIAMETER = 12742.0;
static const double DEG_TO_RAD_FACTOR = M_PI / 180.0;
double latRad1 = lat1 * DEG_TO_RAD_FACTOR, lonRad1 = lon1 * DEG_TO_RAD_FACTOR,
latRad2 = lat2 * DEG_TO_RAD_FACTOR, lonRad2 = lon2 * DEG_TO_RAD_FACTOR;

return EARTH_DIAMETER * asin(hav(latRad2 - latRad1) + cos(latRad1) * cos(latRad2) * hav(lonRad2 - lonRad1));
}
19 changes: 2 additions & 17 deletions src/Flight.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#include <cmath>
#include <utility>
#include "Flight.h"

FlightInfo::FlightInfo(AirlineRef airline, const AirportInfo& src, const AirportInfo& dest)
: airline_(std::move(airline)), distance_(calculateDistance(src, dest)) {}
FlightInfo::FlightInfo(AirlineRef airline, double distance)
: airline_(std::move(airline)), distance_(distance) {}

const AirlineRef &FlightInfo::getAirline() const {
return airline_;
Expand All @@ -12,17 +11,3 @@ const AirlineRef &FlightInfo::getAirline() const {
double FlightInfo::getDistance() const {
return distance_;
}

double hav(double x) {
double sinVal = sin(x / 2);
return sinVal * sinVal;
}

double FlightInfo::calculateDistance(const AirportInfo &src, const AirportInfo &dest) {
static const double EARTH_DIAMETER = 12742.0;
static const double DEG_TO_RAD_FACTOR = M_PI / 180.0;
double lat1 = src.getLatitude() * DEG_TO_RAD_FACTOR, lat2 = dest.getLatitude() * DEG_TO_RAD_FACTOR,
lon1 = src.getLongitude() * DEG_TO_RAD_FACTOR, lon2 = dest.getLongitude() * DEG_TO_RAD_FACTOR;

return EARTH_DIAMETER * asin(hav(lat2 - lat1) + cos(lat1) * cos(lat2) * hav(lon2 - lon1));
}
26 changes: 26 additions & 0 deletions src/FlightPath.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "FlightPath.h"

FlightPath::FlightPath(): airports_(), distance_(0.0) {}

FlightPath::FlightPath(const std::vector<AirportRef> &airports, double distance)
: airports_(airports), distance_(distance) {}

const std::vector<AirportRef> &FlightPath::getAirports() const {
return airports_;
}

std::vector<AirportRef> &FlightPath::getAirports() {
return airports_;
}

double FlightPath::getDistance() const {
return distance_;
}

void FlightPath::setDistance(double distance) {
distance_ = distance;
}

int FlightPath::getFlights() const {
return (int)airports_.size() - 1;
}
Loading