alogorithm: random walk and a knight's tour

本文介绍了两种经典的路径搜索算法——随机漫步和骑士旅行。随机漫步算法通过模拟蟑螂在一个网格上的随机移动来覆盖所有格子,而骑士旅行则解决了一个骑士如何在不重复的情况下走遍整个棋盘的问题。文章提供了详细的算法实现。
摘要由CSDN通过智能技术生成

数据结构第2章花了2个礼拜才搞定,工作忙,业余时间少了。

总结2个算法:随机漫步和骑士旅行(题目参见p62)

随机漫步:一只大蟑螂在m*n的格子上随机行走,经过多少次可以走遍整个格子

 

// algorithm random walk.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <time.h>
using namespace std;
//Current status of bug
struct status
{
	int x, y;
	int passed;
	int iterated;
};
//Map information
struct maps
{
	int iLength, iWideth;
	int **p;
};

class randomwalk
{
public:
	randomwalk(int iLen, int iWide, int max_iter);
	~randomwalk();
	int walk(int i);
	void algorithm();
	void printWalk();
private:
	struct status m_stStatus;
	struct maps m_stMap;
	int m_iMaxIter;
};

//Init map and status
randomwalk::randomwalk(int iLen, int iWide, int max_iter)
{
	m_stMap.iLength = iLen;
	m_stMap.iWideth = iWide;
	m_stMap.p = new int *[iLen];
	int i, j;
	for(i = 0; i < iLen; ++i)
	{
		m_stMap.p[i] = new int[iWide];
	}
	for(i = 0 ; i < iLen; ++i)
		for(j = 0; j < iWide; ++j)
			m_stMap.p[i][j] = 0;
	//random the position of bug, passed grid is 0
	m_stStatus.passed = 0;
	m_stStatus.iterated = 0;
	m_stStatus.x = rand()%(iLen - 1);
	m_stStatus.y = rand()%(iWide - 1);
	m_iMaxIter = max_iter;
}

randomwalk::~randomwalk()
{
	for(int i = 0; i < m_stMap.iLength; ++i)
		delete []m_stMap.p[i];
	delete []m_stMap.p;
}

//judge if walk is legal , if walk return 1, else return 0
int randomwalk::walk(int i)
{
	switch(i)
	{
		case 0:
			if(m_stStatus.x > 0 && m_stStatus.y < (m_stMap.iWideth - 1))
			{
				m_stStatus.x--;
				m_stStatus.y++;
				return 1;
			}
			return 0;
		case 1:
			if(m_stStatus.y < (m_stMap.iWideth - 1))
			{
				m_stStatus.y++;
				return 1;
			}
			return 0;
		case 2:
			if(m_stStatus.x < (m_stMap.iLength - 1) && m_stStatus.y < (m_stMap.iWideth -1) )
			{
				m_stStatus.x++;
				m_stStatus.y++;
				return 1;
			}
			return 0;
		case 3:
			if(m_stStatus.x <(m_stMap.iLength - 1))
			{
				m_stStatus.x++;
				return 1;
			}
			return 0;
		case 4:
			if(m_stStatus.x < (m_stMap.iLength - 1) && m_stStatus.y > 0)
			{
				m_stStatus.x++;
				m_stStatus.y--;
				return 1;
			}
			return 0;
		case 5:
			if(m_stStatus.y >0)
			{
				m_stStatus.y--;
				return 1;
			}
			return 0;
		case 6:
			if(m_stStatus.x >0 && m_stStatus.y > 0)
			{
				m_stStatus.x--;
				m_stStatus.y--;
				return 1;
			}
			return 0;
		case 7:
			if(m_stStatus.x > 0)
			{
				m_stStatus.x--;
				return 1;
			}
			return 0;
		default:
			printf("Error walk");
			return 0;
	}
}

//walk all grids
void randomwalk::algorithm()
{
	while(m_stStatus.passed < (m_stMap.iLength*m_stMap.iWideth) && m_stStatus.iterated < m_iMaxIter)
	{
		int rnd = rand()%8;
		if(walk(rnd))
		{
			int i = m_stStatus.x, j = m_stStatus.y;
			if(m_stMap.p[i][j] == 0)
			{
				m_stStatus.passed++;
			}
			m_stMap.p[i][j]++;
			m_stStatus.iterated++;
		}
	}
}
void randomwalk::printWalk()
{
	printf("Walk times is %d.\n", m_stStatus.iterated);
	for(int i = 0; i < m_stMap.iLength; ++i)
	{
		for(int j = 0; j< m_stMap.iWideth; ++j)
		{
			printf("%3d ", m_stMap.p[i][j]);
		}
		printf("\n");
	}
}
int _tmain(int argc, _TCHAR* argv[])
{
	srand((int)time(0));
	class randomwalk *pcRandWalk;
	pcRandWalk = new randomwalk(15, 15, 50000);
	pcRandWalk->algorithm();
	pcRandWalk->printWalk();
	delete pcRandWalk;
	return 0;
}


骑士旅行:一个国际象棋棋盘,随机一个位置(i,j),在不重复的情况下走L步,走遍整个棋盘。

算法:board[8][8] = {0};当位于(i,j)时,下一步pos = movpos(i,j),if(pos = 0 ) 退出,打印;else 存储下一步的可能的坐标;

            对可能的坐标 posnext = movpos(nextx,nexty); 找到最小的posnext,并把该坐标 = 当前坐标,mboard[i][j] = count++;

 代码如下:也可以采用递归,我这个方法比较2,各位看官谅解。

// knight's tour.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>


int ktmove1[8] = {-2,-1,1,2,2,1,-1,-2};
int ktmove2[8] = {1,2,2,1,-1,-2,-2,-1};
struct coordinate
{
	int x, y;
};

struct nextpos
{
	int nextx[8], nexty[8];
	int pos;
};


class lshaped
{
public:
	lshaped(int x, int y);
	int movepos(int x, int y, struct nextpos *pnext);
	int move();
	void print();
private:
	int m_board[8][8];
	int m_count;
	struct coordinate m_stCondition;
	struct nextpos m_stNextPos;
	bool m_flag;
};

//init board
lshaped::lshaped(int x, int y)
{
	for(int i = 0; i < 8; ++i)
		for(int j = 0; j < 8; ++j)
			m_board[i][j] = 0;
	m_stCondition.x = x;
	m_stCondition.y = y;
	m_count = 0;
	m_flag = 1;
	memset(&m_stNextPos, 0, sizeof(m_stNextPos));
}


//possible move position and return num
int lshaped::movepos(int x, int y, struct nextpos *pnext)
{
	pnext->pos = 0;
	for(int i = 0; i < 8; ++i)
	{
		if( (x + ktmove1[i]) < 8 && (x + ktmove1[i]) >= 0 &&
		(y + ktmove2[i]) < 8 && (y + ktmove2[i]) >= 0 &&((x + ktmove1[i])!= 3 || (y + ktmove2[i])!=3) &&
		m_board[x + ktmove1[i]][y + ktmove2[i]] == 0)
		{
			pnext->nextx[pnext->pos] = x + ktmove1[i];
			pnext->nexty[pnext->pos] = y + ktmove2[i];
			pnext->pos++;
		}
	}
	return pnext->pos;
}

//begin to move, loop movepos, if pos = 0;printf else min = movepos(x[i],y[i]), postion + [min];
int lshaped::move()
{
	int i;
	int num, min = 8;
	int index;
	struct nextpos *ptemp = NULL;
	i = movepos(m_stCondition.x, m_stCondition.y, &m_stNextPos);
	if(i == 0)
	{
		return 1;
	}
	ptemp = (struct nextpos *)malloc(sizeof(struct nextpos));
	memcpy(ptemp, &m_stNextPos, sizeof(struct nextpos));
	for(int j = 0 ; j < i; ++j)
	{
		num = movepos( m_stNextPos.nextx[j],m_stNextPos.nexty[j], ptemp );
		if(num < min)
		{
			min = num;
			index = j;
		}
	}
	free(ptemp);
	m_stCondition.x = m_stNextPos.nextx[index];
	m_stCondition.y = m_stNextPos.nexty[index];
	m_board[m_stCondition.x][m_stCondition.y] = ++m_count;
	return 0;
}

void lshaped::print()
{
	for(int i = 0; i < 8; ++i)
	{
		for(int j = 0; j < 8; ++j)
		{
			printf("%2d ", m_board[i][j]);
		}
		printf("\n");
	}
}
int _tmain(int argc, _TCHAR* argv[])
{
	class lshaped example(3, 3);
	int flag = 1;
	while(flag)
	{
		if(example.move())
			flag = 0;
	}
	example.print();
	return 0;
}


 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值