当前位置:   article > 正文

动态规划之凸多边形最优三角剖分问题_已知下图,采用动态规划法求解以下凸多边形的最优三角剖分。其中,m[i][j]记录子问

已知下图,采用动态规划法求解以下凸多边形的最优三角剖分。其中,m[i][j]记录子问

【三角剖分】

三角剖分(Triangulation)也叫做三角化,或者分格化,就是对给定的平面点集,生成三角形集合的过程,即将复杂的多边形剖分成多个三角。

考虑平面点集P={ P1...Pn },我们希望得到三角形集合T=在{ t1...tm },满足:

a)所有三角形的端点恰好构成集合P。

b)任意两个三角形的边不相交(要么重合,要么没有交点)。

c)所有三角形的合集构成P的凸包。

【题目】

使用动态规划算法解凸多边形最优三角剖分问题,具体来说就是,依据递归式,按照顺序求得子问题,使得该三角剖分中诸三角形上权之和为最小。

[输入:] 在屏幕上输入凸多边形顶点个数和顶点坐标。按逆时针顺序输入顶点坐标。

[输出:]  最优三角剖分后的三角形顶点。

【问题分析】

【最优子结构性质】

凸多边形的最优三角剖分问题有最优子结构性质

若凸(n+1)边形P=<v0 ,v1 ,… ,vn>的一个最优三角剖分T包含三角形v0 vk vn ,1≤k≤n-1,则T的权为3个部分权的和,即三角形v0 vk vn的权,子多边形<v0 ,v1 ,… ,vk>的权和<vk ,vk+1 ,… ,vn>的权之和。由T所确定的这两个子多边形的三角剖分也是最优的,因为若有<v0 ,v1 ,… ,vk>或<vk ,vk+1 ,… ,vn>的更小权的三角剖分,将会导致T不是最优三角剖分的矛盾。

【最优三角剖分的递归结构】

定义t[i,j],1≤i<j≤n,为凸子多边形<vi-1 ,vi ,… ,vj>的最优三角剖分所对应的权值,即最优值。
设退化的多边形<Vi-1 ,vi>权值为0,那么凸(n+1)边形对应的权的最优值为t[1,n]。
t[i,j]的值可以利用最优子结构性质递归地计算。由于退化的2顶点多边形的权值为0,所以t[i,i]=0,i=1,2,…,n 。当j-i≥1时,子多边形<vi-1 ,vi ,… ,vj>至少有3个顶点。

由最优子结构性质,t[i,j]的值应为t[i,k]的值加上t[k+1,j]的值,再加上vi-1 vk vj的权值,并在i≤k≤j-1的范围内取最小。由此,t[i,j]可递归地定义为:

【计算最优值】

计算凸(n+1)边形P=<v0 ,v1 ,… ,vn>的三角剖分最优权值的动态规划算法,输入是凸多边形P=<v0 ,v1 ,… ,vn>的权函数ω,输出是最优值t[i,j]和使得t[i,k]+t[k+1,j]+ω(△vi-1vkvj)达到最优的位置(k=)s[i,j],1≤i≤j≤n 。

【构造最优三角剖分】

对于任意的1≤i≤j≤n ,上述算法在计算每一个子多边形<vi-1 ,vi ,… ,vj>的最优三角剖分所对应的权值t[i,j]的同时,还在s[i,j]中记录了此最优三角剖分中与边(或弦)vi-1vj构成的三角形的第三个顶点的位置。

因此,利用最优子结构性质并借助于s[i,j],1≤i≤j≤n ,凸(n+l)边形P=<v0 ,v1 ,… ,vn>的最优三角剖分可容易地在Ο(n)时间内构造出来

【C++代码实现】

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N = 7; //凸多边形边数+1
  4. int weight[][N] = {{0,2,2,3,1,4},{2,0,1,5,2,3},{2,1,0,2,1,4},{3,5,2,0,6,2},{1,2,1,6,0,1},{4,3,4,2,1,0}};//凸多边形的权
  5. int MinWeightTriangulation(int n, int **t, int **s);//此多边形的最优三角剖分值
  6. void Traceback(int i, int j, int **s); //构造最优解
  7. int Weight(int a, int b, int c); //权函数
  8. int main()
  9. {
  10. int **s = new int *[N];
  11. int **t = new int *[N];
  12. for(int i=0; i<N; i++)
  13. {
  14. s[i] = new int[N];
  15. t[i] = new int[N];
  16. }
  17. cout<<"此多边形的最有三角剖分值为:"<<MinWeightTriangulation(N-1, t, s)<<endl;
  18. cout<<"最优三角剖分结构为:"<<endl;
  19. Traceback(1, 5, s); //s[i][j]记录了Vi-1和Vj构成三角形的第三个顶点的位置
  20. system("pause");
  21. return 0;
  22. }
  23. int MinWeightTriangulation(int n, int **t, int **s)
  24. {
  25. for(int i=1; i<=n; ++i) t[i][i] = 0;
  26. for(int r=2; r<=n; ++r) //r表示凸子多边形的顶点数
  27. for(int i=1; i<=n-r+1; ++i)
  28. {
  29. int j = i+r-1;
  30. t[i][j] = t[i+1][j] + Weight(i-1, i, j);
  31. s[i][j] = i;
  32. for(int k=i+1; k<i+r-1; k++)
  33. {
  34. int u = t[i][k] + t[k+1][j] + Weight(i-1, k, j);
  35. if(u<t[i][j])
  36. {
  37. t[i][j] = u;
  38. s[i][j] = k;
  39. }
  40. }
  41. }
  42. return t[1][N-2];
  43. }
  44. void Traceback(int i, int j, int **s)
  45. {
  46. if(i==j) return;
  47. Traceback(i, s[i][j], s);
  48. Traceback(s[i][j]+1, j, s);
  49. cout<<"三角剖分顶点:V"<<i-1<<",V"<<j<<",V"<<s[i][j]<<endl;
  50. }
  51. int Weight(int a, int b, int c)
  52. {
  53. return weight[a][b] + weight[b][c] + weight[a][c];
  54. }

运行截图:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/670581
推荐阅读
相关标签
  

闽ICP备14008679号