盘点数独终盘生成算法 – 哆啦A瑶的博客

版权述说:定冠词是视频博客作者的原型文字,变动从而产生断层视频博客作者答应,不得模仿究竟哪个答应。。

数独很难玩,设置数独题轻易吗?,率先,规定数独中数独的精确地解释。,列举如下图所示,把数独堕入9个9格,完全,数字1-9从左到右。81隔间数独被精确地解释为二维阻碍[9][9。是否we的所有格形式不意识到玩数独,,因而这变动从而产生断层给你的。,请去数独百度百科了本领独游玩的不动的。

是否你想设想一个人挨次来发生数独成绩,we的所有格形式从哪里开端?有两个体系。:体系一,提早设置好皇冠即时走地,率先,数独成绩就十足了 另存为录音,当你运用它时,你可以选择数独成绩, 留点合住。;体系二,经过算法实时 准备数独科目,再空白一次。。作为一名优良的挨次员,we的所有格形式只好履行更硬的的详细提出某事二,这么到何种地步设计算法呢 凌厉的达到解决体系 数独标题呢?我在沉思了《计划之美》和入席 在视频博客的回复后来地,总结以下第四的解决体系。

1、例行的回溯法

2、以宫阙为单位的矩阵置换法

3、鉴于数字挨次的回溯法

4、一种鉴于数独的数字掉换方式


1、例行的回溯法

这人方式是最轻易出现的, 但给予帮助实力能够变动从而产生断层很高。

思绪辨析:

最原始的不动的回归方式是从左上角皮病,0)开端,达到随机数字,和以次从左向右地行驶、完全,we的所有格形式逐步使成形数独不动的。。仍然,平昔人道总结的体验和在的成绩:这种方式真是迟钝的。!笨伯,你不克不及复杂地经过随机达到来达到极限的的数独。。故,使感激采取回溯法。:在任何人步达到1-9的数字均不克不及姑息数独请求允许的时分必要退回到上一个人国家重行达到安心能够的解。因而直到极限的,它蓄长了一个人充分的数独脸,此处理列举如下所示。:

C++加密:

#include 
#include 			// srand()
#include 			// time()
using namespace std;

int sudoMap[9][9] = {0};		// initialise map.
int counter = 1;			// the number of map already 达到。
int maxMapNumber = 1;			// how many map you want to 达到。

void printMap()
{
大约(int i = 0; i < 9; i++)
	{
	大约(int j = 0; j < 9; j++)
		{
			cout << sudoMap[i][j] << " ";
		}
		cout << endl;
	}
	cout << endl;
}

bool check()
{
	//check the row
大约(int i = 0; i < 9; i++)
	{
		int tempArr[9] = {0};

	大约(int j = 0; j < 9; j++)
		{
			if(sudoMap[i][j] != 0)
			{
				if(tempArr[sudoMap[i][j] - 1] == 0)
				{
					tempArr[sudoMap[i][j] - 1] = 1;
				}
				else
				{
					return false;
				}
			}
		}
	}

	//check the col
大约(int j = 0; j < 9; j++)
	{
		int tempArr[9] = {0};

	大约(int i = 0; i < 9; i++)
		{
			if(sudoMap[i][j] != 0)
			{
				if(tempArr[sudoMap[i][j] - 1] == 0)
				{
					tempArr[sudoMap[i][j] - 1] = 1;
				}
				else
				{
					return false;
				}
			}
		}
	}

	//check the 9-box
大约(int m = 0; m < 9; m += 3)
	{
	大约(int n = 0; n < 9; n += 3)
		{
			int tempArr[9] = {0};

		大约(int i = 0; i < 3; i++)
			{
			大约(int j = 0; j < 3; j++)
				{
					if(sudoMap[m + i][n + j] != 0)
					{
						if(tempArr[sudoMap[m + i][n + j] - 1] == 0)
						{
							tempArr[sudoMap[m + i][n + j] - 1] = 1;
						}
						else
						{
							return false;
						}
					}
				}
			}
		}
	}

	return true;
}

bool isMapFull()
{
	int flag[9*9] = {0};

大约(int i = 0; i < 9; i++)
	{
	大约(int j = 0; j < 9; j++)
		{
			if(sudoMap[i][j] != 0)
			{
				flag[i*9 + j] = 1;
			}
		}
	}

大约(int i = 0; i < 81; i++)
	{
		if(flag[i] == 0)
		{
			return false;
		}
	}

	return true;
}

bool checkIsNumberFull(int arr[9])
{
大约(int i = 0; i < 9; i++)
	{
		if(arr[i] == 0)
		{
			return false;
		}
	}
	return true;
}

int getRandNumber()
{
	return rand()%9 + 1;
}

void generateMap(int curIndex)
{
	if(isMapFull())
	{
		if(counter <= maxMapNumber)
		{
			cout << "SudoMap " << counter++ << endl;
			printMap();
			return;
		}
	}

	srand((unsigned int)time(0));
大约(int i = 1; i < 10; i++)
	{
		sudoMap[(int)(curIndex / 9)][curIndex % 9] = i;
		if(check())	// if curNumber is legal.
		{
			// cout << "curLevel:" << curIndex << endl;
			// printMap();
			generateMap(curIndex + 1);
		}
	}
	sudoMap[(int)(curIndex / 9)][curIndex % 9] = 0;

	return;
}

void generateLine1()
{
	int numberFlag[9] = {0};
	int curNumber;
	int counter = 0;

	srand((unsigned)time(NULL));
	while(!checkIsNumberFull(numberFlag))
	{
		curNumber = getRandNumber();
		if(numberFlag[curNumber - 1] == 0)
		{
			numberFlag[curNumber - 1] = 1;
			sudoMap[counter / 9][counter % 9] = curNumber;
			counter++;
		}
	}
}

int main()
{
	cout << "enter the number of sudoMap you want to generate: ";
	cin >> maxMapNumber;
	cout << "generating first line of the map..." << endl;
	generateLine1();
	cout << "generating the full sudoMap..." << endl;
	generateMap(9);

	return 0;
}

2、以宫阙为单位的矩阵置换法

这种方式很巧妙。,采取矩阵使轮流的方式来实施复杂化,但缺陷是它不克不及计入所局部法度数独。要达到的提议列举如下所述:

第一步:率先,用9个契合数独请求允许的数字填写第五宫。。

另外的步:第五宫宫调满意的经过行替换。

 第三步:第五宫的宫调满意的是经过柱式替换来改编乐曲的。。

第四的步:第四的宫的宫调满意的是经过柱式替换来改编乐曲的。,六度音程宫的满意的按条线图分为两有些。。大约,经过替换达到一个人充分的数独图。。

3、鉴于数字挨次的回溯法

这可以应该方式1的最佳化版本。

数独的方式是从左到右。、完全,填写挨次,仍然,挨次的运转通知we的所有格形式这人方式太迟钝的了,有那么多东西要回去,因而功能很差。视频博客们提到了最佳化边,总结列举如下:在达到数独的处理中,we的所有格形式率先填写,9座宫阙的定位从左到右从9到1决定。,和按使相等挨次填写2。,直到所局部数字都成功。是否we的所有格形式不契合数独不动的,we的所有格形式将回到极限的一个人包围。。

4、一种鉴于数独的数字掉换方式

这种方式也很巧妙,但有一个人充分致命的成绩。:恰当的换了号码。,数独的根本和解不动,因而和解是规则的。。比如,下面的数独:

we的所有格形式把第五宫的编号标注列举如下:a(3), b(6), c(5), d(7), e(9), f(8), g(2), h(1), i(4)。经过这人掉换不动的,你可以发音法母表掉换下面的数独。,这么字母A可以整个掉换为1-9的数字,B可以掉换1-9击中要害8个数字,但符合的的数字除外。,经过类比,有9个。!中间物排挤法。故,经过这种排挤方式,可以达到9!数独脸的榜样使相等但数字确切的。

发表评论

电子邮件地址不会被公开。 必填项已用*标注