出现问题迭代 1 | 总损失: 6.72196 | 距离损失: 10.1859 | 面积损失: 0.288881
0x00007FFE5A118508 (torch_cpu.dll)处(位于 test.exe 中)引发的异常: 0xC000008E: Floating-point division by zero (参数: 0x0000000000000000, 0x0000000000001924)。
“test.exe”(Win32): 已加载“C:\Windows\System32\duser.dll”。
“test.exe”(Win32): 已加载“C:\Windows\System32\xmllite.dll”。
“test.exe”(Win32): 已加载“C:\Windows\System32\atlthunk.dll”。
“test.exe”(Win32): 已卸载“C:\Windows\System32\xmllite.dll”
0x00007FFF5CE8933A (KernelBase.dll)处(位于 test.exe 中)引发的异常: 0x8001010D: 因为应用程序正在发送一个输入同步呼叫,所以无法执行传出的呼叫。。
“test.exe”(Win32): 已加载“C:\Windows\System32\OneCoreCommonProxyStub.dll”。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: wil::ResultException,位于内存位置 0x000000EDA68FDF50 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: [rethrow],位于内存位置 0x0000000000000000 处。
线程 33260 已退出,返回值为 0 (0x0)。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: wil::ResultException,位于内存位置 0x000000EDA68FE2B0 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: [rethrow],位于内存位置 0x0000000000000000 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: wil::ResultException,位于内存位置 0x000000EDA68FE300 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: [rethrow],位于内存位置 0x0000000000000000 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: wil::ResultException,位于内存位置 0x000000EDA68FDF50 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: [rethrow],位于内存位置 0x0000000000000000 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: wil::ResultException,位于内存位置 0x000000EDA68FE2B0 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: [rethrow],位于内存位置 0x0000000000000000 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: wil::ResultException,位于内存位置 0x000000EDA68FE300 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: [rethrow],位于内存位置 0x0000000000000000 处。
线程 36532 已退出,返回值为 0 (0x0)。
线程 1208 已退出,返回值为 0 (0x0)。
线程 36320 已退出,返回值为 0 (0x0)。
线程 22984 已退出,返回值为 0 (0x0)。
线程 4384 已退出,返回值为 0 (0x0)。
线程 17576 已退出,返回值为 0 (0x0)。
线程 14288 已退出,返回值为 0 (0x0)。
线程 35492 已退出,返回值为 0 (0x0)。
线程 22860 已退出,返回值为 0 (0x0)。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: wil::ResultException,位于内存位置 0x000000EDA68FE330 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: [rethrow],位于内存位置 0x0000000000000000 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: wil::ResultException,位于内存位置 0x000000EDA68FE3A0 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: [rethrow],位于内存位置 0x0000000000000000 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: wil::ResultException,位于内存位置 0x000000EDA68FE330 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: [rethrow],位于内存位置 0x0000000000000000 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: wil::ResultException,位于内存位置 0x000000EDA68FE3A0 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: [rethrow],位于内存位置 0x0000000000000000 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: wil::ResultException,位于内存位置 0x000000EDA68FE330 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: [rethrow],位于内存位置 0x0000000000000000 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: wil::ResultException,位于内存位置 0x000000EDA68FE3A0 处。
0x00007FFF5CE8933A 处(位于 test.exe 中)引发的异常: Microsoft C++ 异常: [rethrow],位于内存位置 0x0000000000000000 处。
线程 30132 已退出,返回值为 0 (0x0)。
线程 27048 已退出,返回值为 0 (0x0)。
线程 27212 已退出,返回值为 0 (0x0)。
线程 33764 已退出,返回值为 0 (0x0)。
线程 35108 已退出,返回值为 0 (0x0)。
线程 12392 已退出,返回值为 0 (0x0)。
#define PARTICLESWARMMETHOD_EXPORTS // 定义导出宏
#include "particleSwarmMethod.h"
torch::Tensor distance_point_to_segment(const torch::Tensor& P, const torch::Tensor& A, const torch::Tensor& B)
{
auto AP = P - A;
auto AB = B - A;
auto ab_sq = AB.pow(2).sum();
if (ab_sq.item<float>() == 0)
{
return AP.norm(2, 1);
}
auto t = torch::mv(AP, AB.squeeze()) / ab_sq;
t = torch::clamp(t, 0.0, 1.0);
auto proj = A + t.unsqueeze(1) * AB;
return (P - proj).norm(2, 1);
}
std::vector<std::vector<float>> particle(const std::vector<float>& wy, const std::vector<float>& zh)
{
std::vector<std::vector<float>> particles;//六边形初始化
auto wymax = *std::max_element(wy.begin(), wy.end());
auto wymin = *std::min_element(wy.begin(), wy.end());
auto zhmax = *std::max_element(zh.begin(), zh.end());
auto zhmin = *std::min_element(zh.begin(), zh.end());
particles.push_back({ wymin, zhmax });
particles.push_back({ wymax, zhmax });
particles.push_back({ wymax, (zhmax - zhmin) * 0.5f + zhmin });
particles.push_back({ (wymax - wymin) * 0.5f + wymin, (zhmax - zhmin) * 0.5f + zhmin });
particles.push_back({ (wymax - wymin) * 0.5f + wymin, zhmin });
particles.push_back({ wymin, zhmin });
return particles;
}
// 应用约束
torch::Tensor apply_constraints(torch::Tensor vertices)
{
torch::NoGradGuard no_grad; // 临时禁用梯度计算
// 边界约束
vertices.data() = torch::clamp(vertices, -0.05, 1.02);
auto min_val = torch::tensor(0.2, vertices.options());
auto max_val = vertices.index({ 1, 0 }) * 1.1;
vertices.index_put_({ 2, 0 }, torch::clamp(vertices.index({ 2, 0 }), min_val, max_val));
vertices.index_put_({ 2, 1 }, torch::clamp(vertices.index({ 2, 1 }), 0.2, 1.02));
vertices.index_put_({ 3, 0 }, torch::clamp(vertices.index({ 3, 0 }),
vertices.index({ 4, 0 }),
vertices.index({ 2, 0 }) * 1.1));
vertices.index_put_({ 3, 1 }, torch::clamp(vertices.index({ 3, 1 }),
vertices.index({ 4, 1 }) * 1.1,
vertices.index({ 2, 1 })));
vertices.index_put_({ 4, 0 }, torch::clamp(vertices.index({ 4, 0 }),
vertices.index({ 5, 0 }) * 1.1,
vertices.index({ 3, 0 })));
vertices.index_put_({ 4, 1 }, torch::clamp(vertices.index({ 4, 1 }),
torch::nullopt,
vertices.index({ 5, 1 }) + 0.1));
return vertices;
}
// 计算损失函数
std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
calculate_gradient_descent_loss(const torch::Tensor& vertices,
const torch::Tensor& points,
const torch::Tensor& target_area,
float lambda1)
{
// 计算六边形面积
auto shifted_vertices = torch::roll(vertices, -1, 0);
auto x = vertices.index({ torch::indexing::Slice(), 0 });
auto y = vertices.index({ torch::indexing::Slice(), 1 });
auto x_shifted = shifted_vertices.index({ torch::indexing::Slice(), 0 });
auto y_shifted = shifted_vertices.index({ torch::indexing::Slice(), 1 });
auto area = 0.5 * torch::abs(torch::sum(x * y_shifted - y * x_shifted));
// 计算所有边到数据点的距离
std::vector<std::pair<int, int>> edges;
for (int i = 0; i < 6; ++i)
{
edges.emplace_back(i, (i + 1) % 6); // 添加边 (i, (i+1)%6)
}
std::vector<torch::Tensor> dists;
for (const auto& edge : edges) {
auto A = vertices[edge.first].unsqueeze(0); // [1, 2]
auto B = vertices[edge.second].unsqueeze(0); // [1, 2]
auto dist = distance_point_to_segment(points, A, B);
dists.push_back(dist);
}
auto dist_matrix = torch::stack(dists, 1);
auto min_dists = std::get<0>(torch::min(dist_matrix, 1));
auto distance_loss = torch::sum(min_dists);
// 计算面积损失
auto area_loss = torch::abs(area - target_area);
// 总损失
auto total_loss = (1 - lambda1) * area_loss + lambda1 * distance_loss;
return { total_loss, distance_loss, area_loss };
}
extern "C" PARTICLESWARMMETHOD_API int* opening_closing_point_recognition(
const float* wy, int wySize,
const float* zh, int zhSize,
int iterations,
bool print1,
float lambda1,
int* resultSize
) {
// 输出所有输入信息
std::cout << "Opening_closing_point_recognition 函数的输入信息:" << std::endl;
std::cout << "wy 数组内容:";
for (int i = 0; i < wySize; ++i) {
std::cout << wy[i];
if (i < wySize - 1) {
std::cout << ", ";
}
}
std::cout << std::endl;
std::cout << "wy 数组大小: " << wySize << std::endl;
std::cout << "zh 数组内容:";
for (int i = 0; i < zhSize; ++i) {
std::cout << zh[i];
if (i < zhSize - 1) {
std::cout << ", ";
}
}
std::cout << std::endl;
std::cout << "zh 数组大小: " << zhSize << std::endl;
std::cout << "迭代次数: " << iterations << std::endl;
std::cout << "是否打印信息: " << (print1 ? "是" : "否") << std::endl;
std::cout << "权重系数 lambda1: " << lambda1 << std::endl;
// 数据归一化
auto wmin = *std::min_element(wy, wy + wySize);
auto wmax = *std::max_element(wy, wy + wySize);
auto zmin = *std::min_element(zh, zh + zhSize);
auto zmax = *std::max_element(zh, zh + zhSize);
std::vector<float> wy_nored(wySize), zh_nored(zhSize);
for (int i = 0; i < wySize; ++i) {
wy_nored[i] = (wy[i] - wmin) / (wmax - wmin);
}
for (int i = 0; i < zhSize; ++i) {
zh_nored[i] = (zh[i] - zmin) / (zmax - zmin);
}
std::vector<float> low_before = { *std::min_element(wy_nored.begin(), wy_nored.end()) - 0.1f,
*std::min_element(zh_nored.begin(), zh_nored.end()) - 0.1f };
std::vector<float> up_before = { *std::max_element(wy_nored.begin(), wy_nored.end()) * 1.1f,
*std::max_element(zh_nored.begin(), zh_nored.end()) * 1.1f };
std::vector<float> low, up;
for (int i = 0; i < 6; ++i)
{
low.insert(low.end(), low_before.begin(), low_before.end());
up.insert(up.end(), up_before.begin(), up_before.end());
}
// 初始化六边形
std::vector<std::vector<float>> polygon = particle(wy_nored, zh_nored);
// 将 polygon (vector<vector<float>>) 转换为 Tensor
std::vector<float> flattened;
for (const auto& point : polygon)
{
flattened.insert(flattened.end(), point.begin(), point.end());
}
torch::Tensor vertices = torch::tensor(flattened, torch::dtype(torch::kFloat32))
.view({ -1, 2 })
.requires_grad_(true);
// 创建优化器
auto optimizer = torch::optim::AdamW({ vertices }, torch::optim::AdamWOptions(0.008));
//auto scheduler = torch::optim::LRScheduler(optimizer, 500);
// 准备数据点
std::vector<torch::Tensor> point_tensors;
for (size_t i = 0; i < wy_nored.size(); ++i)
{
point_tensors.push_back(torch::tensor({ wy_nored[i], zh_nored[i] }));
}
auto points = torch::stack(point_tensors);
std::cout << "vertices 张量的值:" << std::endl;
auto vertices_accessor = points.accessor<float, 2>();
for (int i = 0; i < points.size(0); ++i) {
for (int j = 0; j < points.size(1); ++j) {
std::cout << vertices_accessor[i][j] << " ";
}
std::cout << std::endl;
}
// 计算目标面积
auto shifted_points = torch::roll(points, -1, 0);
auto target_area = 0.5 * torch::abs(torch::sum(
points.index({ torch::indexing::Slice(), 0 }) * shifted_points.index({ torch::indexing::Slice(), 1 }) -
points.index({ torch::indexing::Slice(), 1 }) * shifted_points.index({ torch::indexing::Slice(), 0 })));
// 优化循环
for (int k = 0; k < iterations; ++k) {
optimizer.zero_grad();
auto loss = calculate_gradient_descent_loss(vertices, points, target_area, lambda1);
//[total_loss, distance_loss, area_loss]
torch::Tensor total_loss = std::get<0>(loss); // 第一个元素
torch::Tensor distance_loss = std::get<1>(loss); // 第二个元素
torch::Tensor area_loss = std::get<2>(loss); // 第三个元素
// 输出损失信息
std::cout << "迭代 " << k + 1
<< " | 总损失: " << total_loss.item<float>()
<< " | 距离损失: " << distance_loss.item<float>()
<< " | 面积损失: " << area_loss.item<float>() << std::endl;
try
{
total_loss.backward();
}
catch (const c10::Error& e) {
std::cerr << "Caught c10::Error: " << e.what() << std::endl;
}
catch (const std::exception& e) {
std::cerr << "Caught std::exception: " << e.what() << std::endl;
}
vertices = apply_constraints(vertices);
optimizer.step();
/*
// 打印信息
std::cout << "迭代次数 " << k + 1
<< ", 面积损失: " << area_loss.item<float>()
<< ", 距离损失: " << distance_loss.item<float>()
<< ", 总损失: " << total_loss.item<float>() << std::endl;
*/
}
// 找到最近点
std::vector<int> vertex_indices = { 0, 1, 4, 5 };
std::vector<std::vector<float>> closest_points;
for (int idx : vertex_indices) {
auto vertex = vertices.index({ idx }).unsqueeze(0);
auto distances = torch::norm(points - vertex, 2, 1);
auto closest_idx = torch::argmin(distances).item<int>();
auto closest_point = points.index({ closest_idx });
closest_points.push_back({
closest_point.index({0}).item<float>(),
closest_point.index({1}).item<float>()
});
}
// 反归一化
std::vector<std::vector<float>> closest_points_original;
for (const auto& point : closest_points) {
closest_points_original.push_back({
point[0] * (wmax - wmin) + wmin,
point[1] * (zmax - zmin) + zmin
});
}
// 匹配原始数据点索引
std::vector<int> matched_indices;
for (const auto& point : closest_points_original) {
for (int i = 0; i < wySize; i++) {
if (round(point[0] * 100.0f) / 100.0f == round(wy[i] * 100.0f) / 100.0f &&
round(point[1] * 100.0f) / 100.0f == round(zh[i] * 100.0f) / 100.0f) {
matched_indices.push_back(i);
break;
}
}
}
// 打印结果
if (print1) {
std::cout << "反归一化后的最近点坐标:" << std::endl;
for (size_t i = 0; i < closest_points_original.size(); ++i) {
std::cout << "顶点 " << vertex_indices[i] << " 最近点: ["
<< closest_points_original[i][0] << ", "
<< closest_points_original[i][1] << "]" << std::endl;
}
}
*resultSize = static_cast<int>(matched_indices.size());
// 动态分配结果数组
int* output = new int[matched_indices.size()];
std::copy(matched_indices.begin(), matched_indices.end(), output);
return output;
}
extern "C" PARTICLESWARMMETHOD_API void free_int_array(int* arr) {
delete[] arr;
}