凸多边形最优三角

前言:大三下算法课,自己看的凸多边形最优三角,最后上台讲解,和子涵苗子等一起的一段时间

1.相关概念

  凸多边形:一个简单多边形及其内部构成一个闭凸集时,则 称该简单多边形为一个凸多边形。
边:多边形相邻两点的连线
弦:多边形不相邻两点的连线

2.问题定义——凸多边形最优三角

给定凸多边形 P ,以及定义在由多边形的边和弦组成的三角形上的权函数 w 。要求确定该凸多边形的三角剖分,使得该三角剖分中所有三角形上权之和为最小。
(这个定义删减了些数学描述,只描述了问题)
相关性质:
   对一个n 边形划分三角问题中,有( 1 )弦: n-3                                                                                                                                2 三角形: n-2
权函数:
   权函数是一个自己定义的函数,也就是给凸多边形上的边和弦定义的代价,你可以将边的权定义为路径,时间,距离等,可以赋予你想要的实际意义,下面的程序中的权函数定义的是三角形的周长

3.与矩阵连乘的关系

    一个表达式的完全加括号方式相应与一颗完全二叉树,称为表达式的语法树

    凸n边形的三角划分对应一颗n-1个叶节点的语法树

    凸多边形的语法树,以边为节点

 矩阵连乘的最优计算问题是凸多边形最优三角划分问题的特殊情况

4.最优子结构性质

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

5.递归结构

 先来看矩阵连乘的递归结构

 矩阵连乘分为左半边+右半边+合并时间

而多边形分割的递归结构如下:

 可以看到这两个递归结构十分相似

6.代码实现

package 凸多边形最优三角分割;

import java.util.Scanner;

public class minWeightTriangulation {


    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("几边形?");

        int n = in.nextInt();
        int[][] n1 = new int[n][n];

        int[][] m = new int[n][n];
        int[][] s = new int[n][n];

        shuzu(n, n1);

        minWeightTriangulation(n-1, m, s, n1);

        System.out.println("最优值");
        shuchu(m);
        System.out.println("最优解");
        shuchu(s);
        System.out.println("划分点");
        Traceback(1,n-1,s);
    }


    //p为边数,n为存储权值的二维数组
    public static void shuzu(int p, int[][] n) {
        Scanner in = new Scanner(System.in);

        //初始化对角线
        for (int i = 0; i < p; i++)
            for (int i1 = 0; i1 < p; i1++)
                n[i][i1] = 0;

        for (int i = 0; i < p - 1; i++) {
            for (int l = i + 1; l < p; l++) {
                System.out.print(i + "点到" + l + "点,边的权值为:");
                n[i][l] = in.nextInt();
            }
        }

        System.out.println("\n测试输出\n");
        shuchu(n);
    }


    public static void shuchu(int[][] n) {


        /*测试输出*/
        for (int i = 0; i < n.length; i++) {
            for (int l = 0; l < n.length; l++) {

                System.out.printf("%-8d%s",n[i][l] , " ");
            }
            System.out.println();
        }
    }

    public static void minWeightTriangulation(int n, int[][] m, int[][] s, int[][] q) {
        for (int i = 1; i <= n; i++) {
            m[i][i] = 0;
        }

//        m最优值,s最优解  w权函数
        for (int r = 2; r <= n; r++) {//i与j的差值
            for (int i = 1; i <= n - r + 1; i++) {

                int j = i + r - 1;

                m[i][j] = m[i + 1][j] + w(i - 1, i, j, q);//k==i的情况
                s[i][j] = i;

                for (int k = i + 1; k < i + r - 1; k++) {

                    int u = m[i][k] + m[k + 1][j] + w(i - 1, k, j, q);

                    if (u < m[i][j]) {

                        m[i][j] = u;
                        s[i][j] = k;
                    }
                }
            }
        }
    }

    //    权值函数
    private static int w(int a, int b, int c, int[][] n) {

        int num = n[a][b] + n[b][c] + n[a][c];
        return num;

    }

    /*递归倒退函数*/
    public static void Traceback(int i, int j, int[][] s) {
        if (i == j) {
            return;
        }
        //子问题的K值
        Traceback(i, s[i][j], s);
        Traceback(s[i][j] + 1, j, s);

        System.out.println("剖分点:" + (i - 1) + " " + j + " " + s[i][j]);
    }

}

7.测试

输入边的权值,之后根据划分点写出分割的多边形,再去计算权值之和,看是否和程序输出的最优值相等

输入:

 输出:

 计算:

 测试通过!

8.复杂度分析

从程序中不难看出 时间复杂度为n*n   空间复杂度为n*n

9.其他

在研究这个算法时,发现一些很有趣但不确定是否有价值的点

在输出的最优解矩阵中,数值最大的那个数字,是Traceback(划分点输出函数)的递归层数,是建立语法树的深度,是划分三角形的个数

算法的用途:不规则房间监控问题    将房间区域划分为凸多边形,再用算法解决

ppt

贴不到这里,有需要联系我  扣扣1586470758

相关知识:

如何看懂程序输出的最优解矩阵(用最优解矩阵手动划分三角)

凸多边形最优三角剖分

动态规划_凸多边形最优三角剖分_哔哩哔哩

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值