动态规划---凸多边形的最优三角剖分问题

来源:互联网 发布:中国女人崇洋媚外 知乎 编辑:程序博客网 时间:2024/05/01 19:49

 1、问题相关定义:

     (1)凸多边形的三角剖分将凸多边形分割成互不相交的三角形的弦的集合T。

    (2)最优剖分给定凸多边形P,以及定义在由多边形的边和弦组成的三角形上的权函数w。要求确定该凸多边形的三角剖分,使得该三角剖分中诸三角形上权之和为最小。

     凸多边形三角剖分如下图所示:

          2、最优子结构性质

     若凸(n+1)边形P={V0,V1……Vn}的最优三角剖分T包含三角形V0VkVn,1<=k<=n-1,则T的权为三个部分权之和:三角形V0VkVn的权,多边形{V0,V1……Vk}的权和多边形{Vk,Vk+1……Vn}的权之和。如下图所示:

          可以断言,由T确定的这两个子多边形的三角剖分也是最优的。因为若有{V0,V1……Vk}和{V0,V1……Vk}更小权的三角剖分,将导致T不是最优三角剖分的矛盾。因此,凸多边形的三角剖分问题具有最优子结构性质。

3、递推关系:

     设t[i][j],1<=i<j<=n为凸多边形{Vi-1,Vi……Vj}的最优三角剖分所对应的权值函数值,即其最优值。最优剖分包含三角形Vi-1VkVj的权,子多边形{Vi-1,Vi……Vk}的权,子多边形{Vk,Vk+1……Vj}的权之和。

      因此,可得递推关系式:

     凸(n+1)边形P的最优权值为t[1][n]。

     

#include <stdio.h>#include <iostream>#include <fstream>#include <string.h>using namespace std;const int N = 7;//凸多边形边数+1,凸6边形{v0,,v1,...,v5}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}};//凸多边形的权int MinWeightTriangulation(int n,int **t,int **s);void Traceback(int i,int j,int **s);//构造最优解int Weight(int a,int b,int c);//权函数int main(){    int **s = new int *[N];    int **t = new int *[N];    for(int i=0;i<N;i++)    {        s[i] = new int[N];        t[i] = new int[N];    }    cout<<"此多边形的最优三角剖分值为:"<<MinWeightTriangulation(N-1-1,t,s)<<endl;    cout<<"最优三角剖分结构为:"<<endl;    Traceback(1,5,s); //s[i][j]记录了Vi-1和Vj构成三角形的第3个顶点的位置    return 0;}int MinWeightTriangulation(int n,int **t,int **s){    for(int i=1; i<=n; i++)    {        t[i][i] = 0;    }    for(int r=2; r<=n; r++) //r为当前计算的链长(子问题规模)    {        for(int i=1; i<=n-r+1; i++)//n-r+1为最后一个r链的前边界        {            int j = i+r-1;//计算前边界为r,链长为r的链的后边界            t[i][j] = t[i+1][j] + Weight(i-1,i,j);//将链ij划分为A(i) * ( A[i+1:j] )这里实际上就是k=i            s[i][j] = i;            for(int k=i+1; k<j; k++)            {                //将链ij划分为( A[i:k] )* (A[k+1:j])                int u = t[i][k] + t[k+1][j] + Weight(i-1,k,j);                if(u<t[i][j])                {                    t[i][j] = u;                    s[i][j] = k;                }            }        }    }    return t[1][N-2];}void Traceback(int i,int j,int **s){    if(i==j) return;    Traceback(i,s[i][j],s);    Traceback(s[i][j]+1,j,s);    cout<<"三角剖分顶点:V"<<i-1<<",V"<<j<<",V"<<s[i][j]<<endl;}int Weight(int a,int b,int c){     return weight[a][b] + weight[b][c] + weight[a][c];}




阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 重回洛杉矶陶良辰 洛杉矶房价 洛杉矶奥运会 决战洛杉矶 重返洛杉矶txt 洛杉矶英语 洛杉矶山火爆发 东北酱在洛杉矶 洛杉矶景点 北京到洛杉矶 洛杉矶酒店 洛杉矶租房子 洛杉矶游玩 洛杉矶一日游 洛杉矶图片 美国洛杉矶图片 洛杉矶旅游攻略 洛杉矶县 洛杉矶 旅游 旅游洛杉矶 洛杉矶旅游景点 洛杉矶一日游攻略 洛杉矶温度 洛杉矶气候 洛杉矶邮编 洛杉矶气温 洛杉矶房产价格 洛杉矶房产网 洛杉矶深度游 洛杉矶环球影城 洛杉矶旅游路线 洛杉矶亲子游 洛杉矶好莱坞 洛杉矶华人旅游 洛杉矶旅行社 去洛杉矶旅游攻略 洛杉矶地铁 洛杉矶周边 洛杉矶旅游跟团 洛杉矶 房价 洛杉矶公寓价格