算法重拾之路——凸多边形最优三角剖分

***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************

第二章:动态规划

>凸多边形最优三角剖分<

算法描述:

? 多边形: 平面上一条分段线性闭曲线。即 一系列首尾相接的直线段所组成的。

? 通常用多边形顶点的逆时针序列表示 凸多边形,即 P = { v0,v1,...,vn-1 } 表示具有n条边,v0,v1,...,vn,其中,约定 v0 = vn。

? 若 vi与vj 是多边形上不相邻的两个顶点,则线段vivj称为多边形的一条弦。且弦vivj将多边形分割成两个不同的三角剖分。

? 凸多边形最优三角剖分问题:给定凸多边形 P
= { v0,v1,...,vn-1 },以及定义在由凸多边形的边和弦组成的三角形上的权函数w。要求确定该凸多边形的三角剖分,使得该三角剖分所对应的权,即三角剖分中诸三角形上权之和为最小。

算法分析:

? 定义三角形上各种各样的权函数w。例如:w(vi,vj,vk)= |vivj| + |vjvk| + |vkvi|,其中,|vivj|是点vi到vj的欧氏距离(定义可看最下面的注解①)。相应于此权函数的最优三角剖分即为最小弦长三角剖分。

? 最优子结构性质: 若凸(n+1)边型
P = { v0,v1,...,vn-1 } 的最优三角剖分T包含三角形 v0vkvn,1≤k≤n-1,则T的权为三个部分权的和:三角形v0vkvn的权,子多边形{ v0,v1,...,vk } 和 { vk+1,vk+2,...,vn }的权之和。

可以断言,由T所确定的这两个子多边形的三角剖分也是最优的。因为若有
{ v0,v1,...,vk } 或 {vk,vk+1,...,vn }的更小权的三角剖分将导致T不是最优三角剖分的矛盾。

? 递归结构:设t[i][j],1≤i<j≤n为凸多边形{ vi-1,vi,...,vj } 的最优三角剖分所对应的权值函数值,即其最优值。最优剖分包含三角形vi-1vkvj的权,子多边形{vi-1,vi,...,vk}的权,子多边形{vk,vk+1,...,vj}的权之和。

因此,可得递归式为:

同矩阵连乘问题算法相似,此算法时间复杂度为O(n^3) 空间复杂度为O(n^2)

算法程序:

<span style="font-family:Comic Sans MS;font-size:14px;">//凸多边形的权
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 w(int a,int b,int c)
{
     return weight[a][b] + weight[b][c] + weight[a][c];
}
int MinWeightTriangulation( int n , int** t , int** s )
{
    // 初始化表格
    for( int i = 1 ; i <= n ; ++i )
        t[i][i] = 0;

    //r为当前计算的链长(子问题规模)
    for( int r = 2 ; r <= n ; ++r ) {
        //n-r+1为最后一个r链的前边界
        for( int i = 1 ; i <= n-r+1 ; ++i ) {
            //计算前边界为r,链长为r的链的后边界
            int j = i+r-1;

            //将链ij划分为A(i) * ( A[i+1:j] )这里实际上就是k=i
            t[i][j] = t[i+1][j] + w(i-1,i,j);
            s[i][j] = i;

            for( int k = i+1 ; k < i+r-1 ; ++k )    {
                //将链ij划分为( A[i:k] )* (A[k+1:j])
                int u = t[i][k]+t[k+1][j]+w(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;
}</span>

相关注解:

①欧氏距离:即 欧几里得度量(euclidean metric),是一个通常采用的距离定义,指在m维空间中,两个点的真实距离。比如在二维空间,点A(x1,y1) 和 点B(x2,y2)的欧氏距离为: d=sqrt( (x1-x2)^2 + (y1-y2)^2
); 扩展到三维空间即为: d=sqrt( (x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2 ) 。由此可继续推出m维空间的欧氏距离。

②图片来源:风仲达

***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************

时间: 2024-10-29 19:10:38

算法重拾之路——凸多边形最优三角剖分的相关文章

算法重拾之路——最大子段和

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 第二章:动态规划 >最大子段和< 算法描述: ?给定由n个整数(可能为负整数)组成的序列 a1,a2, ... , an ,求该序列形如  从ai 到 aj (i ≤ j)的子段和的最大值.当所有整数均为负整数时定义其最大值为0.根据这个定义,所求的最优值为:

算法重拾之路——最长公共子序列(LCS)

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 第二章:动态规划 最长公共子序列 算法描述: 一个给定序列的子序列是该序列中删去若干元素后得到的序列.确切的说,若给定序列 X={ x1,x2,...,xm },则另一序列 Z = { z1,z2, ... ,zk },是X的子序列是指存在一个严格递增下标序列

算法重拾之路——矩阵连乘问题

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 第二章:动态规划 矩阵连乘问题 算法描述: 给定n个矩阵{A1,A2,...,An},其中Ai 与 Ai+1 是可乘的,i=1,2, ... ,n-1.考察这n个矩阵的连乘积 A1A2, ... ,An. 由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同

算法重拾之路——动态规划基础

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 闲谈: 快到期末了,身为计算机专业大三学生,各种大作业缠身,到了大三,不再局限于考试了,学校更重视的是实践能力,所以各种大作业啊,并行计算.软件工程.软件综合设计 等等,有些东西,要求做的,在前两年,没有学过,于是又去学习,基本要把时间榨干了,这本书看了很多,就

算法重拾之路——快速排序

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 第一章:分治与递归 快速排序 算法描述: 同合并排序一样,就是对于一堆数据进行排序. 快排的原理就是,找一个标准,以这个标准为中心进行扩展.就像以前 做操 的时候,老师会说,以XXX为基准,成体操队形散开,这时,XXX左右的人分别就会向它看齐,并向外扩散.快排原

算法重拾之路——strassen矩阵乘法

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 第一章:分治与递归 STRASSEN矩阵乘法 算法描述: 矩阵乘法是线性代数中最常见的问题之一,它在数值计算中有广泛的应用.设A 和 B 是两个n × n矩阵,它们的乘积AB同样是一个n×n矩阵.A和B的乘积矩阵C 中的元素cij定义为: 按照这个定义来看,计算

算法重拾之路——棋盘覆盖

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 隶属于递归与分治 棋盘覆盖问题 问题描述: 在一个2^k × 2^k个方格组成的棋盘中,若恰有一个方格与其他方格不同,则该方格为一特殊方格,且称该棋盘为一特殊棋盘.在棋盘覆盖问题中,用下图所示四种' L '型骨牌覆盖一个给定的特殊棋盘中除特殊方格之外的所有方格,

算法重拾之路——合并排序

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 隶属于递归与分治 合并排序 问题描述:实现对n个元素的排序. 算法描述:不断将待排序的元素分成大小大致相同的两个子集合各自排序,最终将排序好的两个子集合合并.集合不断递归分下去,直至集合元素个数为1. 算法程序: <span style="font-fam

算法重拾之路——大数乘法

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 隶属于递归与分治 描述:设X与Y都是n位十进制的整数,现在要计算它们的乘积XY. 朴素法:用小学时候学过的方法,模拟乘,这样计算步骤太多,效率很低,时间复杂度达到了O(n^2)的地步. 分治法:将n为十进制整数分为两段每段长为n/2位,如下所示: 所以,X= A