Prim算法生成迷宫
初始化地图
function initMaze(r,c){
let row = new Array(2 * r + 1)
for(let i = 0; i < row.length; i++){
let column = new Array(2 * c + 1)
row[i] = column
for(let j = 0; j < column.length; j++){
row[i][j] = 1
}
}
for(let i = 0; i < r; i++){
for(let j = 0; j < c; j++){
row[2 * i + 1][2 * j + 1] = 0
}
}
console.log(row)
}
initMaze(3,3)
计算二维数组坐标位置
let arr = [
[0,0,0],
[0,0,0],
[0,0,0]
]
for(let i = 0; i < 9; i++){
let row = Math.floor(i / 3)
let column = i % 3
arr[row][column] = false
}
console.log(arr)
偏移量方向预制
let offset = [
{
x:-1,
y:0
},
{
x:1,
y:0
},
{
x:0,
y:-1
},
{
x:0,
y:1
}
]
let x = 0
let y = 0
for(let i = 0; i < offset.length; i++){
x = x + offset[i].x
y = y + offset[i].y
console.log(x,y)
}
随机数公式
1. 0-x之间的随机数:
Math.round(Math.random()*x);
2. x至y之间的随机数
Math.round(Math.random()*(y-x)+x);
3. 1-x之间的随机数:
Math.ceil(Math.random()*x);
Prim算法
const INF = Number.MAX_SAFE_INTEGER
function findMinKey(graph,key,visited){
let min = INF
let minIndex
//找到候选边中成本最小的节点
for(let v = 0; v < graph.length; v++){
if(!visited[v] && key[v] < min){
min = key[v]
minIndex = v
}
}
return minIndex
}
const prim = (graph) => {
const visited = [],
key = [],
parent = [];
let {length} = graph;
for(let v = 0; v < length; v++){
visited[v] = false
key[v] = INF
}
//把到第一个顶点的权值初始化为0
key[0] = 0
parent[0] = -1
//根节点不需要比
for(let i = 0; i < length - 1; i++){
//找到成本最小边的顶点
let u = findMinKey(graph,key,visited)
//标记下该顶点已被访问
visited[u] = true;
//以及该顶点到对应其他顶点是不是成本最小的
//如果是那么就走到该顶点去
for(let v = 0; v < length; v++){
if(graph[u][v] && !visited[v] && graph[u][v] < key[v]) {
parent[v] = u
key[v] = graph[u][v]
}
}
}
return parent
}
const graph = [
[0,2,4,0,0,0],
[2,0,2,4,2,0],
[4,2,0,0,3,0],
[0,4,0,0,3,2],
[0,2,3,3,0,2],
[0,0,0,2,2,0]
]
const parent = prim(graph)
console.log('Edge Weight')
for (let i = 1; i < graph.length; i++) {
console.log(parent[i] + ' - ' + i + ' ' + graph[i][parent[i]]);
}
使用Prim算法生成迷宫
- 生成2 * k + 1的迷宫,1表示墙,0表示路
- 随机选一个顶点,在该顶点上下左右随机抽取一个位置,如果没有访问过而且没有越界就选这个点生成迷宫
- 重复第2步
function roadmap(r,c){
let map = []
let rLen = 2 * r + 1
let cLen = 2 * c + 1
for(let i = 0; i < rLen; i++){
map[i] = []
for(let j = 0; j < cLen; j++){
//生成0101的格式
if((i ^ (i - 1)) === 1 && (j ^ (j - 1)) === 1){
map[i][j] = 0
}else{
map[i][j] = 1
}
}
}
map[1][0] = 0;
map[2 * r - 1][2 * c] = 0;
return map
}
const MathUtil = {
randomInt(a = 0,b){
if(typeof b === 'undefined'){
return Math.floor(Math.random() * a)
} else {
return Math.floor(Math.random() * (b - a) + a)
}
}
}
function maze(map){
let row = map.length >> 1
let col = map[0].length >> 1
let size = row * col
let notAccessed = new Array(size).fill(0)
let accessed = []
let cur = MathUtil.randomInt(0,size)
let offsS = [-col,col,-1,1] //cur在notAccessed要走的偏移量
let offsR = [-1,1,0,0] //cur在map中row要走的偏移量
let offsC = [0,0,-1,1]//cur在map中col要走的偏移量
accessed.push(cur)
notAccessed[cur] = 1
while(accessed.length < size){
let tr = Math.floor(cur / row)
let tc = cur % col
let num = 0;
let pos = -1
//判断四周格子是不是可以走
while(num++ < 4){
let dir = MathUtil.randomInt(0,4)
nr = tr + offsR[dir]
nc = tc + offsC[dir]
if(nr >= 0 && nc >= 0 && nr < row && nc < col && notAccessed[cur + offsS[dir]] === 0){
pos = dir
break
}
}
if(pos < 0){
//堵死的情况
cur = accessed[MathUtil.randomInt(0,accessed.length)]
}else{
//可以走的情况
tr = 2 * tr + 1
tc = 2 * tc + 1
map[tr + offsR[pos]][tc + offsC[pos]] = 0
cur = cur + offsS[pos]
notAccessed[cur] = 1
accessed.push(cur)
}
}
return map
}
function geMaze(r,c){
return maze(roadmap(r,c))
}
Prim算法生成迷宫的更多相关文章
- C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)
1.Prim 算法 以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树. 2.Kruskal 算法 直接寻找最小权值的边来构建最小生成树. 比较: Kruskal 算法主要是针对边来展开,边数 ...
- 图解最小生成树 - 普里姆(Prim)算法
我们在图的定义中说过,带有权值的图就是网结构.一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边.所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接 ...
- 图的最小生成树prim算法模板
用prim算法构建最小生成树适合顶点数据较少而边较多的图(稠密图) prim算法生成连通图的最小生成树模板伪代码: G为图,一般为全局变量,数组d为顶点与集合s的最短距离 Prim(G, d[]){ ...
- 最小生成二叉树-prim算法
1.prim算法:一种计算生成最小生成树的方法,它的每一步都会为一棵生长中的树添加一条边. 2.时间复杂度:
- php生成迷宫和迷宫寻址算法实例
较之前的终于有所改善.生成迷宫的算法和寻址算法其实是一样.只是一个用了遍历一个用了递归.参考了网上的Mike Gold的算法. <?php //zairwolf z@cot8.com heade ...
- PHP树生成迷宫及A*自己主动寻路算法
PHP树生成迷宫及A*自己主动寻路算法 迷宫算法是採用树的深度遍历原理.这样生成的迷宫相当的细,并且死胡同数量相对较少! 随意两点之间都存在唯一的一条通路. 至于A*寻路算法是最大众化的一全自己主动寻 ...
- UWP开发:自动生成迷宫&自动寻路算法(3)
+ , + ];//0<=x<=12 0<=y<=24 private static Random Rd = new Random(); 首先声明mazeMap存储数据,声明了 ...
- 生成最小树prim算法
最小生成树prim算法实现 ‘ ’最小生成树,就是权值(两点间直线的值)之和的最小值. 首先,要用二维数组记录点和权值.如上图所示无向图: int G[6][6]; G[1] ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
随机推荐
- P2619 [国家集训队2]Tree I(最小生成树+二分)
P2619 [国家集训队2]Tree I 每次二分一个$x$,每条白边加上$x$,跑最小生成树 统计一下满足条件的最小值就好了. to me:注意二分不要写挂 #include<iostream ...
- 【JMeter4.0】一、JAVA环境-JDK1.10安装与配置
环境变量的作用: 它是操作系统用来指定运行环境的一些参数.比如临时文件夹位置和系统文件夹位置等.当你运行某些程序时,除了在当前文件夹中寻找外,还会到这些环境变量中去查找,比如“Path”就是一个变量, ...
- redis学习(二)
简单了解一下 1.build.gradle中添加 依赖 org.springframework.boot:spring-boot-starter-data-redis //定义依赖:声明项目中需要哪 ...
- NHibernet 事务 修改操作,事务没提交,数据库数据却同步(修改)了
Nhibernet 缓存 由于查询出来的数据和缓存关联,更新之后就算事务没执行提交操作,数据库依旧会更新,解决方法, 清空缓存,实例不和缓存关联,如下面标红代码 public bool UpdateT ...
- smbumount - 为普通用户卸载smb文件系统
总览 smbumount 装载点 描述 普通用户使用这个程序可以卸载smb文件系统.它在工作时会suid到root身份,并且向普通linux用户提供了对资源更多的控制能力.在suid方面,它拥有足够的 ...
- Linux学习笔记之文件与文件系统的压缩与打包
四.文件与文件系统的压缩与打包 用途: 传输时减少带宽 Linux系统常见的压缩命令 Compass(旧版压缩,并且在centOS中默认为不安装) gzip, zcat bzip2, bzcat zi ...
- 数据库_MHA群集搭建
MHA概念介绍,群集搭建与测试 一, MHA介绍 1.概念:MHA master high availability,由日本DeNA公司开发,解决mysql故障切换可以做到0-30秒,而且在故障切换过 ...
- ffmpeg音频文件转换之使用stdin/stdout或BytesIO对象输入输出
最近在搞小程序录音,然后使用百度接口做语音识别. 小程序目前仅支持mp3和aac编码格式.虽然百度接口提供的m4a格式支持能直接识别小程序的录音文件,但由于自己还有其他一系列需求(比如直接读取数据,根 ...
- Android学习电子书
- 罗技K380使用手册
Ipad最佳伴侣|码字神器|罗技K380|附使用指南 ———— 为了方便平时在家处理工作➕写小红书笔记,年初买了个Ipad2018 我以前买过一个罗技的K480,因为太重了不方便携带,于是又入了K38 ...