试探法(回溯法)算法

试探算法的思路

用试探法解题的一般步骤如下:

(1)针对所给问题,定义问题的解空间;

(2)确定易于搜索解空间结构

(3)以深度优先方式搜索空间,并再搜索过程种用减枝函数避免无效搜索。

试探法为了求得问题得正确解,先试探某一种可能情况。在试探过程种,一旦发现原来得选择的假设情况是错误的,就退回一步重新算则,继续向前试探,如此反复进行,直至得到解或证明无解


八皇后问题

八皇后问题是一个古老而著名得问题,是试探法的典型例题。该问题由19世纪数学家高斯于1850年手工解决:在8*8格的国际象棋棋盘摆放8个皇后,使其不能相互公鸡,即任意两个皇后不能处于同一行,同一列或同一斜线上,问由多少种摆法。

算法思想:

做之前首先将问题简化,设为4*4的棋盘。易知有2种摆法。每行摆在列2413和3142上。

#include<stdio.h>
#define N 8
int solution[N],j,k,count,sols;
int place(int row,int col)
{
    for(j=0;j<row;j++){
	     if(row-j==solution[row]-solution[j]||row+solution[row]==j+solution[j]||solution[j]==solution[row]){
		     return 0;
		 }
	}
	return 1;
}

void bcaktrack(int row)
{ 
   count++;
   if(N==row){
      sols++;
	  for(k=0;k<N;k++){
	      printf("%d\t",solution[k]);
	  }
	  printf("\n\n");
   }
   else{
       int i;
	   for(i=0;i<N;i++){
	      solution[row]=i;
		  if(place(row,i)){
		      bcaktrack(row+1);
		  }
	   }
   }
}

void queens()
{
     bcaktrack(0);
}

void main()
{
   queens();
   printf("Total Solution:%d\n",sols);
}

彩票组合

假设有一种彩票,每注由7个1~29的数字组成,且这7个数字不能相同,编写程序生成所有的号码组合。


#include<stdio.h>
#define MAXN 7 //设置每一注彩票的位数
#define NUM 29 //设置组成彩票的数字
int num[NUM];
int lottery[MAXN];

void combine(int n,int m)
{
    int i,j;
	for(i=n;i>=m;i--){
	   lottery[m-1]=num[i-1]; //保存一位数字
	   if(m>1){
	      combine(i-1,m-1); 
	   }
	   else{  //若m=1,输入一注号码
	       for(j=MAXN-1;j>=0;j--){
		      printf("%3d",lottery[j]);
		   }
		   getchar();
		   printf("\n");
	   }
	   
	}
}

void main()
{
     int i;
	 for(i=0;i<NUM;i++){  //设置彩票各位数
	     num[i]=i+1;
	 }
	 for(i=0;i<MAXN;i++){
	     lottery[i]=0;
	 }
	 combine(NUM,MAXN);
}


猜你喜欢

转载自blog.csdn.net/qq_41398448/article/details/80318193