动态规划法解决凸多边形最优三角剖问题

题目描述

凸多边形最优三角剖分问题和矩阵连乘问题极其相似,矩阵连乘问题明天我会在博客中介绍。
我们的目的是给定凸多边形P={v0,v1,…,vn-1},以定义在由凸多边形的边和弦组成的三角形上的权函数w,要求缺定该凸多边形的三角剖分,使得该三角剖分所对应的权,即三角剖分中诸三角形上权之和为最小。

题目分析

我们先聊一聊什么是凸多边形的三角剖分。
多边形是平面上一条分段线性的闭曲线。也就是说,多边形是由一系列首尾相接的直线段组成的。组成多边形的各直线段称为该多边形的边。连接多边形相继两条边的点称为多边形的顶点。若多边形的边除了连接顶点没有别的交点,我称其为一个简单多边形。
通常,用多边形的顶点的逆时针序列表示凸多边形,即P={vo,v1,v2,…,vn-1}表示具有n条边v0v1、v1v2、v2v3、…、vn-1vn的凸多边形。其中我们约定v0 = vn
若vi与vj是多边形上的不相邻的两个顶点,则线段vivj称为多边形的一条弦。弦vivj将多边形分割为两个多边形{vi,vi+1,…,vj}和{vj,vj+2,…,vn}.
多边形的三角剖分是指将多边形分割成互不相交的三角形的弦的集合T。
具体的三角剖分如图所示:
在这里插入图片描述
我们提前定义了我们的权值函数w,w(vivjvk)=|vivj|+|vivk|+|vjvk|。其中|vivj|表示vi到vj的欧氏距离,对应此权函数的最优三角剖分即为最小弦长三角剖分。
所以我们现在就是要求出最小剖分。
我们发现我们可以找到一个弦,将多边形分为两个多边形,然后分别去求其中的最小三角剖分,最后相加即可。
还有一种更加直观的表示方法——完全二叉树,又叫做表达式的语法树,如图所示
在这里插入图片描述
我们通过创建一颗完全二叉树的方式来表示子多边形的不同构建方法。
如图,完全二叉树的每一个叶子节点就是我们多边形的一条边,除此以外,多边形还有一条边是根节点,从这条边出发可以构建不同的子多边形。
所以n+1边形对应的完全二叉树将有n个叶节点。
每两个叶子节点可以和他们共同的父节点组成一个三角形,所以每一个完全二叉树就对应着一个多边形的三角剖分。那我们应该如何计算最小权值呢?
答案就是利用动态规划算法来解决。
在这里插入图片描述
我们会逐步扩大我们的子问题,直至子问题变成了全局问题,即子问题变成了对整个多边形求解,由于我们的至少需要三个点构成一个子问题,所以至少从t[1][2]卡开始求解,因为t[1][2]相当于将v0v1v2构成一个三角形,所以最小子问题规模应该为2.我们会不断增加我们的子问题规模。
因此我们在这层子规模大小的循环中,应该控制我们的子问题大小不发生改变。
我们还需要设置一个变量,用来指示中间划分的顶点,即k,我们会将整个多边形分为vi-1vi,…vk和vk,…,vj,再加上vi-1vkvj组成的三角形面积。就得到了我们最终的结果。

代码

#include <iostream>
using namespace std;
template<class Type>
void MinWeightTree(int n,Type **t,int **s)
{
    for(int i = 1;i <= n;i++)
    {
        t[i][i] = 0;
    }
    for(int r = 2;r <= n;r++)
    {
        for(int i = 1;i <= n - r + 1;i++)
        {
            int j = i + r - 1;//在整个循环中,j与i之间的差不会发生改变,一直为r
            //因为我们要维持子问题大小
            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++)
            {
                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;
                }
            }
        }
    }
}

数组s用来记录最优三角剖分中所有三角形的信息.s[i][j]记录了与vi-1和vj组成三角形的第三个顶点的位置。据此用O(n)时间就可以构造出最优三角剖分中的所有三角形了。

发布了60 篇原创文章 · 获赞 2 · 访问量 1065

猜你喜欢

转载自blog.csdn.net/weixin_44755413/article/details/105501677