算法分析 | 动态规划 | 凸多边形的最优三角剖分问题

只谈情不闲聊 提交于 2020-02-08 01:21:44

学习自https://www.jianshu.com/p/b97b0bb78b6c

 

一.问题分析:

 

将凸多边形内部划分成若干三角形,每一条线都带权 

哪一种划法,让

三角形的权最小?

 

因其具有最优子结构:

所以,总问题的最优解=子问题的最优解+

一个三角形的权

举例来说:当程序运行到i=0,j=5,k=3时:

 

 

 

 

 

设: 求解的是多边形{V0,V1,........Vn-1}

bestWeight[ i ] [ j ] =m 表示它的一个子多边形{Vi , Vi+1 , ... , Vj-1 , Vj}的最优解=m  (所以最终解为bsetWeight[ 0 ][ n-1 ])

bestPoint[ i ] [ j ] = k  表示该子多边形出现最优解时,构成的三角形为{ Vi , Vk , Vj }.

 

当i==j时,子问题退化成了点 ; 当i+1=j时,子问题退化成了一条线.

此时要退出,并且bestWeight[ i ] [ j ] =0;bestPoint[ i ] [ j ] = -1

 

二.代码实现

const int N = 6;

vector<vector<int>> weight = {// 给出权函数。
        {0, 2, 3, 1, 5, 6},
        {2, 0, 3, 4, 8, 6},
        {3, 3, 0, 10, 13, 7},
        {1, 4, 10, 0, 12, 5},
        {5, 8, 13, 12, 0, 3},
        {6, 6, 7, 5, 3, 0} };

//记录最优权值
vector<int>tempWeight(N, 0);
vector<vector<int>>bestWeight(N, tempWeight); //bestWeight[i][j]=m表示多边形{Vi, ... , ... , ... , Vj}的最优解=m

//记录最优策略
vector<int>tempPoint(N,-1);
vector<vector<int>> bestPoint(N, tempPoint);// bestPoing[i][j]=k 表示 Vi、Vj 构成三角形第三个顶点 Vk 。

//计算三角权重之和
int getWeight(int i, int k, int j)
{
    return weight[i][k] + weight[i][j] + weight[k][j];
}

//自底而上的DP算法, (组合子问题的解->父问题的解)
int TriSplit(int n)
{
    //i==j时是点;  j = i + 1时是边,此时的bestWeight[i][j]=0
    //但无需赋值,数组已默认全为0

    for (int scale = 2; scale < n; scale++)//遍历2~N-1条边的多边形
    {
		for (int i = 0; i < N - scale; i++)//例如,边数=2时,(V0,V1,V2)~(V3,V4,V5)
		{
			int j = i + scale;  //多边形的Vj
			int k = i + 1;
			bestWeight[i][j] = bestWeight[i][k] + bestWeight[k][j] + getWeight(i, k, j);//记录第一个基准值
			bestPoint[i][j] = k;
			for (k = i + 2; k < j; k++)//( i < k < j )
			{
                int t = bestWeight[i][k] + bestWeight[k][j] + getWeight(i, k, j);
                if (t < bestWeight[i][j])
                {
                    bestWeight[i][j] = t;
                    bestPoint[i][j] = k;
                }
			}
		}
    }
    return bestWeight[0][N - 1];//返回整体{V0~VN-1}的最优解
}

void TSPrint(int i, int j)
{
    if (j == i + 1 || j == i)
    {
        return;
    }
    TSPrint(i, bestPoint[i][j]);
    cout << "V" << i << " -- V" << bestPoint[i][j] << " -- V" << j << " = " << getWeight(i,bestPoint[i][j],j)<<endl;
	TSPrint(bestPoint[i][j], j);
}

 

main()

cout << endl << "最优三角剖分的权值之和为:" << TriSplit(N) << endl << endl;
			cout << "剖分结果为:" << endl;
			TSPrint(0, N - 1);

 

三.几个疑惑 

1.当规模=2时,需求解多边形{V0,V1,V2} , {V1,V2,V3} , {V2,V3,V4} , {V3,V4,V5},实际上是六边形的4/6个角

但没有取{V4,V5,V0} , {V5,V0,V1}这剩下的2个角

2.当规模变大时也是一样.不能取余吗?

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!