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

来源:互联网 发布:淘宝一元商品怎么赚钱 编辑:程序博客网 时间:2024/05/01 08:13

凸多边形最优分割是典型的动态规划问题

凸多边形最优剖分:给定凸多边形,以及定义在由多边形的边和弦上的权函数,使得该多边形三角剖分后所有三角形权值之和最小







思路:先将多边形三角剖分

2、三角剖分最优子结构性质

     若n+1边形{V0,V1……Vn}的最优三角剖分包含三角形V0VkVn(1<=k<=n)则T的权为三个部分权之和:

------三角形V0VkVn的权,

------多边形{V0,V1……Vk}的最优三角剖分权值

------多边形{Vk,Vk+1……Vn}的三角剖分权值

(为什么要选取三角形V0VkVn?因为在三角剖分后,必定含有一个三角形的两个顶点为V0,VnV0,Vn可以是多变形任意一条边的两个端点!)


如下图所示:

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

   3、递推关系:

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

      因此,可得递推关系式:

------当i=j时,只有多边形的一条边,所以不存在三角剖分,即t[i][j]=0;

------当i<j时,通过程序计算权值最小时的的K值,然后放进数组保存。(这是本程序核心算法)

------程序执行过程:(1)初试化:(以N+1边形每个顶点作为t[i][j]中的i值),

                                                          i=j时,t[i][j]=0;

                                  (2)先将多边形分割成较小的多边形:使 j=I+1,即为三角形,(以N+1边形每个顶点作为t[i][j]中的i值):计算出每一个三角形的最优三角剖分值t[i][j]   (即三角形本身权值),存放在数组t[i][j]中;

                                     使j=i+2,即为四边形,计算最优三角剖分值,存放在数组t[i][j]中

                                      具体算法在下面:

                                       使j=i+3.......

                                       使j=i+4.......

                                     。。。。。。

                                (3)当j=i+n-1时,即为n+1边形,计算出最优三角剖分值t[i][j],即为最终结果。

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

------该算法所用递推关系:每一次被分割的小多边形的最优三角剖分都用到上一次最优剖分的计算结果,产生递推关系!

比如:计算五边形{Vi,Vi+1,Vi+2,Vi+3,Vj}的t[i][j]值时,需要用到四边形{Vi,Vi+1,Vi+2,Vj}的t[i][j]值,计算四边形{Vi,Vi+1,Vi+2,Vj}的t[i][j]值时,需要用到三角形{Vi,Vi+1,Vj}的三角剖分值,即其本身权值!

     

<pre name="code" class="cpp">#include<iostream>using namespace std;const int N=7; 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}};   /*存放多变形每一个点到其它点的权值,每个点到自己的权值为0,第i组第j个数表示第i个点到第j个点的权值,如{2,0,1,5,2,3}这组中5表示第2个顶点到第4个顶点的权值*/int Min(int n,int **t);/*n表示多边形边数,t用来存放最优三角剖分值*/int Weight(int a,int b,int c);/*该函数用来计算三角形的权值*/int main(){    int **t=new int *[N];    for(int i=0;i<N;i++)    {        t[i]=new int[N];    }    cout<<Min(N-2,t)<<endl;    return 0;}int Min(int n,int **t){    int i;    for(i=0;i<=n;i++)    {        t[i][i]=0;    }    for(int r=2;r<=n;r++)/*n边形需要循环计算n-1次,上述算法执行过程的第二步*/    {        for(i=1;i<=n-r+1;i++) /*i为每次计算t[i][j]的前顶点*/        {            int j=i+r-1;      /*j为每次计算t[i][j]的后顶点*/            t[i][j]=t[i+1][j]+Weight(i-1,i,j);            for(int k=i+1;k<j;k++)            {                int u=t[i][k]+t[k+1][j]+Weight(i-1,k,j);                if(u<t[i][j])        //判断是否是最小值                    {                         t[i][j]=u;                    }            }        }    }    return t[1][n];}int Weight(int a,int b,int c){    return weight[a][b]+weight[b][c]+weight[a][c];}


                                             
0 0
原创粉丝点击