问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

系统讲解回溯法6

发布网友 发布时间:2023-11-29 03:51

我来回答

4个回答

热心网友 时间:2024-02-26 23:08

有许多问题,当需要找出它的解集或者要求回答什么解是满足某些约束条件的最佳解时,往往要使用回溯法。

回溯法的基本做法是搜索,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法。这种方法适用于解一些组合数相当大的问题。

回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先策略搜索。

在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。

解向量:(x1, x2, … , xn)

显约束:xi=1,2, … ,n

隐约束:

    1)不同列:xixj

    2)不处于同一正、反对角线:|i-j||xi-xj|

bool Queen::Place(int k)

{

  for (int j=1;j<k;j++)

    if ((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k])) return false;

  return true;

void Queen::Backtrack(int t)

{

  if (t>n) sum++;

    else

      for (int i=1;i<=n;i++) {

        x[t]=i;

        if (Place(t)) Backtrack(t+1);

      }

 }

热心网友 时间:2024-02-26 23:09

以前算法试验做得
勉强看看吧

回溯的精髓在于不知道解决问题的确定方向,
就硬着头皮往前走,可以走的地方都走,
到最后没路可走到死路时,才往回退回上一个路口试探别的路

个人感觉有点像图的深度遍历
--------------------------------------------

//八皇后问题
//2008-04-23
//作者:leo

#include <iostream>
using namespace std;
#define N 8//皇后个数
int x[N+1]={0};//定义棋盘

bool place(int k)//判断k位置摆放皇后是否合理
{
int i=1;
while(i<k)
{
if(x[i]==x[k]||(abs(x[i]-x[k])==abs(i-k)))return false;
i++;
}
return true;
}

void print()//打印结果
{
for(int i=1;i<N+1;i++)
cout<<x[i]<<" ";
cout<<endl;
}

void nqueen(int k)//
{
int count=0;//解决方案数
while(k>=1)
{
x[k]++;
while(x[k]<=N&&!place(k))//从第一个位置开始试摆第k个皇后
{
x[k]++;
}
if(x[k]<=N)//第k个皇后安全时在棋盘内
{
if(k==N)//已经是第最后一个皇后则得到一个解决方案
{
count++;
cout<<count<<endl;
print();
}
else k++;//继续处理下一个皇后

}
else x[k--]=0;//第k个皇后安全时不在棋盘内,则回溯
}
}

void main()
{
nqueen(1);
}

热心网友 时间:2024-02-26 23:09

// Queen.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <stdio.h>
#include <stdlib.h>
char Queen[8][8],chessboard[8][8][200];
int column[8], askew1[15], askew2[15];
int answer=0;//开始之前,八皇后的解个数为零
void BlankChessboard()//构造初始法的国际棋盘与检验冲突的数组
{
int i,j;
for(i=0;i<8;i++)
{
column[i]=0;
for(j=0;j<8;j++)
Queen[i][j]='\35';
}
for(i=0;i<15;i++)
{
askew1[i]=0;
askew2[i]=0;
}

}

void Putqueen(int c_row,int c_col)//放置皇后的函数
{
Queen[c_row][c_col]='Q';
column[c_col]=1;//该位置[c_row][c_col]的列不能再放皇后
askew1[c_row-c_col+7]=1;//该位置[c_row][c_col]的右斜线不能再放皇后
askew2[c_row+c_col]=1;//该位置[c_row][c_col]的左斜线不能再放皇后
}

void RecordChessboard()//利用一个三维数组记录合法棋盘的函数
{
answer++;
int i,j;
for(i=0;i<8;i++)
for (j=0;j<8;j++)
chessboard[i][j][answer]=Queen[i][j];
}

void solveQueen(int c_row)
{
int c_col;
for (c_col=0;c_col<8;c_col++)
{
if ((column[c_col]==0)&&(askew1[c_row-c_col+7]==0)&&(askew2[c_row+c_col]==0))//如果当前位置的行列斜都没有皇后,该位置可以放皇后
{
Putqueen(c_row,c_col);//将皇后放到当前位置Queen[c_row][c_col]
if (c_row<7)
solveQueen(c_row+1);//利用递归,放置下一个皇后
else RecordChessboard();//记录当前合法的棋盘
Queen[c_row][c_col]='\35';
column[c_col]=0;
askew1[c_row-c_col+7]=0;
askew2[c_row+c_col]=0;
}

}

}
void Fprintf(FILE *fpw)//打印答案的函数
{
int i,j,k;
for(k=1;k<=answer;k++)
{
fprintf(fpw,"八皇后的第%d种解:\n",k);
for (i=0;i<8;i++)
{
for (j=0;j<8;j++)
{
fprintf(fpw,"%c ",chessboard[i][j][k]);
}
fprintf(fpw,"\n");
}
fprintf(fpw,"\n");
}

}

int main()
{

printf("八皇后问题是一个古老而著名的问题,是递归算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。现代教学中把八皇后问题当成一个经典递归算法例题。\n");
printf("程序运行后,答案放在当前目录的'八皇后的解.txt'\n");
FILE *fpw=fopen("八皇后的解.txt","w");
BlankChessboard();//初始化棋盘
solveQueen(0);//解决问题
Fprintf(fpw);//调用输出函数"Fprintf"
fclose(fpw);
system("pause");
return 0;
}
/*
printf("");
*/

热心网友 时间:2024-02-26 23:10

Lz,自己找书看,有很多书有啊。既然你问了,我就班门弄斧下。初始一个int数组。数组的下标代表列数。这样保证一列只有一个皇后。数组的值代表行数。比如说a[1]=2,代表的意思就是第一列,第二行有一个皇后。只要全部8列结束就行,有一组解。假设现在前面b列排好了,然后判断b+1列。a[b+1]的解不能与前面的解冲突,如果没有冲突,继续向下,直到第8列。如果冲突,退回来改a[b]的值,然后接下刚才的步骤。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
苹果手机微信怎么换漂亮字体(苹果手机微信怎么换行输入) 有什么好用的app转换字体 手写转文字的软件 erp可以看评论地址吗 淘宝评论url是什么意思? 揭秘:码牌支付风控升级,背后真相揭秘 电脑电视直播软件哪个好用什么软件好电脑看电视直播 潼南子同街学区是哪些 三极管BU406价格和参数? 火锅料放在冰柜忘了插电一个星期给会坏了吗 火锅的设备有哪些 忆苦思甜什么意思45 拼多多里由于某种原因,再补发的物件,是不显示物流信息的吗?_百度知 ... 苏州诺康贸易有限公司怎么样? 发现计算机病毒后比较彻底的清除方式是什么 ...意外终止,状态码为-1073741819。系统现在将关机 一个手机号码两个咋取消一个 86年正月初八时辰在12点--13点之间 是什么命呢?1 倩女幽魂2宁远本服敌军士兵和将领出现时间? 微信重新注册了,怎么找回以前那个? 我想换一个,怎么把原上的好友全都转移到新号上? 如何查询自己的身份信息被绑定了几个 “五一”假期小明骑自行车去郊游,早上8:00从家出发,9:30到达目的地.在... 太阳系有四道“墙”,人类可能永远无法脱离,难道我们被圈养了?_百度知 ... 《登飞来峰》中的一,二句,写实的是什么,联想的是什么 银行卡开户行号码怎么查 一款安卓的游戏 好像是个魔法师 他可以发射光弹 光弹可以攻击 也可以让... 为什么笔记本硬盘可以在移动硬盘盒上用,却不用在笔记本电脑上装系统... 我是1986年 2月 16日出生 下午5点 就是正月初八 有... 连接wifi后其他使用一切正常,但微信红包进不去,视频通话接不了打不了... 有个游戏,在地图里打怪单机的,里面有魔法师和枪手两种职业,求解_百度... 一个手机号可以注册两个吗? 为什么在由分子构成的物质中,分子是保持物质化学性质的一种粒子而不是... 白山东高速口是否关闭 韩国那里有没有QQ??接近QQ的东西有没有? 怎么隐藏起来好友看不到? 一个手机号注册了两个,怎样解绑第二个? 纠偏系统的液压系统的维护主要是哪方面的维护? 高端的算法和策略,谁能科普下,什么才叫高端算法和策略? 简述回溯法的2种算法框架,并分别举出适合用这两种框架解决的一...1 无换籽手串的穿法图解 ...原子保持了它们的化学性质,可为什么是分子保持了物质化学性质... 万科新榆公馆供暖怎么样 一个手机号码可以注册两个吗? 我是1987年3月28日21点30分出生的(阴历2月29日)... 以下叙述中,正确的是A.正数与负数互为相反数B.任何一个有理数都有相反... 改一年内怎么改第二次 正宫 塞鸿秋这首元曲运用了哪些修辞手法11 一个号码注册了两个,怎么注销另一个? ...windows XP Professional 版本 Service Pack 3 注册到 微软... 腾讯手游火影忍者怎么获得药师兜