You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Conception/任务规划.h

125 lines
3.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
// 坐标类
class Point {
public:
double x, y;
Point(double nx, double ny) : x(nx), y(ny) {}
};
// 图类
class Graph {
public:
Graph(vector<Point> points) {
for (int i = 0; i < points.size(); i++) {
vector<double> row;
for (int j = 0; j < points.size(); j++) {
if (i == j) {
row.push_back(0);
} else {
double dis = sqrt(pow(points[i].x - points[j].x, 2) + pow(points[i].y - points[j].y, 2));
row.push_back(dis);
}
}
matrix.push_back(row);
}
}
// Dijkstra算法求解最短路径网上嫖的
vector<Point> get_shortest_path(int start_index, int end_index) {
int node_num = matrix.size();
vector<bool> visited(node_num, false);
vector<int> prev(node_num, -1);
vector<double> dist(node_num, INFINITY);
dist[start_index] = 0;
// Dijkstra算法
for (int i = 0; i < node_num; i++) {
int u = -1;
double min_dist = INFINITY;
// 找到未访问过的距离最小的节点u
for (int j = 0; j < node_num; j++) {
if (!visited[j] && dist[j] < min_dist) {
u = j;
min_dist = dist[j];
}
}
if (u == -1) break;
visited[u] = true;
// 更新u的邻接节点v的距离和前驱
for (int v = 0; v < node_num; v++) {
if (!visited[v] && matrix[u][v] < INFINITY) {
double new_dist = dist[u] + matrix[u][v];
if (new_dist < dist[v]) {
dist[v] = new_dist;
prev[v] = u;
}
}
}
}
// 输出最短路径
vector<Point> path;
int u = end_index;
while (prev[u] != -1) {
path.push_back(points[u]);
u = prev[u];
}
reverse(path.begin(), path.end());
return path;
}
private:
vector<vector<double>> matrix; // 邻接矩阵,用来存放
vector<Point> points; // 顶点坐标列表
const double INFINITY = std::numeric_limits<double>::infinity(); // 无穷大
};
// 顶点序列类
class VertexSequence {
public:
// 构造函数
VertexSequence(vector<Point> points, Graph graph) {
this->points = points;
this->graph = graph;
start_index = 0; // 初始起点为第一个点
end_index = -1; // 结尾没有定义
sequence = graph.get_shortest_path(start_index, end_index); // 计算最短路径
}
// 重新排序方法
void sort(Point current_point) {
// 计算起点到各顶点的距离
vector<double> distances;
for (int i = 0; i < sequence.size(); i++) {
double dis = sqrt(pow(current_point.x - sequence[i].x, 2) + pow(current_point.y - sequence[i].y, 2));
distances.push_back(dis);
}
// 对顶点序列进行重新排序
sort(sequence.begin(), sequence.end(), [&distances](const Point& lhs, const Point& rhs) {
int index_lhs = &lhs - &distances[0];
int index_rhs = &rhs - &distances[0];
return distances[index_lhs] < distances[index_rhs];
});
}
Point pop() {
Point next_point = sequence.front();
sequence.erase(sequence.begin());
return next_point;
}
private:
vector<Point> points; // 顶点坐标
Graph graph; // 连通图
int start_index; // 起点
int end_index; // 结尾
vector<Point> sequence; // 顶点序列
};