#include "geo/private/math/triangulation.h" namespace ns { namespace geo { double weightCost(const vector& points, int i, int j, int k) { PointD p1 = points[i], p2 = points[j], p3 = points[k]; double weight = p1.distance(p2) + p2.distance(p3) + p3.distance(p1); return weight; } double minWeightTriangulation(const vector& points, const int i, const int j, std::vector>& vres) { if (j < i + 2) return 0.0; double result = basic::DOUBLE_MAX; for (int k = i + 1; k < j; k++) { double weight = minWeightTriangulation(points, i, k, vres) + minWeightTriangulation(points, k, j, vres) + weightCost(points, i, k, j); if (weight < result) { result = weight; std::vector indexV = {i, k, j}; vres.emplace_back(indexV); } } return result; } double mTCDP(const vector& points, int n) { // There must be at least 3 points to form a triangle if (n < 3) return 0; // table to store results of subproblems. table[i][j] stores cost of // triangulation of points from i to j. The entry table[0][n-1] stores // the final result. double table[n][n]; // Fill table using above recursive formula. Note that the table // is filled in diagonal fashion i.e., from diagonal elements to // table[0][n-1] which is the result. for (int gap = 0; gap < n; gap++) { for (int i = 0, j = gap; j < n; i++, j++) { if (j < i + 2) { table[i][j] = 0.0; } else { table[i][j] = basic::DOUBLE_MAX; for (int k = i + 1; k < j; k++) { double val = table[i][k] + table[k][j] + weightCost(points, i, j, k); if (table[i][j] > val) { table[i][j] = val; } } } } } return table[0][n - 1]; } double minWeightTriangulation(const vector& points, vector>& s) { int n = points.size(); if (n < 3) return 0.0; s.resize(n); for (int i = 0; i < n; i++) { s[i].resize(n); } double t[n][n]; // t[i][j]表示多边形{ViVkVj}的最优权值 for (int i = 0; i < n; i++) { t[i][i] = 0.; t[i][(i + 1) % n] = 0.; // t[i][i+1] =0 } for (int j = 2; j < n; j++) // 至少有三个点 { for (int i = 0; i < n - j; i++) { int k = i + j; int m = i + 1; t[i][k] = t[i][m] + t[m][k] + weightCost(points, i, m, k); s[i][k] = m; for (m = m + 1; m < k; m++) { int u = t[i][m] + t[m][k] + weightCost(points, i, m, j); if (u < t[i][k]) { t[i][k] = u; s[i][k] = m; } } } } return t[0][n - 1]; } vector> traceBack(const vector>& s, const int i, const int j, vector>& vres) { if (i == j || i + 1 == j) { return {}; } traceBack(s, i, s[i][j], vres); traceBack(s, s[i][j], j, vres); vector tempV = {i, s[i][j], j}; vres.emplace_back(tempV); return vres; } } // namespace geo } // namespace ns