<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>New Page 1</title>
<script language="JavaScript" fptype="dynamicanimation">
<!--
function dynAnimation() {}
function clickSwapImg() {}
//-->
</script>
<script language="JavaScript1.2" fptype="dynamicanimation" src="animate.js">
</script>
</head>

<body onload="dynAnimation()">

<pre dynamicanimation="fpAnimOutflyLeftFP1" id="fpAnimOutflyLeftFP1" style="position: relative !important" onclick="dynAnimOut(this)" language="Javascript1.2">         <img border="0" src="picture/110601.gif" width="100" height="96">                               <b><font size="5">马 行 天 下<img border="0" src="picture/horse.jpg" width="32" height="32"></font></b></pre>
<pre>　</pre>
<pre>//这是一个欧拉提出的问题：国际象棋的棋盘上一个马，能否走64步正好走遍64个棋盘格子。</pre>
<pre>//我用最土的办法来搜索，这是一个典型的“深度优先搜索”（Depth-First-Search)，我全部由数组来做，一个2维数组存走过的轨迹，一个数组存可</pre>
<pre>//以走的步数，再一个数组存每一层的最后一个选择，实际就是当前最底层的父亲。</pre>
<pre>//这是在McGill听Prfessor NewBurn 的课的唯一的收获，这位老教授是Game软件的专家，据说主持过IBM的“深蓝”与国际特级大师“卡斯帕罗夫”的</pre>
<pre>//对抗赛，可惜他的课程艰深，作业难做，我听课时，（当然是非法的。）加上我才7个学生，他对学生态度很好，总是说他担心学生会觉得作业太难会</pre>
<pre>//杀他。哈哈。。。也许阿。真怀念那个月的生活，一天听6门课，从8：30到4：30，每节课只有十分钟换教室，中午没吃饭，我几乎晕过去，下午困的要死，</pre>
<pre>//上一节课睡半截。不过一想到这是不要钱的，顿时觉得大赚特赚。</pre>
<pre>//这个小东东，我搞了快两天才完，还不知道对不对，哎，真失败！</pre>
<pre>//改进就是要能出结果，因为这样搜索是没有结果的因为，8^64是一个天文数字（当然，并不是每一步都有8个选择，有些出界，有些以前走过，但是可以</pre>
<pre>//看出这个问题的复杂性。）我粗略测试，估计电脑运行几万年也不会有结果，也不知道对不对。各位有兴趣不妨帮我检验一下，做做测试，很简单的，</pre>
<pre>只要<a href="KnightTour.zip">下载</a>解压缩并运行看看多长时间能有结果，在<a href="mailto:nickhuang99@sympatico.ca">写信</a>告诉我。</pre>
<pre>改进就是对产生的子节点排序，排序的原则是基于类似“权”值得概念，比如某一个点的权值是由能走到他的点的个数决定的，个数越多权值得优先级越低，</pre>
<pre>于是，我先将棋盘上所有点的“权”值存起来，当产生子树时候，先搜索优先级高的子树。</pre>
<pre>不过，好像还是有问题，搜索了两个结果后，（一个2百多万子节点，第二个约3千多万节点）第三个始终不出来。</pre>

<pre><font face="宋体">#include &lt;iostream&gt;
#include &lt;cstdlib&gt;
#include &lt;ctime&gt;


using namespace std;

//&Otilde;&acirc;&Ecirc;&Ccedil;&Acirc;í&Ograve;&AElig;&para;&macr;&micro;&Auml;×&oslash;±ê&iexcl;&pound;
struct Pos
{
	int x;
	int y;
}pos;

//&Otilde;&acirc;&Ecirc;&Ccedil;&AElig;&eth;&Ecirc;&frac14;&Icirc;&raquo;×&Oacute;&iexcl;&pound;
struct Pos startPos;
//&AElig;&aring;&Aring;&Igrave;&micro;&Auml;&acute;ó&ETH;&iexcl;
const boardSize =6;   //using even 7 will cost days running.


//&Acirc;í&iquest;&Eacute;&Ograve;&Ocirc;×&szlig;&micro;&Auml;8&cedil;&ouml;&sup2;&frac12;×&Oacute;&iexcl;&pound;
enum Move
{
	upright, upleft, downleft, downright, leftup, leftdown, rightup, rightdown
};
//&frac14;&Iacute;&Acirc;&frac14;×&szlig;&micro;&Auml;&sup2;&frac12;&Ecirc;&yacute;&iexcl;&pound;
int Tour[8 * boardSize * boardSize]= {0};

//&Otilde;&acirc;&Ecirc;&Ccedil;&Euml;&Ntilde;&Euml;÷&micro;&Auml;&sup2;&atilde;&Ecirc;&yacute;&pound;&not;&Ograve;&sup2;&frac34;&Iacute;&Ecirc;&Ccedil;&Atilde;&iquest;&Ograve;&raquo;&sup2;&frac12;&micro;&Auml;&Ouml;&cedil;±ê&pound;&not;&Ograve;ò&Icirc;&ordf;&Atilde;&iquest;&Ograve;&raquo;&sup2;&frac12;&para;&frac14;&iquest;&Eacute;&Auml;&Uuml;&Oacute;&ETH;8&cedil;&ouml;&Ntilde;&iexcl;&Ocirc;&ntilde;&iexcl;&pound;&Otilde;&acirc;&Agrave;&iuml;&Ouml;&cedil;&Iuml;ò×&icirc;&ordm;ó&Ograve;&raquo;&cedil;&ouml;&Icirc;&raquo;&Ouml;&Atilde;&iexcl;&pound;
int Level[boardSize*boardSize]={0};

//&Ecirc;&Ccedil;·&ntilde;&Oacute;&ETH;&frac12;&acirc;&pound;¨&Egrave;&laquo;&frac34;&Ouml;±&auml;&Aacute;&iquest;&sup2;&raquo;&ordm;&Atilde;&pound;&copy;
bool solution = false;

//reading way of priority
int getPriority(int x, int y);

//from direction to priority
int direction2Priority(int direction);

//×&Uuml;&micro;&Auml;&frac14;&AElig;&Ecirc;&yacute;&AElig;÷&iexcl;&pound;
int Counter = 0;

//temp storage for possible move and sorting before save to Tour[];
int tempMove[8] = {0};


//storage for prioty for each square in chessboard
int priority[boardSize][boardSize] = {0};


//&sup2;&atilde;&Ecirc;&yacute;&micro;&Auml;&frac14;&AElig;&Ecirc;&yacute;&AElig;÷&iexcl;&pound;
int Step = 0;

//save possible move to tempMove[] with big to small priority
//void saveTempMove(int &amp;x, int &amp;y, int moveNum);

//assignment prioty for each square.
void generatePriority();

//&Otilde;&acirc;&Ecirc;&Ccedil;&AElig;&aring;&Aring;&Igrave;&pound;&not;&Oacute;&Atilde;&Agrave;&acute;&frac14;&Ccedil;&Acirc;&frac14;&AElig;&aring;×&Oacute;&Ecirc;&Ccedil;·&ntilde;×&szlig;&sup1;&yacute;&Auml;&sup3;&Ograve;&raquo;&cedil;&ouml;&Icirc;&raquo;×&Oacute;&pound;&not;0&Icirc;&ordf;&Atilde;&raquo;&Oacute;&ETH;&pound;&not;1&Icirc;&ordf;×&szlig;&sup1;&yacute;&iexcl;&pound;
int board[boardSize][boardSize] = {0};

//&sup2;ú&Eacute;ú&Atilde;&iquest;&Ograve;&raquo;&sup2;&atilde;&micro;&Auml;&sup2;&frac12;&Ecirc;&yacute;&iexcl;&pound;&Egrave;&ccedil;&sup2;&raquo;&Auml;&Uuml;&sup2;ú&Eacute;ú·&micro;&raquo;&Oslash;&frac14;&Ugrave;&iexcl;&pound;
bool Generate();
//&AElig;&Agrave;&sup1;&Agrave;&Ecirc;&Ccedil;·&ntilde;&Otilde;&Ograve;&micro;&frac12;&frac12;á&sup1;&ucirc;&iexcl;&pound;
bool Evaluate();
//&sup2;&raquo;&Auml;&Uuml;&sup2;ú&Eacute;ú&pound;&not;&frac34;&Iacute;&Iacute;&Euml;&raquo;&Oslash;&Ograve;&raquo;&sup2;&frac12;&pound;&not;&Ouml;&Oslash;&ETH;&Acirc;&sup2;ú&Eacute;ú&iexcl;&pound;
void Restore();

//&iquest;&acute;&Ecirc;&Ccedil;·&ntilde;&Ecirc;&Ccedil;&Iacute;&Euml;&raquo;&Oslash;&micro;&frac12;&Eacute;&Iuml;&Ograve;&raquo;&sup2;&atilde;&Aacute;&Euml;&iexcl;&pound;
bool stepPoint();
//&Auml;&Uacute;&sup2;&iquest;·&frac12;·¨&pound;&not;&sup2;ú&Eacute;ú&Auml;&sup3;&Ouml;&Ouml;×&szlig;·¨&micro;&Auml;×&oslash;±ê&Ouml;&micro;&iexcl;&pound;
void getMove(int direction, int &amp;x, int &amp;y);
//°&acute;&Otilde;&Otilde;&sup2;&Icirc;&Ecirc;&yacute;&micro;&Auml;×&szlig;·¨&pound;&not;&Ograve;&AElig;&para;&macr;&Acirc;í&micro;&Auml;×&oslash;±ê&Icirc;&raquo;&Ouml;&Atilde;&iexcl;&pound;
void stepMove(int direction);
//&Iuml;&Ocirc;&Ecirc;&frac34;&Otilde;&yacute;&Egrave;·&micro;&Auml;&sup2;&frac12;×&Oacute;
void displayMove();

//to see if the direction is possible move
bool testMove(int direction);//test new move if within bound and unoccupied


//&sup3;&otilde;&Ecirc;&frac14;&raquo;&macr;&iexcl;&pound;
void Initialize(int, int);


int main()
{
	int startTime=0;
	long tick =0;
	generatePriority();
	for (int i =0; i&lt; boardSize; i++)
	{
		for (int j=0; j&lt; boardSize; j++)
		{
			tick =0;
			Initialize(i, j);
			startTime = time(0);
			while (!Evaluate())
			{		
				if (!Generate())     //&sup2;&raquo;&Auml;&Uuml;&sup2;ú&Eacute;ú&frac34;&Iacute;&Iacute;&Euml;&raquo;&Oslash;&Eacute;&Iuml;&Ograve;&raquo;&sup2;&frac12;&iexcl;&pound;
				{	
					Restore();  //&Iacute;&Euml;&raquo;&Oslash;&Eacute;&Iuml;&Ograve;&raquo;&sup2;&frac12;&iexcl;&pound;
					if (Counter &lt;= 0)   //&frac14;ì&Ntilde;é&Ecirc;&Ccedil;·&ntilde;&Iacute;&Euml;&raquo;&Oslash;&micro;&frac12;&AElig;&eth;&micro;&atilde;&pound;&not;±í&Atilde;÷&Ecirc;&Ccedil;·&ntilde;&Icirc;&THORN;&frac12;&acirc;&iexcl;&pound;
					{
						cout&lt;&lt;&quot;no solution for pos.x=&quot;&lt;&lt;startPos.x
							&lt;&lt;&quot; and pos.y=&quot;&lt;&lt;startPos.y&lt;&lt;&quot;    total time is:&quot;
							&lt;&lt;time(0) - startTime&lt;&lt;&quot; tick is &quot;&lt;&lt;tick&lt;&lt;&quot; times&quot;&lt;&lt;endl;
						break;
					}
				
				}
				tick++;
		//		displayMove();
			}
			cout&lt;&lt;&quot;  pos.x=&quot;&lt;&lt;startPos.x
							&lt;&lt;&quot; and pos.y=&quot;&lt;&lt;startPos.y&lt;&lt;&quot;    total time is:&quot;
							&lt;&lt;time(0) - startTime&lt;&lt;&quot; tick is &quot;&lt;&lt;tick&lt;&lt;&quot; times&quot;&lt;&lt;endl;
			if (solution)
				displayMove();
			else
				cout&lt;&lt;&quot;no solution!&quot;&lt;&lt;endl;
			
		}
	}
	
	return 0;
}

void displayMove()
{
	cout&lt;&lt;&quot;  A solution is as following:&quot;&lt;&lt;endl;
//	cout&lt;&lt;&quot;  Starting from pos.x = &quot;&lt;&lt;startPos.x&lt;&lt;&quot; and pos.y = &quot;&lt;&lt;startPos.y&lt;&lt;endl;
	cout&lt;&lt;&quot;  Total moves are &quot;&lt;&lt;Counter&lt;&lt;endl;

	for (int i =0; i &lt;= Step; i++)
	{
		
		cout&lt;&lt;&quot;   Tour[&quot;&lt;&lt;Level[i]&lt;&lt;&quot;]  &quot;&lt;&lt;Tour[Level[i]]&lt;&lt;endl;//&Ecirc;&auml;&sup3;&ouml;&frac12;á&sup1;&ucirc;&iexcl;&pound;
	}
}

int getPriority(int x, int y)
{
	return priority[x][y];
}

/*
//x, y must return the smallest move pos which is the last one in array(big--&gt;small)
void saveTempMove(int &amp;x, int &amp;y, int moveNum)
{
	int temp =0;
	for (int i=0; i&lt; moveNum; i++)
	{
		if  (getPriority(x, y) &lt; priority[i])//???????????
		{
			temp = priority[i];
			priority[i] = 
			while (i &lt;= moveNum)
			{
				priority[
			insertPriority(x, y);
			;
		}
	}
}
*/


void generatePriority()
{
	int moves;
	for (int i =0; i&lt; boardSize; i++)
	{
		for (int j=0; j&lt; boardSize; j++)
		{
			moves =0;
			for (int direction =0; direction &lt; 8; direction++)
			{
				if (testMove(direction))
				{
					moves++;
				}
			}
			priority[i][j] = moves;
		}
	}
}

int direction2Priority(int direction)
{
	int x, y;
	getMove(direction, x, y);
	return getPriority(x, y);
}





void Initialize(int x, int y)
{

	startPos.x = x;
	startPos.y = y;
	for (int i=0; i&lt; boardSize; i++)
	{
		for (int j=0; j &lt; boardSize; j++)
		{
			board[i][j] =0;
		}
	}
	board[x][y] = 1;
	pos.x = x;
	pos.y = y;
	Step = 0;
	Counter = 0;
	Level[Step] = Counter;
	Tour[Counter] = -1;   //&Atilde;&raquo;&Ograve;&acirc;&Euml;&frac14;&micro;&Auml;&iexcl;&pound;
	solution = false;
}

void addStep()     //&Ograve;&AElig;&para;&macr;&micro;&frac12;&ETH;&Acirc;&sup2;&atilde;&iexcl;&pound;
{
	Step++;
	Level[Step] = Counter;
}

bool Evaluate()
{
	if (Counter &lt; 0)
	{
		cout&lt;&lt;&quot;no&quot;;
		solution =false;
		return true;
	}
	return (solution =(Step == boardSize * boardSize - 1));
}

bool Generate()
{
	int findPriority(int tempPriority, int start);
	void insertPriority(int curPos, int direction);
	void addStep();
	int curPos=0, tempPriority;
	
	bool result = false;
	int row, col;
	int temp = Counter + 1;
	for (int direction =0; direction &lt; 8; direction ++)  
	{
		if (testMove(direction))   //&sup2;&acirc;&Ecirc;&Ocirc;8&cedil;&ouml;·&frac12;&Iuml;ò&iexcl;&pound;
		{
			result = true;
			Counter ++;
			tempPriority = direction2Priority(direction);
			curPos = findPriority(tempPriority, temp);
			insertPriority(curPos, direction);			
		}
	}
	if (result)    //&Ograve;&AElig;&para;&macr;&micro;&frac12;×&icirc;&ordm;ó&Ograve;&raquo;&cedil;&ouml;×&szlig;·¨&iexcl;&pound;
	{	
//		copyMoves();
		getMove(Tour[Counter], row, col);
		pos.x = row;
		pos.y = col;
		board[row][col] = 1;   //this is the point to move to.
		addStep();
	}
	return result;
}


int findPriority(int tempPriority, int start)
{
	for (int i=start; i &lt; Counter; i++)
	{
		if (tempPriority &gt;direction2Priority(Tour[i]))
			break;
	}
	return i;
}

void insertPriority(int curPos, int direction)
{
	int hold=0, temp =0;
	hold = Tour[curPos];
	Tour[curPos] = direction;
	for (int i = curPos + 1; i &lt;= Counter + 1; i++)
	{
		temp = Tour[i];
		Tour[i]= hold;
		hold = temp;
	}
}


	


bool stepPoint()
{
	return (Counter == Level[Step - 1]);   //&sup2;&acirc;&Ecirc;&Ocirc;&Ecirc;&Ccedil;·&ntilde;&Iacute;&Euml;&raquo;&Oslash;&micro;&frac12;&Eacute;&Iuml;&Ograve;&raquo;&sup2;&atilde;&iexcl;&pound;
}

void Restore()
{
	void counterMove(int lastMove);
	void moveStep();

	board[pos.x][pos.y] = 0;  //make unoccupied erase track
	counterMove(Tour[Counter]);  //restore to parent pos

	Counter --; 
	if (Counter &lt;= 0)
		return;
	
	//back
	if (stepPoint())   //if it is parent
	{
		Step--;       //use the upper level step
		Restore();  //keep going
	}
	else
		moveStep();  //simply make current node the step point
}


void moveStep()
{
	Level[Step] = Counter;
	stepMove(Tour[Counter]);
	board[pos.x][pos.y] = 1;   //&Ograve;&AElig;&para;&macr;&micro;&frac12;&ETH;&Acirc;&micro;&Auml;&frac34;&Iacute;&Ograve;&ordf;±í&Ecirc;&frac34;&Ograve;&Ntilde;&frac34;&shy;&Otilde;&frac14;&Oacute;&Atilde;&Aacute;&Euml;&iexcl;&pound;
}


void getMove(int direction, int &amp;x, int &amp;y)
{
	switch (direction)
	{
	case upleft:
		x = pos.x - 1;
		y = pos.y - 2;
		break;
	case upright:
		x = pos.x + 1;
		y = pos.y - 2;
		break;
	case downleft:
		x = pos.x - 1;
		y = pos.y + 2;
		break;
	case downright:
		x = pos.x + 1;
		y = pos.y + 2;
		break;
	case leftup:
		x = pos.x - 2;
		y = pos.y - 1;
		break;
	case leftdown:
		x = pos.x - 2;
		y = pos.y + 1;
		break;
	case rightup:
		x = pos.x + 2;
		y = pos.y - 1;
		break;
	case rightdown:
		x = pos.x + 2;
		y = pos.y + 1;
		break;
	}
}

bool testMove(int direction)
{
	int x, y;
	getMove(direction, x, y);
	if ((x &lt; boardSize)&amp;&amp;(x &gt;= 0)&amp;&amp;(y &lt; boardSize)&amp;&amp;(y &gt;= 0))   //&Ecirc;&Ccedil;·&ntilde;&sup3;&ouml;&frac12;&ccedil;
	{
		if (board[x][y]== 0)   //prevent x, y out of bound of board[][] if they are minus. so don't put logic op above.
		{		
			return true;
		}
	}
	return false;
}
	
void stepMove(int direction)
{
	int x, y;
	getMove(direction, x, y);
	pos.x = x;
	pos.y = y;
}

void counterMove(int lastMove)
{
	int newMove;
	switch(lastMove)
	{
	case upleft:
		newMove = downright;
		break;
	case upright:
		newMove = downleft;
		break;
	case downleft:
		newMove = upright;
		break;
	case downright:
		newMove = upleft;
		break;
	case leftup:
		newMove = rightdown;
		break;
	case leftdown:
		newMove = rightup;
		break;
	case rightup:
		newMove = leftdown;
		break;
	case rightdown:
		newMove = leftup;
		break;
	}
	stepMove(newMove);
}




</font>


                       <a href="zebra.htm"><img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>      <a href="index.htm"><img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       <a href="Maze.htm"><img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35"></a>


</pre>

</body>

</html>
