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
155 changes: 155 additions & 0 deletions AStar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// // AStar.cpp
// #include "AStar.h"
// #include "Haversine.h"
// #include <unordered_map>
// #include <set>
// #include <cmath>

// std::vector<Property> aStarSearch(double startLat, double startLon, double targetPrice, const std::vector<Property>& properties) {
// std::priority_queue<Node, std::vector<Node>, std::greater<Node>> openSet;
// std::unordered_map<int, Node> allNodes; // Track nodes by ID for efficient access

// // Initialize the start node
// Property virtualStart = {0.0, startLat, startLon}; // Dummy price 0.0
// Node startNode = {0, 0.0, std::abs(properties[0].price - targetPrice), virtualStart, nullptr};
// openSet.push(startNode);
// allNodes[0] = startNode;

// // A set of closed nodes to avoid revisiting
// std::set<int> closedSet;

// Node bestGoalNode; // Store the best goal found
// bool goalFound = false;

// // A* Algorithm Loop
// while (!openSet.empty()) {
// Node current = openSet.top();
// openSet.pop();

// // // Check if the current node is a valid goal (closest to target price)
// // if (std::abs(current.property.price - targetPrice) < std::abs(bestGoalNode.property.price - targetPrice)) {
// // bestGoalNode = current;
// // }

// // If this node is closer to the target price, update the goal
// if (!goalFound || std::abs(current.property.price - targetPrice) < std::abs(bestGoalNode.property.price - targetPrice)) {
// bestGoalNode = current;
// goalFound = true;
// }

// closedSet.insert(current.id);

// // Iterate over neighbors
// for (size_t i = 0; i < properties.size(); ++i) {
// if (closedSet.count(i)) continue;

// double tentativeGCost = current.gCost + haversine(current.property.latitude, current.property.longitude, properties[i].latitude, properties[i].longitude);
// double hCost = std::abs(properties[i].price - targetPrice) + haversine(properties[i].latitude, properties[i].longitude, startLat, startLon);

// Node neighbor = {static_cast<int>(i), tentativeGCost, hCost, properties[i], &allNodes[current.id]};

// if (!allNodes.count(i) || tentativeGCost < allNodes[i].gCost) {
// openSet.push(neighbor);
// allNodes[i] = neighbor;
// }
// }
// }

// // Backtrace to retrieve the path
// std::vector<Property> path;
// while (bestGoalNode.parent != nullptr) {
// path.push_back(bestGoalNode.property);
// bestGoalNode = *bestGoalNode.parent;
// }

// path.push_back(virtualStart);
// std::reverse(path.begin(), path.end());
// return path;
// }


#include "AStar.h"
#include "Haversine.h"
#include <unordered_map>
#include <set>
#include <cmath>
#include <queue>
#include <algorithm>

std::vector<Property> aStarSearch(double startLat, double startLon, double targetPrice, const std::vector<Property>& properties) {
// Priority queue to store nodes to explore
std::priority_queue<Node, std::vector<Node>, std::greater<Node>> openSet;
std::unordered_map<int, Node> allNodes; // Map nodes by ID
std::set<int> closedSet; // To avoid revisiting nodes

// Step 1: Find the closest node to the virtual start
double minDistance = std::numeric_limits<double>::max();
int closestNodeIndex = -1;

for (size_t i = 0; i < properties.size(); ++i) {
double dist = haversine(startLat, startLon, properties[i].latitude, properties[i].longitude);
if (dist < minDistance) {
minDistance = dist;
closestNodeIndex = static_cast<int>(i);
}
}

if (closestNodeIndex == -1) {
return {}; // No valid nodes found
}

// Step 2: Add the closest node as the starting point
Property virtualStart = {0.0, startLat, startLon}; // Dummy price 0.0
Node startNode = {closestNodeIndex, minDistance,
std::abs(properties[closestNodeIndex].price - targetPrice),
properties[closestNodeIndex],
nullptr};
openSet.push(startNode);
allNodes[closestNodeIndex] = startNode;

Node bestGoalNode;
bool goalFound = false;

// Step 3: A* Search
while (!openSet.empty()) {
Node current = openSet.top();
openSet.pop();

// Update best goal node
if (!goalFound || std::abs(current.property.price - targetPrice) < std::abs(bestGoalNode.property.price - targetPrice)) {
bestGoalNode = current;
goalFound = true;
}

closedSet.insert(current.id);

// Expand neighbors
for (size_t i = 0; i < properties.size(); ++i) {
if (closedSet.count(i)) continue;

double tentativeGCost = current.gCost + haversine(current.property.latitude, current.property.longitude, properties[i].latitude, properties[i].longitude);
double hCost = std::abs(properties[i].price - targetPrice) + haversine(properties[i].latitude, properties[i].longitude, startLat, startLon);

Node neighbor = {static_cast<int>(i), tentativeGCost, hCost, properties[i], &allNodes[current.id]};

if (!allNodes.count(i) || tentativeGCost < allNodes[i].gCost) {
openSet.push(neighbor);
allNodes[i] = neighbor;
}
}
}

// Step 4: Reconstruct the path
std::vector<Property> path;
Node* currentNode = &bestGoalNode;

while (currentNode != nullptr) {
path.push_back(currentNode->property);
currentNode = currentNode->parent;
}

// Include the virtual start for completeness
path.push_back(virtualStart);
std::reverse(path.begin(), path.end());
return path;
}
19 changes: 19 additions & 0 deletions AStar.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// AStar.h
#pragma once
#include <vector>
#include <queue>
#include "Property.h"

struct Node {
int id;
double gCost; // Cost from start node to this node
double hCost; // Estimated cost from this node to end node (heuristic)
double fCost() const { return gCost + hCost; }
Property property;
Node* parent;

bool operator>(const Node& other) const { return fCost() > other.fCost(); }
};

// Function to perform A* search and return the shortest path
std::vector<Property> aStarSearch(double startLat, double startLon, double targetPrice, const std::vector<Property>& properties);
120 changes: 120 additions & 0 deletions PreprocessDataset.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <set>
#include <algorithm>

struct Property {
double price;
double latitude;
double longitude;
};

// Function to read the dataset from a CSV file
std::vector<Property> readCSV(const std::string& filename) {
std::vector<Property> properties;
std::ifstream file(filename);

if (!file.is_open()) {
std::cerr << "Error: Unable to open file " << filename << '\n';
return properties;
}

std::string line;
// Skip the header row
std::getline(file, line);

while (std::getline(file, line)) {
std::stringstream ss(line);
std::string emptyColumn, priceStr, latStr, lngStr;

// Read the columns, skipping the empty one
if (std::getline(ss, emptyColumn, ',') &&
std::getline(ss, priceStr, ',') &&
std::getline(ss, latStr, ',') &&
std::getline(ss, lngStr, ',')) {
Property property;
property.price = std::stod(priceStr);
property.latitude = std::stod(latStr);
property.longitude = std::stod(lngStr);
properties.push_back(property);
}
}

file.close();
return properties;
}

// Function to write the dataset to a new CSV file
void writeCSV(const std::string& filename, const std::vector<Property>& properties) {
std::ofstream file(filename);

if (!file.is_open()) {
std::cerr << "Error: Unable to open file " << filename << '\n';
return;
}

// Write the header row
file << "Price,Latitude,Longitude\n";

for (size_t i = 0; i < properties.size(); ++i) {
const Property& property = properties[i];
file << property.price << ',' << property.latitude << ',' << property.longitude << '\n';
}

file.close();
}

// Comparator function for sorting
bool compareByPrice(const Property& a, const Property& b) {
return a.price < b.price;
}

// Function to preprocess the dataset and ensure unique prices
void preprocessDataset(std::vector<Property>& properties) {
// Sort properties by price
std::sort(properties.begin(), properties.end(), compareByPrice);

// Use a set to track unique prices
std::set<double> uniquePrices;

for (size_t i = 0; i < properties.size(); ++i) {
double originalPrice = properties[i].price;
int k = 1; // Start quadratic probing

// Keep probing until a truly unique price is found
while (uniquePrices.count(properties[i].price) > 0) {
properties[i].price = originalPrice + 0.01 * k * k; // Adjust price
k++;
}

// Add the unique price to the set
uniquePrices.insert(properties[i].price);
}
}

int main() {
// Input and output file names
std::string inputFile = "/Users/hemduttrao/Downloads/DSA Dataset-main.csv";
std::string outputFile = "Processed_DSA_Dataset.csv";
// Read the dataset
std::vector<Property> properties = readCSV(inputFile);

if (properties.empty()) {
std::cerr << "Error: No data to process.\n";
return 1;
}

std::cout << "Dataset loaded. Processing " << properties.size() << " entries...\n";

// Preprocess the dataset
preprocessDataset(properties);

// Write the processed dataset
writeCSV(outputFile, properties);

std::cout << "Processed dataset saved to " << outputFile << ".\n";

return 0;
}
Loading