服务计算 作业2 (广搜BFS的TDD)

广搜TDD

实验描述

用go语言完成深搜Bfs的“走迷宫”算法。从迷宫的[1][1]点,走到迷宫右下角(迷宫大小可变,因此数组要用切片数组).

然后自己拟造简单数据,完成test和benchmark(测时间)

先写框架,用最少代码把测试框架跑起来

在bfs_test.go中

package iteration

import "testing"

func TestBfs(t *testing.T){
	var m [][]int;

	ans:=Bfs(m);
	excepted:=-1;

	if (ans!=excepted){
		t.Errorf("we want %d,but %d",excepted,ans);
	}
}

在bfs.go中

package iteration

func Bfs(m [][]int) int{
	return 5;
}

此时执行

go test XXX

结果:

--- FAIL: TestBfs (0.00s)
    bfs_test.go:12: we want -1,but 5
FAIL
FAIL    bo      0.500s
FAIL

C:\Users\ASUS>

编译正确,符合预期

框架已经打出来了,接下来是Bfs的代码,还有在test函数中地图的构建


代码的补全

知识预备:切片数组 (大佬请跳过)

go语言里数组大小也在函数传参的考虑范围里。
例如:

func Arratfunction(a [][]int){

}

a:=[3][3]int;
ArrayFunction(a);

就无法通过编译。

所以这里必须使用切片数组(相当与c语言里数组指针,动态分配数组)
切片数组的长度可动态分配,无论长度如何切片都可以传参。

这样迷宫大小就不是考虑问题了(可以用len()函数获得尺寸)

二维切片数组的分配例子

	var m [][]int=make([][]int,101);
	for i:=0;i<101;i++ {
		m[i]=make([]int,51);
	}

一个101*51的二维切片数组。

我不喜欢0,所以都分配多一点,呜呜呜呜


首先补全Bfs函数

深搜在此不做解释

在bfs.go中:

package bfs


import "fmt"

type point struct {
	x int;
	y int;
}

func Bfs(m [][]int) int {

	var q [10050]point;
	h:=0;t:=1;
	q[1].x=1;q[1].y=1;

	var height int =len(m);
	var width int=len(m[0]);

	var vis [][]bool;
	vis=make([][]bool,height);
	for i:=0;i<height;i++ {
		vis[i]=make([]bool,width);
	}

	var step [][]int;
	step=make([][]int,height);
	for i:=0;i<height;i++{
		step[i]=make([]int,width);
	}


	for i:=0;i<height;i++{

		for j:=0;j<width;j++{

			vis[i][j]=false;
			step[i][j]=-1;
		}
	}
	vis[1][1]=true;
	step[1][1]=0;
	
	


	height=height-1;
	width=width-1;

	var dir [5][3]int;
	dir[1][1]=1;dir[1][2]=0;
	dir[2][1]=0;dir[2][2]=1;
	dir[3][1]=-1;dir[3][2]=0;
	dir[4][1]=0;dir[4][1]=-1;


	for ;h!=t; {
		h++;
		now:=q[h];
		
		x:=now.x;
		y:=now.y;
		for i:=1;i<4;i++ {
			nx:=x+dir[i][1];
			ny:=y+dir[i][2];

			if nx<=0 || nx>height || ny<=0||ny>width {
				continue;
			}

			if vis[nx][ny]==false && m[nx][ny]==1 {
				vis[nx][ny]=true;
				step[nx][ny]=step[x][y]+1;

				t++;
				q[t].x=nx;
				q[t].y=ny;
			}
		}


	}

	fmt.Printf("");
/* ans debug
	for i:=1;i<=height;i++{
		for j:=1;j<=width;j++{
			fmt.Printf("%d ",step[i][j]);
		}
		fmt.Printf("\n");
	}
*/
	return step[height][width];

}

然后补全bfs_test.go

主要就是拟造数据

package bfs

import "testing"

func TestBfs(t *testing.T) {
	var m [][]int=make([][]int,101);
	for i:=0;i<101;i++ {
		m[i]=make([]int,51);
	}

	//先建立无障碍迷宫
	for i:=0;i<101;i++{
		for j:=0;j<51;j++{
			m[i][j]=1;
		}
	}	

	// 在迷宫中加入两堵墙,让计算机绕路
	for i:=1;i<=99;i++ {
		m[i][3]=0;
	}
	for i:=2;i<=100;i++{
		m[i][5]=0;
	}
	excepted:=346;//脑算答案

	ans:=Bfs(m);

	if ans!=excepted {
		t.Errorf("we want %d , but we get %d",excepted,ans);
	}
}

这里画了一个大致是这样的迷宫:

在这里插入图片描述

绕个弯子就走到了答案是346(具体数据见代码)

go test测试结果:

ok      hw2     0.451s

说明答案正确

如果更改excepted为-1呢?(故意出错)
结果:

bfs_test.go:30: we want -1 , but we get 346

说明测试是可靠的。


基准测试 (貌似就是测时间)

在bfs_test.go中加入函数 BenchmarkBfs(b *testing.B)

func BenchmarkBfs( b* testing.B){
	var m [][]int=make([][]int,101);
	for i:=0;i<101;i++ {
		m[i]=make([]int,51);
	}

	//先建立无障碍迷宫
	for i:=0;i<101;i++{
		for j:=0;j<51;j++{
			m[i][j]=1;
		}
	}


	// 在迷宫中加入两堵墙,让计算机绕路
	for i:=1;i<=99;i++ {
		m[i][3]=0;
	}
	for i:=2;i<=100;i++{
		m[i][5]=0;
	}


	for i:=0;i<b.N;i++{
		Bfs(m);
	}
}

然后运行

go test XXX -bench="."

运行结果:

goos: windows
goarch: amd64
pkg: hw2
BenchmarkBfs-16            20274             60140 ns/op
PASS
ok      hw2     2.294s

表明运行了20274次,每次60140纳秒

(新电脑,就是快)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值