IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 关于Unity最小生成树 -> 正文阅读

[游戏开发]关于Unity最小生成树

最近在恶补各种知识,而且在寻找工作的过程中,也见识了好多面试题,开阔了自己的眼界。下面我来给大家分享下,我在解决问题过程中,用到的一个最小生成树算法。(写这个的原因有2个方面,1.首先,搜索关于最小生成树的部分,我没找到太多和Unity相关的知识,大部分是原理,所以,写个博客,强化一下自己的记忆。2.也方便大部分和我一样,找资料但是找不到太相关的文章,而抓瞎的人。当然,自己对最小生成树的算法理解,也相对浅显。欢迎各位大神指正。)

? ? ? ? ?闲言少序,咱们直接进入正题。最近接到的需求是,在2D地图上,生成随机数个点,并通过最小路径,将他们连接起来,而且路径不能重复,不能相交。这就让我想到了算法里面的最小生成树的概念。至于具体概念,我就不在这里赘述了。具体的概念和相关代码可以查看这个文章。数据结构--最小生成树详解_William-CSDN博客_最小生成树

我主要讲讲我的实现方式吧。先贴代码,再逐行解释。

public struct tree
? ? {
? ? ? ? public int goIndex1;
? ? ? ? public int goIndex2;
? ? ? ? public float distance;
? ? }

List<tree> gosDistance = new List<tree>();
? ? ? ? //计算各特殊点之间的距离,利用最小生成树,连接各个房间
? ? ? ? for (int i = 0; i < speciGos.Length; i++)
? ? ? ? {
? ? ? ? ? ? for (int j = i + 1; j < speciGos.Length; j++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? float distance = Vector2.Distance(speciGos[i].transform.position, speciGos[j].transform.position);
? ? ? ? ? ? ? ? tree tree1;
? ? ? ? ? ? ? ? tree1.goIndex1 = i;
? ? ? ? ? ? ? ? tree1.goIndex2 = j;
? ? ? ? ? ? ? ? tree1.distance = distance;
? ? ? ? ? ? ? ? gosDistance.Add(tree1);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? List<int> connectP = new List<int>();
? ? ? ? int indexgos = 0;
? ? ? ? int n = sum;
? ? ? ? float[] mins = new float[gosDistance.Count - 1];
? ? ? ? for (int i = 0; i < gosDistance.Count; i++) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //先遍历所有距离,寻找最短距离连线
? ? ? ? {
? ? ? ? ? ? if (i == 0)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? mins[0] = 99999; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//初始化一个超级大的值
? ? ? ? ? ? }
? ? ? ? ? ? else if (mins[0] > gosDistance[i].distance)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? mins[0] = gosDistance[i].distance;
? ? ? ? ? ? ? ? indexgos = i;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? connectP.Add(gosDistance[indexgos].goIndex1);
? ? ? ? connectP.Add(gosDistance[indexgos].goIndex2); ? ? ? ? ? ? ? ? ? ? ? ? ? //将已找到的连接点放入数组中
? ? ? ? Debug.Log("当前连接最短的2个是物体" + gosDistance[indexgos].goIndex1 + "与物体" + gosDistance[indexgos].goIndex2);

首先我建立了一个List集合和一个tree的结构体,其中tree坐标记录的是2个物体的序号,以及他们之间的距离。然后,利用双重for循环,遍历物体之间的两两距离,放入gosDistance集合中。然后定义一个connectP的集合,用于存放已经找到的特殊点,另外sum就是所有需要遍历的特殊点总和。mins这个float数组是用来存储,每次2点间最短距离的具体数据的。然后我们初始化一个极大的距离值,将咱们所有比对的点之间的距离,进行比较,得出最短的具体。以及连接这两个点的物体序号,最后将最短的2个点的序号,存入connectP的集合,表示这两个点之间已经完成连接,并可以看作一个整体继续进行后续步骤了。(这是第一步,我们先连起来2个点,并保证他是所有特殊点两两连接中,最短的2个点。)

?n = n - 1;
? ? ? ? while (n > 1) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //第一次查到了2物体之间距离最短,然后根据这两物体与其他物体的连线距离,继续寻找距离最短的?? ?
? ? ? ? {
? ? ? ? ? ? for (int i = 0; i < gosDistance.Count; i++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (i == 0)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? mins[n] = 99999;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if (connectP.Contains(gosDistance[i].goIndex1) && !connectP.Contains(gosDistance[i].goIndex2)) ? ? ? ? ? ? ? ? ? ? ? ? ?//如果链表内包含第一个点,但不包含第二个点,则比较距离
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? if (mins[n] > gosDistance[i].distance)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? mins[n] = gosDistance[i].distance;
? ? ? ? ? ? ? ? ? ? ? ? indexgos = i;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else if (!connectP.Contains(gosDistance[i].goIndex1) && connectP.Contains(gosDistance[i].goIndex2))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? if (mins[n] > gosDistance[i].distance)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? mins[n] = gosDistance[i].distance;
? ? ? ? ? ? ? ? ? ? ? ? indexgos = i;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? if (!connectP.Contains(gosDistance[indexgos].goIndex1))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? connectP.Add(gosDistance[indexgos].goIndex1);
? ? ? ? ? ? }
? ? ? ? ? ? else if (!connectP.Contains(gosDistance[indexgos].goIndex2))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? connectP.Add(gosDistance[indexgos].goIndex2);
? ? ? ? ? ? }
? ? ? ? ? ? Debug.Log("当前距离:" + mins[n]);
? ? ? ? ? ? Debug.Log("当前连接点是" + gosDistance[indexgos].goIndex1 + "与" + gosDistance[indexgos].goIndex2);

下面我再解释后续继续查找的步骤代码,如何完成的。首先,n由于上面赋值了sum,是总物体数。我们已经进行了初次查找,所以总查找次数要减一。然后就是循环查找每2个点之间的距离,并把最短的那2个点放入connectP这个集合中,直至,查找了n-1次后,就可以找到连通所有点的最小生成树了。

Untiy随机生成2D地图

最后给大家看一个Demo就是使用情况。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-01-04 13:45:22  更:2022-01-04 13:45:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 18:45:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码