scala 回溯法解决迷宫问题

//回溯法(递归版本)
object MiGong extends App{
	import scala.collection.mutable.ArrayBuffer
    val migong = Array(
        Array(1,1,1,1,1,1,1,1,1,1),
        Array(1,0,0,1,1,0,0,1,0,1),
        Array(1,0,0,1,0,0,0,1,0,1),
        Array(1,0,0,0,0,1,1,0,0,1),
        Array(1,0,0,1,1,0,0,0,0,1), //Array(1,0,1,1,1,0,0,0,0,1), 
        Array(1,0,0,0,1,0,0,0,0,1),
        Array(1,0,1,0,0,0,1,0,0,1),
        Array(1,0,1,1,1,0,1,1,0,1),
        Array(1,1,0,0,0,0,0,0,0,1),
        Array(1,1,1,1,1,1,1,1,1,1))
	val direction = Map(0->(0,-1),1->(-1,0),2->(0,1),3->(1,0)) //左、上、右、下
	// var minpath = ArrayBuffer[(Int,Int)]()
	var minpath = ArrayBuffer[Array[(Int,Int)]]()
	val path = ArrayBuffer[(Int,Int)]((1->1))
	var minlength = Long.MaxValue
	var length = 1
	def search(xd:Int,yd:Int,xt:Int,yt:Int):Unit={
		if(xd == xt && yd == yt){
			// if(length < minlength){
			// 	minlength = length
			// 	minpath = path.clone() //可能有多条最短的路径
			// }
			if(length < minlength){
				minlength = length
				minpath = ArrayBuffer[Array[(Int,Int)]]()
			}
			if(length == minlength){
				minpath += path.toArray
			}
			return 
		}
		for(i <- 0.until(4)){
			val newxd = xd+direction(i)._1
			val newyd = yd+direction(i)._2
			if(migong(newxd)(newyd) == 0){
				migong(newxd)(newyd) = 1
				length += 1
				path += (newxd->newyd)
				search(newxd,newyd,xt,yt)
				migong(newxd)(newyd) = 0
				length -= 1
				path -= (newxd->newyd)
			}
		}
	}
	search(1,1,8,2)
	migong(1)(1) = 1
	println(minlength)
	// println(minpath.mkString)
	println(minpath.map(a => println(a.mkString)))
	println(minpath.size)
}

//回溯法(非递归版本)
object MiGong2 extends App{
	import scala.collection.mutable.Stack
	import scala.collection.mutable.ArrayBuffer
    val migong = Array(
        Array(1,1,1,1,1,1,1,1,1,1),
        Array(1,0,0,1,1,0,0,1,0,1),
        Array(1,0,0,1,0,0,0,1,0,1),
        Array(1,0,0,0,0,1,1,0,0,1),
        Array(1,0,0,1,1,0,0,0,0,1), //Array(1,0,1,1,1,0,0,0,0,1), 
        Array(1,0,0,0,1,0,0,0,0,1),
        Array(1,0,1,0,0,0,1,0,0,1),
        Array(1,0,1,1,1,0,1,1,0,1),
        Array(1,1,0,0,0,0,0,0,0,1),
        Array(1,1,1,1,1,1,1,1,1,1))
	val direction = Map(0->(0,-1),1->(-1,0),2->(0,1),3->(1,0)) //左、上、右、下
	val stack = new Stack[(Int,Int,Int)]()
	var minpath = ArrayBuffer[Array[(Int,Int)]]()
	var minlength = Long.MaxValue
	var length = 1
	stack.push((1,1,0)) //三元组:x,y,d
	migong(1)(1) = 1
	//起点:(1,1),终点:(8,2)
	while(!stack.isEmpty){
		val x = stack.top._1
		val y = stack.top._2
		var d = stack.top._3
		if(x == 8 && y == 2){
			if(stack.size < minlength){
				minlength = stack.size
				minpath = ArrayBuffer[Array[(Int,Int)]]()
			}
			if(stack.size == minlength){
				minpath += stack.reverse.toArray.map(a => (a._1,a._2))
			}
		}
		var tag = false
		while(d<4 && !tag){
			if(migong(x+direction(d)._1)(y+direction(d)._2) == 0) tag = true
			d += 1
		}
		if(tag){
			stack.pop
			stack.push((x,y,d))
			stack.push((x+direction(d-1)._1,y+direction(d-1)._2,0))
			migong(x+direction(d-1)._1)(y+direction(d-1)._2) = 1
		} else {
			stack.pop
			migong(x)(y) = 0
		}
	}
	println(minlength)
	println(minpath.map(a => println(a.mkString)))
	println(minpath.size)
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值