#include #include #include #include #include #include #include using namespace std; using namespace std; using namespace std::chrono; const int INF = numeric_limits::max(); struct Point { int x, y; }; struct Compare { bool operator()(const pair& a, const pair& b) { return a.first > b.first; } }; void generateObstacles(vector>& grid, int numObstacles) { random_device rd; mt19937 gen(rd()); int centerX = grid[0].size() / 2; int centerY = grid.size() / 2; int deviationX = grid[0].size() / 4; int deviationY = grid.size() / 4; normal_distribution<> xDist(centerX, deviationX); normal_distribution<> yDist(centerY, deviationY); uniform_int_distribution widthDist(1, 50); uniform_int_distribution heightDist(1, 100); for (int i = 0; i < numObstacles; i++) { int x = round(xDist(gen)); int y = round(yDist(gen)); int width = widthDist(gen); int height = heightDist(gen); // Ensure the obstacle doesn't go out of bounds if (x < 0) x = 0; if (y < 0) y = 0; if (x + width > grid[0].size()) { width = grid[0].size() - x; } if (y + height > grid.size()) { height = grid.size() - y; } for (int j = y; j < y + height; j++) { for (int k = x; k < x + width; k++) { grid[j][k] = 0; // Mark the cell as an obstacle } } } } int distanceTransform(vector>& grid) { int rows = grid.size(); int cols = grid[0].size(); vector> dt(rows, vector(cols, INF)); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (grid[i][j] == 0) { dt[i][j] = INF; } else { dt[i][j] = 1; } } } for (int _ = 0; _ < 2; _++) { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (grid[i][j] == 0) { continue; } int minDist = INF; if (i > 0) { minDist = min(minDist, dt[i-1][j]); } if (i < rows - 1) { minDist = min(minDist, dt[i+1][j]); } if (j > 0) { minDist = min(minDist, dt[i][j-1]); } if (j < cols - 1) { minDist = min(minDist, dt[i][j+1]); } dt[i][j] = 1 + minDist; } } } return 0; } std::vector> dijkstra(vector>& grid, Point start, vector& goalPoints) { std::vector> paths; for (int i = 0; i < goalPoints.size(); i++) { paths.emplace_back(); } int rows = grid.size(); int cols = grid[0].size(); vector> distances(rows, vector(cols, INF)); vector> previous(rows, vector(cols, {-1, -1})); distances[start.x][start.y] = 0; priority_queue, vector>, Compare> queue; queue.push({0, start}); while (!queue.empty()) { pair current = queue.top(); queue.pop(); int currentDist = current.first; Point currentPos = current.second; // Skip if the current distance is not up-to-date if (currentDist > distances[currentPos.x][currentPos.y]) { continue; } // Check all four cardinal directions for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { if (abs(dx) + abs(dy) == 1) { int x = currentPos.x + dx; int y = currentPos.y + dy; if (x < 0 || x >= rows || y < 0 || y >= cols || grid[x][y] == 0) { continue; // Skip out of bounds or obstacles } int newDist = currentDist + 1; // Uniform cost for moving if (newDist < distances[x][y]) { distances[x][y] = newDist; queue.push({newDist, {x, y}}); previous[x][y] = currentPos; } } } } } for (int i = 0; i < goalPoints.size(); i++) { int goalX = goalPoints[i].x; int goalY = goalPoints[i].y; int distance = distances[goalX][goalY]; if (distance == INF) { } else { for (Point at = goalPoints[i]; at.x != -1; at = previous[at.x][at.y]) { paths[i].emplace_back(at); } } } } int main() { const auto rec = rerun::RecordingStream("rerun_example_cpp"); rec.spawn().exit_on_failure(); int rows = 1000; int cols = 1000; vector> grid(rows, vector(cols, 1)); // Initialize grid with all 1s (no obstacles) int numObstacles = 200; generateObstacles(grid, numObstacles); Point start = {0, 0}; vector goalPoints = {{100, 100}, {800, 800}, {300, 300}}; vector goalScores = {11, 5, 8}; auto start_time = high_resolution_clock::now(); auto paths = dijkstra(grid, start, goalPoints); // Get ending timepoint auto stop = high_resolution_clock::now(); // Get duration. Substart timepoints to // get duration. To cast it to proper unit // use duration cast method auto duration = duration_cast(stop - start_time); cout << "Time taken by function: " << duration.count()/1000.0/1000.0 << " seconds" << endl; return 0; }