八皇后源代码及流程图
计算机专业导论_哈尔滨工业大学中国大学mooc课后章节答案期末考试题库2023年
计算机专业导论_哈尔滨工业大学中国大学mooc课后章节答案期末考试题库2023年1.阅读下面的程序,其时间复杂度为_________?intindex=5;intcondition=1;if(condition==1)thenindex++;elseindex--;fori=1to100forj=1to200index=index+2;答案:O(1)2.假设基本门电路的符号为【图片】,已知如下电路【图片】问该电路不能实现的功能为______。
答案:当A=1,B=1,则P=13.下图是一个存储器的简单模型。
下列说法不正确的是_____。
【图片】答案:该存储器既可读出,又可写入4.已知A=40;B=30;C=100;D=50,逻辑“与”运算符为and,“或”运算符为or,“非”运算符为not。
计算表达式C > A +B +D的值,结果为_____。
答案:假5.TSP算法流程图如下图I.示意,回答问题:最内层循环(L变量控制的循环)的作用是_________。
【图片】答案:用于判断某个城市是否是已访问过的城市6.遗传算法设计需要引入变异操作。
变异操作是对种群中的某些可能解(个体)的某些编码位进行突变处理,例如二进制编码的解01110011,其第3位(自左而右)当前为1则将其变为0,称为变异操作。
通过变异操作,使遗传算法具有局部的随机搜索能力。
为什么?下列说法不正确的是_____。
答案:其它选项的说法有不正确的7.下图是一个存储器的简单模型。
当【图片】=10时,【图片】的内容是_____。
【图片】答案:1010108.操作系统管理信息的基本单位是_____。
答案:文件9.已知如下多元素变量。
【图片】执行下列程序,执行完成后,Sum1和Sum2的值分别为_____。
(10)intJ;(20)intSum1=0,Sum2=0;(30)ForJ=1to4Step1(40){Sum1=Sum1+M[J][J];(50)Sum2=Sum2+M[5-J][5-J];}答案:66,6610.已知函数Fact的程序如下,Fact(4)的值为_____。
数据结构实验报告八皇后问题
2007级数据结构实验报告实验名称:实验二——栈和队列学生姓名:班级:班内序号:学号:日期:2008年11月18日1.实验要求通过选择下面五个题目之一进行实现,掌握如下内容:➢进一步掌握指针、模板类、异常处理的使用➢掌握栈的操作的实现方法➢掌握队列的操作的实现方法➢学习使用栈解决实际问题的能力➢学习使用队列解决实际问题的能力利用栈结构实现八皇后问题。
八皇后问题19世纪著名的数学家高斯于1850年提出的。
他的问题是:在8*8的棋盘上放置8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列、同一斜线上。
请设计算法打印所有可能的摆放方法。
提示:1、可以使用递归或非递归两种方法实现2、实现一个关键算法:判断任意两个皇后是否在同一行、同一列和同一斜线上2. 程序分析2.1 存储结构采用栈存储,其结构图如下:2.2 关键算法分析函数原型: bool check(int i);2.2.1.1.1自然语言:检测至第i行所摆放的第i个皇后是否和之前的i-1个皇后发生冲突。
如是,则返回0;反之,则当前布局合法,返回1。
判断两个皇后是否相互攻击的准则是:若两个皇后处于同一行,或处于同一列,或处于同一斜线,就能相互攻击。
基于如上准则,函数check( )的工作原理是:考虑到数组的每个元素分别代表不同行的皇后,即每行只放置了一个皇后,所以不必考虑“同处一行相互攻击”的情形;对于同处一列,则语句:if(queen[s]==queen[t])就能判断出不同行的两个棋子是否同处一列;对于处于同一斜线的这种情况,首先,我们看出国际象棋的棋盘是一个八行八列的正方形。
因此我们可将棋盘想象为数学上的笛卡尔平面坐标系,两颗棋子想象为平面上的两个点,就很容易发现,为保证两颗棋子不处于同一斜线,只要过这两个点的直线斜率不为1或-1,就能达到要求。
由此可使用下列语句:if( abs(t-s) == abs(queen[s]-queen[t]) )其中t和s分别代表不同行的两个皇后,即数组queen[8]里不同下标的两个元素。
八皇后问题数据结构课程设计报告
数据结构课程设计报告八皇后问题设计任务书指导教师(签章):年月日摘要:众所周知的八皇后问题是一个非常古老的问题,具体如下:在8*8的国际象棋棋盘上放置了八个皇后,要求没有一个皇后能吃掉另一个皇后,即任意两个皇后都不处于棋盘的同一行、同一列或同一对角线上,这是做出这个课题的基础。
要求编写实现八皇后问题的递归解法或非递归解法,对于任意给定的一个初始位置,输出八皇后问题的一个布局。
本次设计旨在学习各种算法,训练对基础知识和基本方法的综合运用及变通能力,增强对算法的理解能力,提高软件设计能力。
在实践中培养独立分析问题和解决问题的作风和能力。
要求熟练运用C++语言、基本算法的基础知识,独立编制一个具有中等难度的、解决实际应用问题的应用程序。
通过对题意的分析与计算,用递归法回溯法及枚举法解决八皇后是比较适合的。
递归是一种比较简单的且比较古老的算法。
回溯法是递归法的升华,在用来求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索遍才结束。
而枚举法,更是一种基础易懂简洁的方法。
把它们综合起来,就构成了今天的算法。
不论用什么法做这个课题,重要的就是先搞清楚哪个位置是合法的放皇后的位置,哪个不能,要先判断,后放置。
关键词:八皇后;递归法;回溯法;数组;枚举法…….目录1 课题综述…………………………………………………………………………………1.1 八皇后问题概述---------------------------------------------------1.2 预期目标---------------------------------------------------------1.3 八皇后问题课题要求-----------------------------------------------1.4 面对的问题-------------------------------------------------------2 需求分析…………………………………………………………………………………2.1 涉及到的知识基础--------------------------------------------------2.2 总体方案----------------------------------------------------------3 模块及算法设计……………………………………………………………………………………3.1 算法描述----------------------------------------------------------3.2.详细流程图-------------------------------------------------------4.代码编写…………………………………………………………………………5 程序调试分析……………………………………………………………………………………6 运行与测试……………………………………………………………………………………总结…………………………………………………………………………1 课题综述1.1 八皇后问题概述八皇后问题是一个古老而著名的问题。
用CSP(约束满足问题)方法解决八皇后问题
conflictNum++; } } //检查同一列是否有冲突 j=column; for(i=0;i<N;i++) { if((i!=row)&&(queenBoard[i][j]==QUEEN)) {
//如果同一列其它位置有皇后,记录冲突点数 conflictNum++; } } //检查'\'斜线是否有冲突 if(row>column) { i=row-column; j=0; } else { i=0; j=column-row; } for(;(i<N)&&(j<N);i++,j++ ) { if((i!=row)&&(queenBoard[i][j]==QUEEN)) { //如果'\'斜线其它位置有皇后,记录冲突点数 conflictNum++; } } //检查'/'斜线是否有冲突 if((row+column)<N) { i=row+column; j=0; } else { i=N-1; j=row+column-N+1; } for(;(i>=0)&&(j<=N);i --,j++)
该列的每一行中与该位置有冲突的皇后数,选取冲突数最小的位置作为新的该列的皇后位置, 并记录下该列被放置皇后的信息,记录被放置皇后信息的目的是为了避免算法陷入死循环。
为了更清楚地说明该算法,假设算法某一步搜索到的状态如下:
此时按照最小冲突算法,第二列、第六列、第七列和第八列的皇后 有冲突,则当计算第六列 的每一行的与该位置有冲突的皇后数时,结果如下:
八皇后问题的解决完整
八皇后问题的解决完整 Standardization of sany group #QS8QHH-HHGX8Q8-GNHHJ8-HHMHGN#淮阴工学院数据结构课程设计报告设计题目:八皇后2008 年 6 月 25 日设计任务书摘要:八皇后问题要求在一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击.按照国际象棋的规则,一个皇后可以攻击与之处在同一行或同一列或同一斜线上的其他任何棋子.因此,八皇后问题等于要求八个皇后中的任意两个不能被放在同一行或同一列或同一斜线上。
而本课程设计本人的目的也是通过用c++语言平台将一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击的92种结构予以实现.使用递归方法最终将其问题变得一目了然,更加易懂。
关键词:八皇后 ; c++ ; 递归法目录.1. 课题综述1. 1课题的来源及意义八皇后问题是一个古老而着名的问题,该问题是十九世纪着名的数学家高斯1850年提出的。
在国际象棋中,皇后是最有权利的一个棋子;只要别的棋子在它的同一行或同一列或同一斜线(正斜线或反斜线)上时,它就能把对方棋子吃掉。
所以高斯提出了一个问题:在8*8的格的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后都不能处于同一列、同一行、或同一条斜线上面,问共有多少种解法。
到了现代,随着计算机技术的飞速发展,这一古老而有趣的数学游戏问题也自然而然的被搬到了计算机上。
运用所学计算机知识来试着解决这个问题是个锻炼和提高我自己编程能力和独立解决问题能力的好机会,可以使我增强信心,为我以后的编程开个好头,故我选择了这个有趣的课题。
1. 2 面对的问题1)解决冲突问题:这个问题包括了行,列,两条对角线;列:规定每一列放一个皇后,不会造成列上的冲突;行:当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I为下标的标记置为被占领状态;2)使用数据结构的知识,用递归法解决问题。
八皇后问题实验报告
软件工程上机报告实验名称:八皇后问题图形界面求解姓名:郭恂学号:2011011435班级:11级数学班中国石油大学(北京)计算机科学与技术系一、试验程序截图:点击显示下一组解即可显示下一组解:同样的,如果点击上一组解即可显示上一组解。
若在第1组解时点击显示上一组解会弹出报错提示框。
同样,若在第92组解点击显示下一组解也会弹出报错提示框:二、程序代码程序使用Java语言编写,编写环境为jdk1.6.0_18。
使用编程开发环境eclipse.exe编写。
本程序创建了两个类,两个类在同一个工程中。
其中Queen类的作用仅仅用来保存八皇后问题计算结果的数据,便于画图时使用。
本程序大概由两部分组成,第一部分是解八皇后问题,第二部分是画图。
程序源代码为:类1:public class Queen{public int[] x=new int[8];public int[] y=new int[8];public String name;}类2:import javax.swing.*;import java.awt.event.*;import java.awt.*;import javax.swing.JOptionPane;public class bahuanghou extends JFrame implements ActionListener {//JLabel[] l;int number=0; //当前显示的解的编号int sum=0; //所有解得数量JLabel l2;JButton b1,b2; //b1为显示下一组解得按钮,b2为显示上一组解得按钮。
Queen[] q=new Queen[128]; //得到的解储存在Queen类的数组里面。
private Image bomb1=Toolkit.getDefaultToolkit().getImage("D:\\qizi1.JPG"); //黑格棋子为bomb1private Image bomb2=Toolkit.getDefaultToolkit().getImage("D:\\qizi2.JPG"); //白格棋子为bomb2public bahuanghou() //构造方法,初始化窗口。
八皇后问题 C++程序
八皇后问题下面本人所用的就是回溯的思想来解决八皇后问题的。
8行8列的棋盘上放八个皇后,且不相互攻击,即每一列每一行只能放一个皇后,且必须要放一个皇后。
采用循环回溯的方法,现在第一列放一个皇后,然后再在第二列放一个皇后,以此类推,直到八个皇后都放完为止。
每个for循环语句都有一条continue语句,用来继续跳出本次循环。
// Queen.cpp(main)#include <iostream>using std::cout;using std::endl;#include <iomanip>using std::setw;#include <cmath>// using std::abs;int main(){static int queen[9];static int count=1;for (int A=1;A<=8;A++){for (int B=1;B<=8;B++){if (B==A){continue;}queen[2]=B;if ((abs(B-A))==1){continue;}queen[1]=A;for (int C=1;C<=8;C++){if ((C==B) || (C==A)){continue;}if ((abs(C-B)==1)||(abs(C-A)==2)) {continue;}queen[3]=C;for (int D=1;D<=8;D++){if ((D==C)||(D==B)||(D==A)){continue;}if ((abs(D-C)==1)||(abs(D-B)==2)||(abs(D-A)==3)){continue;}queen[4]=D;for (int E=1;E<=8;E++){if ((E==D)||(E==C)||(E==B)||(E==A)){continue;}if((abs(E-D)==1)||(abs(E-C)==2)||(abs(E-B)==3)||(abs(E-A)==4)){continue;}queen[5]=E;for (int F=1;F<=8;F++){if ((F==E)||(F==D)||(F==C)||(F==B)||(F==A)){continue;}if((abs(F-E)==1)||(abs(F-D)==2)||(abs(F-C)==3)||(abs(F-B)==4)||(abs(F-A)==5)){continue;}queen[6]=F;for (int G=1;G<=8;G++){if((G==F)||(G==E)||(G==D)||(G==C)||(G==B)||(G==A)){continue;}if((abs(G-F)==1)||(abs(G-E)==2)||(abs(G-D)==3)||(abs(G-C)==4)||(abs(G-B)==5)||(abs(G-A)==6)){continue;}queen[7]=G;for (int I=1;I<=8;I++){if((I==G)||(I==F)||(I==E)||(I==D)||(I==C)||(I==B)||(I==A)){continue;}if((abs(I-G)==1)||(abs(I-F)==2)||(abs(I-E)==3)||(abs(I-D)==4)||(abs(I-C)==5)||(abs(I-B)==6)||(abs(I-A)==7)){continue;}queen[8]=I;cout<<" NO."<<setw(2)<<count<<": ";for (int i=1;i<=8;i++){cout<<setw(3)<<queen[i];}count++;cout<<endl;}}}}}}}}return 0;}运行结果如下:。
第五组回溯算法(硬币分配问题)
第五组回溯算法(硬币分配问题)实训⼀硬币分法问题的回溯算法与实现⼀、设计⽬的1)掌握硬币分法问题的回溯算法;2)进⼀步掌握回溯算法的基本思想和算法设计⽅法;⼆、设计内容1.任务描述1)算法简介回溯算法也叫试探法,它是⼀种系统地搜索问题的解的⽅法。
回溯算法的基本思想是:从⼀条路往前⾛,能进则进,不能进则退回来,换⼀条路再试。
⼋皇后问题就是回溯算法的典型,第⼀步按照顺序放⼀个皇后,然后第⼆步符合要求放第2个皇后,如果没有符合位置符合要求,那么就要改变第⼀个皇后的位置,重新放第2个皇后的位置,直到找到符合条件的位置就可以了回溯在迷宫搜索中使⽤很常见,就是这条路⾛不通,然后返回前⼀个路⼝,继续下⼀条路。
回溯算法说⽩了就是穷举法。
不过回溯算法使⽤剪枝函数,剪去⼀些不可能到达最终状态(即答案状态)的节点,从⽽减少状态空间树节点的⽣成。
回溯法是⼀个既带有系统性⼜带有跳跃性的的搜索算法。
它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。
算法搜索⾄解空间树的任⼀结点时,总是先判断该结点是否肯定不包含问题的解。
如果肯定不包含,则跳过对以该结点为根的⼦树的系统搜索,逐层向其祖先结点回溯。
否则,进⼊该⼦树,继续按深度优先的策略进⾏搜索。
回溯法在⽤来求问题的所有解时,要回溯到根,且根结点的所有⼦树都已被搜索遍才结束。
⽽回溯法在⽤来求问题的任⼀解时,只要搜索到问题的⼀个解就可以结束。
这种以深度优先的⽅式系统地搜索问题的解的算法称为回溯法,它适⽤于解⼀些组合数较⼤的问题。
2)硬币分法问题简介假设有5种硬币:50美分,25美分,10美分,5美分和1美分。
我们给⼀定数量的资⾦,要求这些硬币作出变化。
例如,如果我们有11美分,那么我们可以给出⼀个10美分的硬币和⼀个1美分硬币,或者2个 5美分的硬币和⼀个1美分硬币,或者⼀个5美分硬币和6个 1美分的硬币,或11个1美分硬币。
因此,有四个使上述11美分硬币的变化⽅式。
C语言回溯法解八皇后问题(八皇后算法)
C语⾔回溯法解⼋皇后问题(⼋皇后算法)⼋皇后问题(N皇后问题)的回溯法求解⼀、问题描述在⼀个国际象棋棋盘上放置⼋个皇后,使得任何两个皇后之间不相互攻击,求出所有的布棋⽅法,并推⼴到N皇后情况。
⼆、参考资料啥⽂字都不⽤看,B站上有个⾮常详细的动画视频解说,上链接三、源代码#include<iostream>#include<vector>#include<string>using namespace std;void put_queen(int x, int y, vector<vector<int>>&attack){//实现在(x,y)放置皇后,对attack数组更新,xy表⽰放置皇后的坐标,attack表⽰是否可以放置皇后//⽅向数组,⽅便后⾯对8个⽅向进⾏标记static const int dx[] = { -1,-1,-1,0,0,1,1,1 };static const int dy[] = { -1,0,1,-1,1,-1,0,1 };attack[x][y] = 1;//将皇后位置标记为1//通过两层for循环,将该皇后可能攻击到的位置标记for (int i = 1; i < attack.size(); i++)//从皇后位置向1到n-1个距离延伸{for (int j = 0; j < 8; j++)//遍历8个⽅向{int nx = x + i * dx[j];//⽣成的新位置⾏int ny = y + i * dy[j];//⽣成的新位置列//在棋盘范围内if (nx >= 0 && nx < attack.size() && ny >= 0 && ny < attack.size())attack[nx][ny] = 1;//标记为1}}}//回溯算法//k表⽰当前处理的⾏//n表⽰n皇后问题//queen存储皇后的位置//attack标记皇后的攻击范围//solve存储N皇后的全部解法void backtrack(int k, int n, vector<string>& queen,vector<vector<int>>& attack,vector<vector<string>>& solve){if (k == n)//找到⼀组解{solve.push_back(queen);//将结果queen存储⾄solvereturn;}//遍历0⾄n-1列,在循环中,回溯试探皇后可放置的位置for (int i = 0; i < n; i++){if (attack[k][i] == 0)//判断当前k⾏第i列是否可以放置皇后{vector<vector<int>> tmp = attack;//备份attack数组queen[k][i] = 'Q';//标记该位置为Qput_queen(k, i, attack);//更新attack数组backtrack(k + 1, n, queen, attack, solve);//递归试探k+1⾏的皇后的位置attack = tmp;//恢复attack数组queen[k][i] = '.';//恢复queen数组}}}vector<vector<string>>solveNQueens(int n){//string存储具体的摆放位置,<vector<string>>存放⼀种解法,⼆维vector存放全部解法vector<vector<string>>solve;//存储最后结果vector<vector<int>>attack;//标记皇后的攻击位vector<string>queen;//保存皇后位置//使⽤循环初始化attack和queen数组for (int i = 0; i < n; i++){attack.push_back((vector<int>()));for (int j = 0; j < n; j++){attack[i].push_back(0);}queen.push_back("");queen[i].append(n, '.');}backtrack(0, n, queen, attack, solve);return solve;//返回结果数组}int main(){//int num;//cin >> num;//输⼊皇后数初始化attack数组//vector<vector<int>> attack(num,vector<int>(num, 0));初始化queen数组//string s;//for (int i = 0; i < num; i++)s += '.';//vector<string> queen(num, s);int n;cin >> n;vector<vector<string>>result;result = solveNQueens(n);cout << n << "皇后共有" << result.size() << "种解法" << endl;for (int i = 0; i < result.size(); i++){cout << "解法" << i + 1 << ":" << endl;for (int j = 0; j < result[i].size(); j++){cout << result[i][j] << endl;}cout << endl;}system("pause");return 0;}四、测试结果四皇后⼋皇后到此这篇关于C语⾔回溯法解⼋皇后问题的⽂章就介绍到这了。
基本算法4-回溯法-N皇后问题
1
x1=1 2
x2= 2 3 kill
1
1 2
回溯到结点2生成结点8, 路径变为(1, 3), 则结点8成为E-结点, 它生成结点9和结点11都会被杀死(即它的儿子表示不可能导 x1=1 致答案的棋盘格局), 所以结点8也被杀死, 应回溯.
1
1
1
2
2
3
x2= 2 x2= 3 3 kill 8 x3=2 9 kill x3=4 11 kill
借书问题 [问题描述]
学校放暑假时,信息学辅导教师有n本书要分给参加培训的n个学生。如:A, B,C,D,E共5本书要分给参加培训的张、刘、王、李、孙5位学生,每人只能选 1本。教师事先让每个人将自己喜爱的书填写在如下的表中,然后根据他们填写的 表来分配书本,希望设计一个程序帮助教师求出可能的分配方案,使每个学生都满 意。 A 张 王 刘 孙 李 Y Y Y Y Y Y Y B C Y D Y E
● ●
……
● ● ● ● ● ● ● ●
……
……
●
●
●
●
●
● ● ● ●
●
●
● ●
●
● ●
●
● ●
● ● ● ●
● ● ● ●
● ● ● ●
● ● ● ● ●
● ● ●
•搜索解空间,剪枝:
– (1) 从空棋盘起,逐行放置棋子。
– (2) 每在一个布局中放下一个棋子,即推演到一 个新的布局。 – (3) 如果当前行上没有可合法放置棋子的位置, 则回溯到上一行,重新布放上一行的棋子。
61 2
64
3
16
3
20
4
22
1
25
C语言算法大全
37.Algorithm Gossip: 快速排序法(一).................................................................................... 92 38.Algorithm Gossip: 快速排序法(二).................................................................................... 94 39.Algorithm Gossip: 快速排序法(三).................................................................................... 96 40.Algorithm Gossip: 合并排序法................................................................................................ 99 41.Algorithm Gossip: 基数排序法.............................................................................................. 102 42.Algorithm Gossip: 循序搜寻法(使用卫兵)...................................................................... 104 43.Algorithm Gossip: 二分搜寻法(搜寻原则的代表).......................................................... 106 44.Algorithm Gossip: 插补搜寻法.............................................................................................. 109 45.Algorithm Gossip: 费氏搜寻法.............................................................................................. 112 46.Algorithm Gossip: 稀疏矩阵.................................................................................................. 116 47.Algorithm Gossip: 多维矩阵转一维矩阵.............................................................................. 118 48.Algorithm Gossip: 上三角、下三角、对称矩阵.................................................................. 120 49.Algorithm Gossip: 奇数魔方阵.............................................................................................. 122 50.Algorithm Gossip: 4N 魔方阵................................................................................................ 124 51.Algorithm Gossip: 2(2N+1) 魔方阵....................................................................................... 126
四皇后实验报告
篇一:四皇后问题实验报告人工智能——四皇后问题一、问题描述四皇后问题一个4×4国际象棋盘,依次放入四个皇后,条件:每行、每列及对角线上只允许出现一枚棋子。
设:data=l(表) x∈l x ∈﹛i j﹜1≤ i, j ≤4 其中:i j 表示棋子所在行列如:24 表示第二行第四列有一枚棋子∵棋盘上可放入的棋子数为0 ~ 4 个∴l表中的元素数为0 ~ 4 个,即 length l = 0 ~ 4 ,如图a ﹛12,24,31,43 ﹜定义规则: if1≤ i ≤4andlength data = i -1thenappend(data( ij )) 1≤ j ≤4①对于任一行i , 1≤ j ≤4 表明每行有四条规则。
比如第一行:r11,r12,r13,r14②棋盘中共有四行,所以共有16条规则。
即: r11,r12,r13,r14r21,r22,r23,r24r31,r32,r33,r34r41,r42,r43,r44③ 16条规则中,哪些是当前可用规则,取决于data的长度,即:data中的元素个数。
换言之,每次只能将一个棋子放在当前行的下一行。
二、回溯法搜索策略图讨论:上述算法产生22次回溯,原因在于规则自然顺序排列,没考虑任何智能因素。
改进算法定义对角线函数:diag(i,j):过ij点最长的对角线长度值。
规定:①如果: diag(i,k) ≤ diag(i,j) 则规则排列次序为: rik, rij 同一行四条规则中,对角线函数值小的排在前面②如果:diag(i,k) = diag(i,j) 则规则排列次序为: rij ,rikj < k 对角线长度相等的规则按照字母排列顺序排序讨论:①利用局部知识排列规则是有效的。
② backtrack算法对重复出现的状态没有判断,所以可能造成出现死循环。
③没有对搜索深度加以限制,可能造成搜索代价太大。
三、算法描述回溯法——在约束条件下先序遍历,并在遍历过程中剪去那些不满足条件的分支。
回溯算法原理和几个常用的算法实例
回溯算法原理和几个常用的算法实例回溯算法是一种通过不断尝试和回退的方式来进行问题求解的算法。
它的基本思想是在过程中,当发现当前的选择并不符合要求时,就进行回退,尝试其他的选择,直到找到符合要求的解或者遍历完所有可能的选择。
回溯算法通常用于问题求解中的和排列组合问题,比如求解八皇后问题、0-1背包问题、数独等。
下面将介绍几个常用的回溯算法实例。
1.八皇后问题:八皇后问题是指在一个8×8的国际象棋棋盘上,放置八个皇后,使得任意两个皇后都不在同一行、同一列或同一斜线上。
可以通过递归的方式依次尝试每一行的位置,并判断当前位置是否满足条件。
如果满足条件,则进入下一行尝试;否则回溯到上一行,并尝试其他的位置,直到找到解或遍历完所有的可能。
2.0-1背包问题:0-1背包问题是指在给定一组物品和一个容量为C的背包,每个物品都有自己的重量和价值,求解在不超过背包容量时,如何选择物品使得背包中物品的总价值最大。
可以通过递归的方式依次考察每个物品,并判断是否选择当前物品放入背包。
如果放入当前物品,则背包容量减小,继续递归考察下一个物品;如果不放入当前物品,则直接递归考察下一个物品。
直到遍历完所有物品或背包容量为0时,返回当前总价值。
3.数独问题:数独是一种通过填充数字的方式使得每一行、每一列和每一个九宫格内的数字都满足一定条件的谜题。
可以通过递归的方式依次尝试填充每一个空格,并判断当前填充是否符合条件。
如果符合条件,则继续递归填充下一个空格;如果不符合条件,则回溯到上一个空格,并尝试其他的数字,直到找到解或遍历完所有的可能。
回溯算法的时间复杂度一般较高,通常为指数级别。
因此,在实际应用中,可以结合剪枝等优化策略来提高算法的效率。
此外,回溯算法也可以通过非递归的方式进行实现,使用栈来存储当前的状态,从而避免递归带来的额外开销。
总之,回溯算法是一种非常有效的问题求解方法,通过不断尝试和回退,可以在复杂的空间中找到符合要求的解。
八皇后问题详细的解法
1
1八皇后问题背景 2盲目的枚举算法 3加约束的枚举算法 4回溯法及基本思想 5 回溯法应用 6八皇后问题的递归回溯算法 7八皇后问题的非递归回溯算法
2
【背景】 八皇后问题是一个以国际象棋为背
景的问题: 如何能够在 8×8 的国际象棋棋盘上
放置八个皇后,使得任何一个皇后都 无法直接吃掉其他的皇后?为了达到 此目的,任两个皇后都不能处于同一 条横行、纵行或斜线上。
}
}
23
20
2 回溯法应用-算法框架-递归算法框架
int a[n]; Queens(int k) { if (k>n) 即表示最后一个皇后摆放完毕,输出结果;
else for(i=下界 ; i<=上界; i++) //枚举K个皇后所有可能的路径 {依次从列顶端开始搜索,一直到列底端,直到找到合适位置,如
果未找到,自动返回上层递归
的,能避免不必要搜索的穷举式搜索法。这种方法适 用于解一些组合数相当大的问题。 回溯法在问题的解空间树中,按深度优先策略,从根 结点出发搜索解空间树。算法搜索至解空间树的任意 一点时,先判断该结点是否包含问题的解。如果肯定 不包含,则跳过对该结点为根的子树的搜索,逐层向 其祖先结点回溯;否则,进入该子树,继续按深度优 先策略搜索。
for(a[8]=1;a[8]<=8;a[8]++) 此算法可读性很好,
{if (check(a,8)==0)continue; 体现了“回溯”。但
else for(i=1;i<=8;i++) 它只能解决八皇后问
print(a[i]); }
题,而不能解决任意
}}}}}}}
人工智能实验报告_八皇后问题
八皇后问题八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。
该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
基本思想:在open表中保留已生成而未考察的结点,并用启发函数h(x)对它们全部进行估价,从中选出最优结点进行扩展,而不管这个结点出现在搜索树的什么地方。
(1)把初始结点S0放入open表中,计算h(S0);(2)若open表为空,则搜索失败,EXIT;(3)移出open表中第一个结点N放入closed表中,并冠以序号n(4)若目标结点Sg=N则搜索成功,EXIT(5)若N不可扩展,则转步骤(2);(6)扩展N,计算每个子结点x的函数值h(x),并将所有子结点配以指向N的返回指针后放入open表中,再对open表中的所有子结点按其函数值大小以升序排序,转步骤2;//采用启发式修补解N皇后问题#include<time.h>#include <iostream>//采用启发式修补解N皇后问题#include<time.h>#include <iostream>using space std;void shuffle(int Queen[],const int n)...{//随机取得各行的初始皇后位置,以Queen[i]表示第i行的皇后位置for(int i=0;i<n;i )Queen[i]=abs(rand())%n;}int collision(int Queen[],const int row,const int column,const int n)...{ //计算每个位置的冲突值int bug=0;for(int i=0;i<n;i )...{if ((i!=row)&&(Queen[i]==column||(Queen[i]-column)==(i-row)||(Queen[i]-column)==(row-i)))//同列,同对角线的情况bug ;}return bug;}void show(int Queen[],const int n)...{//打印皇后图cout<<"╭";for(int k=0;k<n-1;k )cout<<"─┬";cout<<"─╮"<<endl;for(int i=0;i<n-1;i )...{cout<<"│";for(int j=0;j<n;j )cout<<((j==Queen[i])? "凤" :" ")<<"│";//有皇后的位置用"凤"cout<<endl;cout<<"├";for(j=0;j<n-1;j )cout<<"─┼";cout<<"─┤"<<endl;}cout<<"│";for(int j=0;j<n;j )cout<<((j==Queen[n-1])? "凤" :" ")<<"│";//有皇后的位置用,没有的用_ cout<<endl;cout<<"╰";for(k=0;k<n-1;k )cout<<"─┴";cout<<"─╯"<<endl;cout<<endl;}int repair(int Queen[],const int n)...{ //启发式修补int max=-1;//标志行行之间冲突数int minbug=n;int count=0;while(max!=0&&count<=100)...{max=0;for(int i=0;i<n;i )...{minbug=collision(Queen,i,Queen[i],n);//取得当前的冲突数,不断优化int temp=Queen[i];for(int j=0;j<n;j )...{int bug=collision(Queen,i,j,n);if(bug<=minbug&&j!=temp)...{ //保持皇后在等冲突的情况下不断变更位置,有利于后面行的优化minbug=bug;Queen[i]=j;}}if (minbug>max)max=minbug;}show(Queen,n);count ;}return count;}void main()...{int n=-1;int step=0;cout<<"Welcome to N Queen Settlement"<<endl;cout<<"Input N (you would better input a interge minor to 15):"<<endl;cin>>n;if(n<=0)...{cout<<"Illegal Input!"<<endl;return;}int* Queen=new int[n];srand(time(NULL));//取得随机种子shuffle(Queen,n);cout<<"The oringinal state:"<<endl;show(Queen,n);step=repair(Queen,n);if(step>100)...{cout<<"Could find solution within 100 steps,Try again!"<<endl;return;}cout<<"After "<<step 1<<" steps"<<endl;cout<<"The goal state arrives!"<<endl;}。
C语言八皇后问题
C语言八皇后问题C语言八皇后问题八皇后问题是一个古老而著名的问题。
该问题是19世纪著名的数学家高斯1850年提出:在一个8*8国际象棋盘上,有8个皇后,每个皇后占一格;要求皇后之间不会出现相互“攻击”的现象,即不能有两个皇后处在同一行、同一列或同一对角线上。
问共有多少种不同的方法?回溯算法也叫试探法,它是一种搜索问题的解的方法。
冋溯算法的基本思想是在一个包含所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。
算法搜索至解空间树的任意结点时,总是先判断该结点是否肯定不包含问题的解。
如果肯定不包含,则跳过对以该结点为根的子树的系统搜索,逐层向其祖先结点回溯。
否则,进入该子树,继续按深度优先的策略进行搜索。
回溯法在用来求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索遍才结束。
八皇后问题有很多中解法,其中使用回溯法进行求解是其中一种。
而回溯发也是最直接的一种解法,也较容易理解。
八皇后问题的回溯法算法,可以采用一维数组来进行处理。
数组的下标i表示棋盘上的第i列,a[i]的值表示皇后在第i列所放的位置。
例如,a[1]=5,表示在棋盘的第例的第五行放一个皇后。
程序中首先假定a[1]=1,表示第一个皇后放在棋盘的第一列的第一行的位置上,然后试探第二列中皇后可能的位置,找到合适的位置后,再处理后续的各列,这样通过各列的反复试探,可以最终找出皇后的全部摆放方法。
八皇后问题可以使用回溯法进行求解,程序实现如下:#include#define Queens 8 //定义结果数组的大小,也就是皇后的数目int a[Queens+1]; //八皇后问题的皇后所在的行列位置,从1幵始算起,所以加1int main(){int i, k, flag, not_finish=1, count=0;//正在处理的.元素下标,表示前i-1个元素已符合要求,正在处理第i个元素i=1;a[1]=1; //为数组的第一个元素赋初值printf("The possible configuration of 8 queens are:\n");while(not_finish){ //not_finish=l:处理尚未结束while(not_finish && i<=Queens){ //处理尚未结束且还没处理到第Queens个元素for(flag=1,k=1; flag && kif(a[k]==a[i])flag=0;for (k=1; flag&&kif( (a[i]==a[k]-(k-i)) || (a[i]==a[k]+(k-i)) )flag=0;if(!flag){ //若存在矛盾不满足要求,需要重新设置第i个元素if(a[i]==a[i-1]){ //若a[i]的值已经经过一圈追上a[i-1]的值i--; //退回一步,重新试探处理前一个元素if(i>1 && a[i]==Queens)a[i]=1; //当a[i]为Queens时将a[i]的值置1elseif(i==1 && a[i]==Queens)not_finish=0; //当第一位的值达到Queens时结束elsea[i]++; //将a[il的值取下一个值}else if(a[i] == Queens)a[i]=1;elsea[i]++; //将a[i]的值取下一个值}else if(++i<=Queens)if(a[i-1] == Queens )a[i]=1; //若前一个元素的值为Queens则a[i]=lelsea[i] = a[i-1]+1; //否则元素的值为前一个元素的下一个值}if(not_finish){++count;printf((count-1)%3 ? "\t[%2d]:" : "\n[%2d]:", count);for(k=1; k<=Queens; k++) //输出结果printf(" %d", a[k]);if(a[Queens-1]a[Queens-1]++; //修改倒数第二位的值elsea[Queens-1]=1;i=Queens -1; //开始寻找下一个满足条件的解}}}输出结果:The possible configuration of 8 queens are:[ 1]: 1 5 8 6 3 7 2 4 [ 2]: 1 6 8 3 7 4 2 5 [ 3]: 1 7 4 6 8 2 5 3 [ 4]: 1 7 5 8 2 4 6 3 [ 5]: 2 4 6 8 3 1 7 5 [ 6]: 2 5 7 1 3 8 6 4 [ 7]: 2 5 7 4 1 8 6 3 [ 8]: 2 6 8 3 1 4 7 5 [ 9]: 2 6 1 7 4 8 3 5 [10]: 2 7 3 6 8 5 1 4 [11]: 2 7 5 8 1 4 6 3 [12]: 2 8 6 1 3 5 7 4 [13]: 3 5 7 1 4 2 8 6 [14]: 3 5 8 4 1 7 2 6 [15]: 3 5 2 8 1 7 4 6 [16]: 3 5 2 8 6 4 7 1 [17]: 3 6 8 1 4 7 5 2 [18]: 3 6 8 1 5 7 2 4 [19]: 3 6 8 2 4 1 7 5 [20]: 3 6 2 5 8 1 7 4 [21]: 3 6 2 7 1 4 8 5 [22]: 3 6 2 7 5 1 8 4 [23]: 3 6 4 1 8 5 7 2 [24]: 3 6 4 2 8 5 7 1 [25]: 3 7 2 8 5 1 4 6 [26]: 3 7 2 8 6 4 1 5 [27]: 3 8 4 7 1 6 2 5 [28]: 3 1 7 5 8 2 4 6 [29]: 4 6 8 2 7 1 3 5 [30]: 4 6 8 3 1 7 5 2[31]: 4 6 1 5 2 8 3 7 [32]: 4 7 1 8 5 2 6 3 [33]: 4 7 3 8 2 5 1 6 [34]: 4 7 5 2 6 1 3 8 [35]: 4 7 5 3 1 6 8 2 [36]: 4 8 1 3 6 2 7 5 [37]: 4 8 1 5 7 2 6 3 [38]: 4 8 5 3 1 7 2 6 [39]: 4 1 5 8 2 7 3 6 [40]: 4 1 5 8 6 3 7 2 [41]: 4 2 5 8 6 1 3 7 [42]: 4 2 7 3 6 8 1 5 [43]: 4 2 7 3 6 8 5 1 [44]: 4 2 7 5 1 8 6 3 [45]: 4 2 8 5 7 1 3 6 [46]: 4 2 8 6 1 3 5 7 [47]: 5 7 1 3 8 6 4 2 [48]: 5 7 1 4 2 8 6 3 [49]: 5 7 2 4 8 1 3 6 [50]: 5 7 2 6 3 1 4 8 [51]: 5 7 2 6 3 1 8 4 [52]: 5 7 4 1 3 8 6 2 [53]: 5 8 4 1 3 6 2 7 [54]: 5 8 4 1 7 2 6 3 [55]: 5 1 4 6 8 2 7 3 [56]: 5 1 8 4 2 7 3 6 [57]: 5 1 8 6 3 7 2 4 [58]: 5 2 4 6 8 3 1 7 [59]: 5 2 4 7 3 8 6 1 [60]: 5 2 6 1 7 4 8 3 [61]: 5 2 8 1 4 7 3 6 [62]: 5 3 8 4 7 1 6 2 [63]: 5 3 1 6 8 2 4 7 [64]: 5 3 1 7 2 8 6 4 [65]: 6 8 2 4 1 7 5 3 [66]: 6 1 5 2 8 3 7 4 [67]: 6 2 7 1 3 5 8 4 [68]: 6 2 7 1 4 8 5 3 [69]: 6 3 5 7 1 4 2 8 [70]: 6 3 5 8 1 4 2 7 [71]: 6 3 7 2 4 8 1 5 [72]: 6 3 7 2 8 5 1 4 [73]: 6 3 7 4 1 8 2 5 [74]: 6 3 1 7 5 8 2 4 [75]: 6 3 1 8 4 2 7 5 [76]: 6 3 1 8 5 2 4 7 [77]: 6 4 7 1 3 5 2 8 [78]: 6 4 7 1 8 2 5 3 [79]: 6 4 1 5 8 2 7 3 [80]: 6 4 2 8 5 7 1 3 [81]: 7 1 3 8 6 4 2 5 [82]: 7 2 4 1 8 5 3 6 [83]: 7 2 6 3 1 4 8 5 [84]: 7 3 8 2 5 1 6 4 [85]: 7 3 1 6 8 5 2 4 [86]: 7 4 2 5 8 1 3 6 [87]: 7 4 2 8 6 1 3 5 [88]: 7 5 3 1 6 8 2 4 [89]: 8 2 4 1 7 5 3 6 [90]: 8 2 5 3 1 7 4 6 [91]: 8 3 1 6 2 5 7 4 [92]: 8 4 1 3 6 2 7 5。
数据结构与算法专题实验实验报告-八皇后-背包问题的求解-农夫过河
八皇后问题1.问题描述设在初始状态下在国际象棋的棋盘上没有任何棋子(这里的棋子指皇后棋子)。
然后顺序在第1行,第2行……第8行上布放棋子。
在每一行中共有8个可选择的位置,但在任一时刻棋盘的合法布局都必须满足3个限制条件(1)任意两个棋子不得放在同一行(2)任意两个棋子不得放在同一列上(3)任意棋子不得放在同一正斜线和反斜线上。
2.基本要求编写求解并输出此问题的一个合法布局的程序。
3、实现提示:在第i行布放棋子时,从第1列到第8列逐列考察。
当在第i行第j列布放棋子时,需要考察布放棋子后在行方向、列方向、正斜线和反斜线方向上的布局状态是否合法,若该棋子布放合法,再递归求解在第i+1行布放棋子;若该棋子布放不合法,移去这个棋子,恢复布放该棋子前的状态,然后再试探在第i行第j+1列布放棋子。
4 程序代码#include<iostream.h>#include<stdio.h>static char Queen[8][8];static int a[8];static int b[15];static int c[15];static int QueenNum=0;//记录总的棋盘状态数void qu(int i);//参数i代表行int main(){int Line,Column;//棋盘初始化,空格为*,放置皇后的地方为@ for(Line=0;Line<8;Line++){a[Line]=0; //列标记初始化,表示无列冲突for(Column=0;Column<8;Column++)Queen[Line][Column]='*';}//主、从对角线标记初始化,表示没有冲突for(Line=0;Line<15;Line++)b[Line]=c[Line]=0;qu(0);return 0;}void qu(int i){int Column;for(Column=0;Column<8;Column++){if(a[Column]==0&&b[i-Column+7]==0&&c[i+Column]==0) //如果无冲突{Queen[i][Column]='Q'; //放皇后a[Column]=1;//标记,下一次该列上不能放皇后b[i-Column+7]=1;//标记,下一次该主对角线上不能放皇后c[i+Column]=1;//标记,下一次该从对角线上不能放皇后if(i<7) qu(i+1); //如果行还没有遍历完,进入下一行else//否则输出{//输出棋盘状态int Line,Column;cout<<"第"<<++QueenNum<<"种状态为:"<<endl;for(Line=0;Line<8;Line++){for(Column=0;Column<8;Column++)cout<<Queen[Line][Column]<<" ";cout<<endl;}cout<<endl;getchar();}/*如果前次的皇后放置导致后面的放置无论如何都不能满足要求,则回溯,重置*/Queen[i][Column]='*';a[Column]=0;b[i-Column+7]=0;c[i+Column]=0;}}}5 程序结果题目2 背包问题的求解1.问题描述假设有一个能装入总体积为T的背包和n件体积分别为w1,w2,…w n的物品,能否从n件物品中挑选若干件恰好装满背包,即使w1+w2+…+w m=T,要求找出所有满足上述条件的解。
bladex审批流流程图配置和后端代码
bladex审批流流程图配置和后端代码1.指定到⼈@Override@Transactional(rollbackFor = Exception.class)// @GlobalTransactionalpublic boolean startProcess(ProcessPurchaseOrder bean) {//是否启动流程boolean isStartProcess = false;//是否新增数据boolean isAdd = false;if (bean != null) {if (Func.isEmpty(bean.getProcessInstanceId())) {isStartProcess = true;}if (Func.isEmpty(bean.getId())) {isAdd = true;}//更新业务数据if (isAdd) {Date now = new Date();SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");String dateStr = format.format(now);if(Func.isNull(bean.getOrderNumber())){bean.setOrderNumber(oaSerialService.getSerial(bean.getTenantId(),"purchaseOrder",dateStr,dateStr,5));}//第⼀次发起保存数据到采购订单表和订单详情表save(bean);//采购订单明细进⼊明细表saveDetail(bean.getPurchaseOrderDetail(), bean.getOrderNumber());} else {updateById(bean);//从新发起修改采购订单详细表1.先删除以前的数据,2.从新插⼊新的订单详情deleteOrderDetail(bean.getOrderNumber());saveDetail(bean.getPurchaseOrderDetail(), bean.getOrderNumber());}//更新附件信息oaAttachmentService.saveOrUpdateOaAttachment(bean.getAttachments(),bean.getId(),bean.getProcessInstanceId(),bean.getTenantId(),"purchaseOrder"); }//除了茶叶原物料都⾛主管经理审批bean.setChanges("01");System.out.println("urchaseType=================="+bean.getPurchaseType());//茶叶原物料价格没有变动只⾛主管审批if(bean.getPurchaseType().equals("茶叶") || bean.getPurchaseType().equals("原物料")){if (null != bean.getPurchaseOrderDetail() && bean.getPurchaseOrderDetail().size() > 0) {for (ProcessPurchaseOrderDetail processPurchaseOrderDetail : bean.getPurchaseOrderDetail()) {System.out.println("processPurchaseOrderDetail.getPriceChange()====" + processPurchaseOrderDetail.getPriceChange());if (processPurchaseOrderDetail.getPriceChange().equals("1")) {//01价格有变动 02没有变动bean.setChanges("01");break;}else{bean.setChanges("02");}}}}//获取发起⼈部门idLong curDeptId = DeskUtil.getCurDeptId(bean.getCreateDept());//获取经理职位Long managerUser=null;String roleId=deptUserUtil.getRoleId(AuthUtil.getTenantId(), "经理");List<User>users=deptUserUtil.getUserListByRoleIdAndDeptId(roleId,String.valueOf(curDeptId),false);if(!Func.isEmpty(users)){managerUser=users.get(0).getId();}("获取经理职位roleId====="+roleId+"------users========================"+users);//获取部门总监String majorRoleId=deptUserUtil.getRoleId(AuthUtil.getTenantId(), "总监");List<User>majordomoUsers=deptUserUtil.getUserListByRoleIdAndDeptId(majorRoleId,String.valueOf(curDeptId),true);Long generalManager=null;if(null!=majordomoUsers && majordomoUsers.size()>0){generalManager =majordomoUsers.get(0).getId();}("获取总监majorRoleId===="+majorRoleId+"-----majordomoUsers========================"+majordomoUsers);//获取总经理String companyBossPostId=deptUserUtil.getPostId("总经理",bean.getTenantId());List<User>companyBossUsers=deptUserUtil.getUserListByPostId(companyBossPostId);//总经理不属于某个部门,不⽤根据部门id查询Long companyBoss=null;if(null!=companyBossUsers && companyBossUsers.size()>0){companyBoss=companyBossUsers.get(0).getId();}("获取总经理companyBossPostId====="+companyBossPostId+"-------companyBossUsers========================"+companyBossUsers);//上级主管roleId = deptUserUtil.getRoleId(AuthUtil.getTenantId(),"主管");boolean isManager = Func.isNotEmpty(AuthUtil.getUserRole())&&AuthUtil.getUserRole().contains("主管")?true:false;Long lastManagerUserId = null;if(isManager){users = deptUserUtil.getUserListByRoleIdAndDeptId(roleId,String.valueOf(curDeptId),true,AuthUtil.getUserId());lastManagerUserId = Func.isEmpty(users)?null:users.get(0).getId();}/*** 判断条件*///如果发起⼈是总监或者经理不是部门最⾼领导没有的职位跳过经理职位if(null!=managerUser){if(AuthUtil.getUser().getUserId().longValue()==managerUser.longValue()){managerUser=null;//经理}}//跳过总监if(null!=generalManager){//跳过总监if(AuthUtil.getUser().getUserId().longValue()==generalManager.longValue()){//跳过经理managerUser=null;//经理//跳过总监职位generalManager=null;}}Kv variables =DeskUtil.createKV(curDeptId,"采购订单",bean.getOrderNumber(),bean.getApplicantName(),isManager,bean.getCcUser(),bean.getCcUserName()).set("taskUser", TaskUtil.getTaskUser(AuthUtil.getUser().getUserId().toString())).set("category", bean.getCategory())//申请类型.set("changes", bean.getChanges())//价格是否变动.set("managerSkip", Func.isEmpty(managerUser)).set("managerUser",TaskUtil.getTaskUser(String.valueOf(managerUser==null ? "" : managerUser)))//经理.set("generalManagerSkip", Func.isEmpty(generalManager)).set("generalManager",TaskUtil.getTaskUser(String.valueOf(generalManager==null ? "" : generalManager)))//总监.set("companyBossSkip",Func.isEmpty(companyBoss)).set("companyBossUser", TaskUtil.getTaskUser(String.valueOf(companyBoss==null ? "" : companyBoss)))//总经理.set("lastManagerSkip",Func.isEmpty(lastManagerUserId)).set("lastManagerUser",TaskUtil.getTaskUser(String.valueOf(lastManagerUserId)));//开启流程if (isStartProcess) {String businessTable = FlowUtil.getBusinessTable(ProcessConstant.PURCHASE_ORDER_KEY);//获取表名R<BladeFlow> result = flowClient.startProcessInstanceById(bean.getProcessDefinitionId(), FlowUtil.getBusinessKey(businessTable, String.valueOf(bean.getId())), variables); if (result.isSuccess()) {log.debug("流程已启动,流程ID:" + result.getData().getProcessInstanceId());// 返回流程id写⼊leavebean.setProcessInstanceId(result.getData().getProcessInstanceId());updateById(bean);} else {throw new ServiceException("开启流程失败");}} else {//开启流程 TaskId ProcessInstanceIdif(!Func.isEmpty(bean.getFlow())&&!Func.isEmpty(bean.getFlow().getTaskId())&&!Func.isEmpty(bean.getProcessInstanceId())){variables.put(ProcessConstant.PASS_KEY, true);pleteTask(bean.getFlow().getTaskId(),bean.getProcessInstanceId(),bean.getFlow().getComment(),variables);}}return true;}//2.指定到⾓⾊/** Copyright (c) 2018-2028, Chill Zhuang All rights reserved.** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions are met:** Redistributions of source code must retain the above copyright notice,* this list of conditions and the following disclaimer.* Redistributions in binary form must reproduce the above copyright* notice, this list of conditions and the following disclaimer in the* documentation and/or other materials provided with the distribution.* Neither the name of the developer nor the names of its* contributors may be used to endorse or promote products derived from* this software without specific prior written permission.* Author: Chill 庄骞 (smallchill@)*/package org.springblade.desk.management.service.impl;import com.alibaba.fastjson.JSONObject;import lombok.AllArgsConstructor;import lombok.extern.slf4j.Slf4j;import org.springblade.core.log.exception.ServiceException;import org.springblade.core.mp.base.BaseServiceImpl;import org.springblade.core.secure.utils.AuthUtil;import org.springblade.core.tool.api.R;import org.springblade.core.tool.support.Kv;import org.springblade.core.tool.utils.Func;import org.springblade.desk.management.constant.AuthorityConstant;import org.springblade.desk.management.entity.OaAuthorityManagement;import org.springblade.desk.management.mapper.OaAuthorityManagementMapper;import org.springblade.desk.management.service.IOaAuthorityManagementService;import org.springblade.desk.service.impl.AdjustPriceDetailServiceImpl;import org.springblade.desk.service.impl.OaSerialServiceImpl;import org.springblade.desk.utils.DeptUserUtil;import org.springblade.desk.utils.DeskUtil;import org.springblade.flow.core.constant.ProcessConstant;import org.springblade.flow.core.entity.BladeFlow;import org.springblade.flow.core.feign.IFlowClient;import org.springblade.flow.core.utils.FlowUtil;import org.springblade.flow.core.utils.TaskUtil;import er;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import java.text.SimpleDateFormat;import java.util.Date;import java.util.List;/*** 权限申请单** @author pei*/@Slf4j@Service@AllArgsConstructorpublic class OaAuthorityManagementServiceImpl extends BaseServiceImpl<OaAuthorityManagementMapper, OaAuthorityManagement> implements IOaAuthorityManagementService { private IFlowClient flowClient;private OaSerialServiceImpl oaSerialService;private AdjustPriceDetailServiceImpl adjustPriceDetailServiceImpl;private DeptUserUtil deptUserUtil;@Override@Transactional(rollbackFor = Exception.class)public boolean startProcess(OaAuthorityManagement bean) {("权限申请单开启流程bean============="+bean);//是否启动流程boolean isStartProcess = false;//是否新增数据boolean isAdd = false;if(bean!=null){if(Func.isEmpty(bean.getProcessInstanceId())){isStartProcess = true;}if(Func.isEmpty(bean.getId())){isAdd = true;bean.setTenantId(AuthUtil.getTenantId());}//更新业务数据if(isAdd){Date now = new Date();SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");String dateStr = format.format(now);if(Func.isEmpty(bean.getAuthorityManagementNumber())){bean.setAuthorityManagementNumber(oaSerialService.getSerial(AuthUtil.getTenantId(),"OaAuthorityManagement",dateStr,dateStr,5));}}if(Func.isNotEmpty(bean.getObjIfo())){//将系统权限数据转换成string保存⼊库String str= JSONObject.toJSONString(bean.getObjIfo());bean.setApplicationSystemValue(str);}saveOrUpdate(bean);}Long curDeptId = DeskUtil.getCurDeptId(bean.getCreateDept());//获取主管Long managerUser=null;String roleId=deptUserUtil.getRoleId(AuthUtil.getTenantId(), "主管");List<User> users=deptUserUtil.getUserListByRoleIdAndDeptId(roleId,String.valueOf(curDeptId),false,AuthUtil.getUserId());if(!Func.isEmpty(users)){managerUser=users.get(0).getId();}("获取主管职位roleId====="+roleId+"------users========================"+users);//获取it部门审批⼈//1.根据部门名称获取部门id IT部String deptId= deptUserUtil.getDeptId(AuthUtil.getTenantId(),AuthorityConstant.IT_DEPT_NAME);String itRoleId=deptUserUtil.getRoleId(AuthUtil.getTenantId(), AuthorityConstant.IT_ROLE_NAME);List<User>itRoleUsers=deptUserUtil.getUserListByRoleIdAndDeptId(itRoleId,String.valueOf(deptId));("获取it部门审批⼈itRoleUsers================="+itRoleUsers);Long itRoleManager=null;if(null!=itRoleUsers && itRoleUsers.size()>0){itRoleManager =itRoleUsers.get(0).getId();}boolean isManager = Func.isNotEmpty(AuthUtil.getUserRole())&&AuthUtil.getUserRole().contains("主管")?true:false;// 启动流程Kv variables =DeskUtil.createKV(curDeptId,"权限申请单",bean.getAuthorityManagementNumber(),bean.getApplicationSystem()+","+bean.getRemark(),isManager,bean.getCcUser(),bean.getCcUserName()) .set("taskUser", TaskUtil.getTaskUser(AuthUtil.getUser().getUserId().toString())).set("managerSkip", Func.isEmpty(managerUser)).set("managerUser",TaskUtil.getTaskUser(String.valueOf(managerUser==null ? "" : managerUser)))//主管.set("itRoleManager",AuthorityConstant.IT_ROLE_NAME);//IT审批⼈(⾓⾊名称)//启动流程 isStartProcessif (isStartProcess) {//先不开启流程String businessTable = FlowUtil.getBusinessTable(ProcessConstant.OA_AUTHORITY_MANAGEMENT);R<BladeFlow> result = flowClient.startProcessInstanceById(bean.getProcessDefinitionId(), FlowUtil.getBusinessKey(businessTable, String.valueOf(bean.getId())), variables);if (result.isSuccess()) {log.debug("流程已启动,流程ID:" + result.getData().getProcessInstanceId());// 返回流程id写⼊业务表中bean.setProcessInstanceId(result.getData().getProcessInstanceId());updateById(bean);} else {throw new ServiceException("开启流程失败");}}else{if(!Func.isEmpty(bean.getFlow())&&!Func.isEmpty(bean.getFlow().getTaskId())&&!Func.isEmpty(bean.getProcessInstanceId())){variables.put(ProcessConstant.PASS_KEY, true);pleteTask(bean.getFlow().getTaskId(),bean.getProcessInstanceId(),bean.getFlow().getComment(),variables);}}return true;}}package org.springblade.desk.management.constant;/*** 2021-01-08*/public interface AuthorityConstant {/*** 部门名称*/String IT_DEPT_NAME="IT部";/*** IT部门⾓⾊*/String IT_ROLE_NAME="IT系统权限";}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
目录一需求分析 (1)1.1程序的功能: (1)1.2程序的输入输出要求: (1)二概要设计 (3)2.1程序的主要模块: (3)2.2程序涉及: (3)三详细设计 (3)3.1相关代码及算法 (4)3.1.1 定义相关的数据类型如下:....................... 错误!未定义书签。
3.1.2 主模块类C码算法: (4)3.1.3 画棋盘模块类C码算法 (5)3.1.4 画皇后模块类C码算法: (5)3.1.5 八皇后摆法模块(递归法): (6)3.1.6 初始化模块 (7)3.1.7 输出摆放好的八皇后图形(动态演示): (7)3.2相关流程图 (9)四调试分析 (12)五设计体会 (13)六附录 (13)七参考文献 (17)一需求分析1.1 程序功能:八皇后问题是一个古老而著名的问题。
该问题是十九世纪著名的数学家高斯1850年提出的。
八皇后问题要求在一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击.按照国际象棋的规则,一个皇后可以攻击与之处在同一行或同一列或同一斜线上的其他任何棋子,问有多少种不同的摆法?并找出所有的摆法。
因此,八皇后问题等于要求八个皇后中的任意两个不能被放在同一行或同一列或同一斜线上。
本程序通过对子函数void qu(int i)的调用,将八皇后的问题关键通过数据结构的思想予以了实现。
虽然题目以及演算看起来都比较复杂,繁琐,但在实际中,只要当一只皇后放入棋盘后,在横与列、斜线上没有另外一只皇后与其冲突,再对皇后的定位进行相关的判断。
即可完成。
如果在这个程序中,我们运用的是非递归的思想,那么将大量使用if等语句,并通过不断的判断,去推出答案,而且这种非递归的思想,大大的增加了程序的时间复杂度。
如果我们使用了数据结构中的算法后,那么程序的时间复杂度,以及相关的代码简化都能取得不错的改进。
这个程序,我运用到了数据结构中的栈、数组,以及树和回溯的方法。
特别是在对于树以及二叉树的学习,更是为八皇后的问题提供了科学的解决方案,通过对树的分析,把八皇后的问题看成了树,而在衍生第一个变化后,上面的第一层八个变化就变成了八个结点,而这八个结点再继续的衍生……,这样比较形象的将八皇后的问题简单化了。
然后再通过回溯法进行设计,回溯法是设计递归过程的一个重要的方法。
它的求解过程实质上是一个先序遍历一棵“状态树“的过程。
在这个程序设计中,它先进行判断,棋盘上是否已经得到一个完整的布局(即棋盘是否已经摆上8个棋子),如果是,则输出布局;如果不是则依次先根遍历满足约束条件的各棵子树,流程即是:判断该子树根的布局是否合法:如果合法的话,则先根遍历该子树;如果不合法的话,则剪去该子树的分支。
1.2 程序的输入输出要求:用TC软件进行编译以及调试,调试正确之后,运行结果如下图:第1种情况 ....... ........第92种情况二概要设计2.1 主要模块:这个程序主要由4个模块组成,分别是画棋盘模块,画皇后模块,输出皇后摆法模块,和解决如何摆置皇后模块。
这4个模块隶属于主函数模块。
既主函数通过对这4个模块的合理调用解决“8皇后问题”,同时这4个模块之间也互有调用。
2.2 程序设计的数据结构及其关系:数据结构的实现:数组a[i]:a [i]表示第i个皇后放置的列;i的范围:1-8;对角线数组:b[j](主对角线),c[j](从对角线),根据程序的运行,去决定主从对角线是否放入皇后;然后进行数据的初始化。
从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要求),先测试当前位置(n,m)是否等于0(未被占领):如果是,摆放第n个皇后,并宣布占领(切记要横列竖列斜列一起来),接着进行递归;如果不是,测试下一个位置(n,m+1),但是如果当n<=8,m=8时,却发现此时已经无法摆放时,便要进行回溯。
三详细设计3.1 定义相关的数据类型:3.1.1 定义的相关数据类型:int A[21],B[21],C[21],Y[8];void *buff1,*buff23.1.2 设计思想:本程序通过对子函数void qu(int i)的调用,将八皇后的问题关键通过数据结构的思想予以了实现。
虽然题目以及演算看起来都比较复杂,繁琐,但在实际中,只要当一只皇后放入棋盘后,在横与列、斜线上没有另外一只皇后与其冲突,再对皇后的定位进行相关的判断。
即可完成。
如果在这个程序中,我们运用的是非递归的思想,那么将的增加了程序的时间复杂度。
如果我们使用了数据结构中的算法后,那么程序的时间复杂度,以及相关的代码简化都能取得不错的改进。
这个程序,我运用到了数据结构中的栈、数组,以及树和回溯的方法。
特别是在对于树以及二叉树的学习,更是为八皇后的问题提供了科学的解决方案,通过对树的分析,把八皇后的问题看成了树,而在衍生第一个变化后,上面的第一层八个变化就变成了八个结点,而这八个结点再继续的衍生……,这样比较形象的将八皇后的问题简单化了。
然后再通过回溯法进行设计,回溯法是设计递归过程的一个重要的方法。
它的求解过程实质上是一个先序遍历一棵“状态树“的过程。
在这个程序设计中,它先进行判断,棋盘上是否已经得到一个完整的布局(即棋盘是否已经摆上8个棋子),如果是,则输出布局;如果不是则依次先根遍历满足约束条件的各棵子树,流程即是:判断该子树根的布局是否合法:如果合法的话,则先根遍历该子树;如果不合法的话,则剪去该子树的分支。
3.2 相关代码及算法3.2.1 主模块C码算法:void main(void){Queen Q;int gdriver=DETECT,gmode;initgraph(&gdriver,&gmode,"D://Win-TC");SetQueen(&Q);setcolor(YELLOW);QueenPic();cleardevice();setcolor(LIGHTGREEN);settextstyle(0,0,3);outtextxy(180,10,"Eight Queens");setcolor(WHITE);settextstyle(0,0,1);outtextxy(250,400,"2009.11.8 3:30pm");getch();closegraph();}3.2.2 棋盘模块C码算法void Checker(void) /* 画棋盘函数 */{int i,k;for(k=0;k<8;k++)for(i=0;i<8;i++)if(k%2==0&&i%2==0||k%2!=0&&i%2!=0){setfillstyle(SOLID_FILL,LIGHTBLUE);setcolor(LIGHTBLUE);rectangle(i*20,20+k*20,(i+1)*20,20+(k+1)*20);floodfill(i*20+10,20+k*20+10,LIGHTBLUE);}else{setfillstyle(SOLID_FILL,WHITE);setcolor(WHITE);rectangle(i*20,20+k*20,(i+1)*20,20+(k+1)*20);floodfill(i*20+10,20+k*20+10,WHITE);}}3.2.3 皇后模块C码算法:void QueenPic(void) /* 画皇后图象,然后存储到缓冲区 */ {int size,polypoints1[10]={9,1,11,1,20,20,1,20,9,1},polypoints2[10]={29,1,31,1,40,20,21,20,29,1};setfillstyle(SOLID_FILL,LIGHTBLUE); /* 画淡蓝色棋格 */setcolor(LIGHTBLUE);rectangle(1,1,20,20);floodfill(10,10,LIGHTBLUE);setfillstyle(SOLID_FILL,WHITE); /* 画白色棋格 */setcolor(WHITE);rectangle(21,1,40,20);floodfill(30,10,WHITE);setfillstyle(SOLID_FILL,DARKGRAY);setcolor(YELLOW);drawpoly(5,polypoints1);drawpoly(5,polypoints2);floodfill(10,10,YELLOW);floodfill(30,10,YELLOW);size=imagesize(1,1,20,20); /* 计算缓冲区大小,然后存储 */buff1=(void *)malloc(size);buff2=(void *)malloc(size);getimage(1,1,20,20,buff1);getimage(21,1,40,20,buff2);cleardevice();}3.2.4 八皇后摆放方法模块C码:void QueenRe(Queen *Q, int y) 八皇后的递归算法{int x;if(y>7)return;for(x=0;x<8;x++)if(!Q->A[x+7]&&!Q->B[x+y+7]&&!Q->C[x-y+7]) 下一棵要遍历的子树由状态数确定 {Q->Y[y]=x;放置皇后Q->A[x+7]=1;标记下次这里不能放置皇后Q->B[x+y+7]=1;标记下次这里不能放置皇后Q->C[x-y+7]=1; 标记下次这里不能放置皇后if(y==7)PrintQueen(Q);调用输出图形函数QueenRe(Q,y+1); 进入下一层递归Q->A[x+7]=0;如果上次摆法导致后面不能继续摆放则重置标记为0 Q->B[x+y+7]=0;Q->C[x-y+7]=0;}}3.2.5 初始化模块C码:void SetQueen(Queen *Q) /* 初始化 */ {int i;for(i=0;i<21;i++){Q->A[i]=0; Q->B[i]=0;Q->C[i]=0;初始化为0,表示可以放置皇后。
} for(i=0; i<8; i++)Q->Y[i]=-1;}3.2.6 图形输出:void PrintQueen(Queen *t) /* 图形输出函数 */{int k;char str[20];static total=0;total++;setviewport(240,80,400,260,1); /* 设置窗口 */sprintf(str,"NO.%d",total);setcolor(GREEN);settextstyle(0,0,1);outtextxy(0,0,str);Checker();for(k=0;k<8;k++)if(k%2==0&&t->Y[k]%2==0||k%2!=0&&t->Y[k]%2!=0)putimage((t->Y[k])*20,20+k*20,buff1,COPY_PUT);elseputimage((t->Y[k])*20,20+k*20,buff2,COPY_PUT);getch();if(getch()==27) exit(0);clearviewport();}void QueenRe(Queen *Q, int y) /* 八皇后的递归算法 */{int x;if(y>7)return;for(x=0;x<8;x++)if(!Q->A[x+7]&&!Q->B[x+y+7]&&!Q->C[x-y+7]) /* 下一棵要遍历的子树由状态数确定 */{Q->Y[y]=x;Q->A[x+7]=1;Q->B[x+y+7]=1;Q->C[x-y+7]=1;if(y==7)PrintQueen(Q);QueenRe(Q,y+1); /* 进入下一层递归 */Q->A[x+7]=0;Q->B[x+y+7]=0;Q->C[x-y+7]=0;}}}3.3 相关流程图函数调用图皇后模块流程图八皇后递归流程图START行循环遍历完毕列循环遍历当前位置可否放置皇后放置皇后,并且标记下次该列,主次对角线不能放皇后回朔 重置 YN列遍历完毕输出图形EndNYNY四调试分析通过编译连接后,程序基本上把八皇后的92种摆法的都进行了演示;但程序运行中也出现了以下缺点:因为八皇后的表现方法甚多,输出后虽能全部显示,但未能使屏幕停留,把一个一个的将其显示出来,但是这样便使得操作步骤太多,也会造成不必要的麻烦!所以只画出了第一种和最后一种的输出结果,演示如图所示:正确输出结果如下:五设计体会本课程设计本人的目的也是通过用WIN-TC程序设计平台将一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击的92种结构予以实现.最终将其问题变得一目了然,更加易懂。