算法设计与分析实验报告c++实现(八皇后问题、连续邮资问题、卫兵布置问题、圆排列问题)

一、实验目的

1.加深学生对回溯法算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;
2.提高学生利用课堂所学知识解决实际问题的能力;
3.提高学生综合应用所学知识解决实际问题的能力。

二、实验任务

用回溯法解决下列问题:
1、 八皇后问题
在8×8的棋盘上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上。可以把八皇后问题扩展到n皇后问题,即在n×n的棋盘上摆放n个皇后,使任意两个皇后都不能处于同一行、同一列或同一斜线上。
2、 连续邮资问题
连续邮资问题:某国家发行了n种不同面值的邮票,并且规定每张信封上最多只允许贴m张邮票。连续邮资问题要求对于给定的n和m的值,给出邮票面值的最佳设计。
3、 卫兵布置问题
一个博物馆由排成m×n个矩阵陈列的陈列室组成,需要在陈列室中设立哨位,每个哨位上的哨兵除了可以监视自己所在陈列室外,还可以监视他上、下、左、右四个陈列室。试给出一个最佳哨位安排方法,使得所有陈列室都在监视之下,但使用的哨兵最少。
4、 圆排列问题
给定n个大小不等的圆c1,c2,…,cn,现要将这n个圆排进一个矩形框中,且要求各圆与矩形框的底边相切。圆排列问题要求从n个圆的所有排列中找出有最小长度的圆排列。

三、实验设备及编程开发工具

编程开发工具:Microsoft Visual c++

四、实验过程设计(算法设计过程)

(一)八皇后问题

1、基本算法思想
首先我们分析一下问题的解,我们每取出一个皇后,放入一行,共有八种不同的放
简单的说就是 从当前列中依次选取位置,与前面列中选取的位置进行比较,判断是否冲突,若冲突,回溯到上一列寻找,否则进入下一列寻找位置
1、从column=0列中选取一个位置,column+1,转到2。(这里column为当前列 值为0~7),
2、从第column列中选取一个位置, 转到3。
3、判断是否与前面各列选取位置冲突。
若冲突:判断column列中位置是否全部判断过,若是 转到5,否则 直接转到2;
否则:转到4。
4、判断是否到最后一列。
若到最后一列说明本次查找成功,记录位置并将结果输出,转到5;
否则,记录当前位置,进入下一列寻找合适位置,即column+1转到2
5、判断是否回溯到第一列。
若是:结束。
否则:继续回溯,回溯到上一列继续选取位置,即column-1转到2 。
2、源程序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace eightQueen
{//八皇后问题:在8*8格的国际象棋上摆放八个皇后,使其不能互相攻击,//即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
class Program{staticvoid Main(string[] args){DateTime time1 = DateTime.Now;QueenArithmetic(8);              //皇后个数可选DateTime time2 = DateTime.Now;TimeSpan span = time2 - time1;Console.WriteLine("\n执行时间:"+span);Console.ReadKey();}//定义解决皇后问题方法,使用回溯法,根据皇后数量获取结果
staticvoid QueenArithmetic(int queenNum){int[] Queen =newint[queenNum];    //保存每次成功的结果,索引代表所在列,值代表皇后在该列的位置
int row =0;    //当前所在的行    
int column =0;     //当前所在列Queen[0]=-1;int count =0;     //用来记录当前是第几种摆法while (true){for (row = Queen[column]+1; row < queenNum; row++)    //遍历本次回溯  该列中未被访问到的行{if (!IsConflict(Queen, column, row))        //如果不冲突{break;} }if (row >= queenNum)   //没有找到合适的位置{if (column ==0)   //如果当前已经回溯到了第一列{break;          //退出while循环,整个过程结束}else{Queen[column] =-1;      //否则回溯到上一列column--;}}else//找到了合适的位置{Queen[column] = row;column++;               //为下一列找合适位置
if (column < queenNum)//如果当前不是最后一列{Queen[column] =-1;}else//说明本次查找完毕,开始打印输出{PrintQueen(Queen, queenNum, ++count);//打印输出当前结果column--;               //回溯到上一列继续查找}}}}//根据获得的皇后数组,判断当前位置(row,column)是否与前面冲突
staticbool IsConflict(int[] queen, int column, int row){for (int exsitColumn =0; exsitColumn < column; exsitColumn++)  //遍历当前列之前的所有列中找到的皇后位置,检测是否与当前位置冲突{int exsitRow = queen[exsitColumn];int span = column - exsitColumn;if ((row == exsitRow) || (row == exsitRow + span) || (row == exsitRow - span))  //如果在同一行或者同一条斜线上{returntrue;                                                            //即冲突}}returnfalse;}//打印输出结果
staticvoid PrintQueen(int[] queen,int queenNum, int count){Console.WriteLine("\n第{0}种摆法:", ++count);for (int c =0; c < queenNum; c++){for (int r =0; r < queenNum; r++){if (r == queen[c]){Console.Write("Q");}else{Console.Write("*");}}Console.Write("\n");}}}
}

(二)连续邮资问题

1、基本算法思想
在下面的回溯法描述中,递归函数Backtrack实现对整个解空间的回溯搜索。 maxvalue记录当前已经找到的最大连续邮资区间,bestx是相应的当前最优解。 数组y用来记录当前已经选定的邮票面值x[1:i]能贴出各种邮资所需的最少邮票数。 也就是说,y[k]是用不超过m张面值为x[1:i]的邮票,贴出邮资k所需的最少邮票张数。 在函数Backtrack中, 当i>n时,表示算法已经搜索到一个叶结点,得到一个新的邮票面值设计方案x[1:n]。如果该方案能贴出的 最大连续邮资区间大于当前已经找到的最大连续邮资区间maxvalue,则更新当前最优值maxvalue和相应的最优解。 当i <= n时,当前扩展结点z是解空间中的一个内部结点,在该结点处x[1:i-1] 能贴出的最大最大邮资区间为r-1.因此在结点z处x[i]的可取范围是x[i-1]+1:r, 从而,结点z有r-x[i-1]个儿子结点。算法对当前扩展结点z的每一个儿子结点, 以深度优先的方式递归地对相应子树进行搜索 解空间是多叉树,孩子接点个数是每层都在变化的。
2、源程序

#include <stdio.h>
#include <string.h>
int n,m;//n为邮票种类,m为一封信上最多贴的邮票个数
int Max;
int ans[10000];//最终答案数组
int min(int a,int b)
{return a<b?a:b;
}
int panduan(int x[10000],int n,int sum)
//能否用n种邮票,面值在x数组中,最多贴m张,表示出sum(是个动态规划问题,
//方法是求出dp[n][sum]看它是否小于sum,状态转移方程dp[i][j]=min(dp[i-1][j-k*x[i]]+k)(其中dp[i][j]表示用到第i种邮票,表示邮资为j的最少邮票{int i,j,k;int dp[15][1005];for (i=0;i<=n;i++)dp[i][0]=0;for (i=0;i<=sum;i++)dp[1][i]=i;for (i=2;i<=n;i++)for (j=1;j<=sum;j++){dp[i][j]=9999;for (k=0;k<=j/x[i];k++)dp[i][j]=min(dp[i][j],dp[i-1][j-x[i]*k]+k);  //使用min函数}if (dp[n][sum]>m)return 0;return 1;}void DFS(int x[10000],int cur,int max)//x数组储存当前的解,cur代表目前到第几种面值,当到n为止,max表示到目前为止的最大可到达邮资。
{int i,j,next;if (cur==n)//如果已经得出了n种邮票{if (max>Max)//并且它的最大值已经大于当前最大邮资数{Max=max;for (i=1;i<=cur;i++)ans[i]=x[i];//更新答案数组}return;}for (next=x[cur]+1;next<=max+1;next++)//如果还没得到n中邮票,那么从x[cur]+1~max+1选一个作为下一个邮资,//因为max+1没法表示,所以必定到max+1为止{x[cur+1]=next;//接下来是重点,用种类为cur+1,数目分别为x[1..cur+1]的邮票,最多使用m张,能否表示出大于max的某个数for (i=max+1;i<=m*x[cur+1];i++)//这个数最少要为max+1(不然没有意义了),最多是x[cur+1]*mif (panduan(x,cur+1,i)==0)//如果成立break;if (i>max+1)//如果至少让最大值更新了一次DFS(x,cur+1,i-1);}}int main(){int i,j,max,cur;int x[1000];//中间传递的数组,存储当前的邮票值的解printf("请输入邮票种类数:");scanf("%d",&n);printf("请输入最多粘贴邮票数:");scanf("%d",&m);Max=0;max=m;cur=1;x[cur]=1;DFS(x,cur,max);//x存储当前的解,cur表示当前传递到第几种邮票,max表示目前能表示到的最大值printf("生成的最大邮资是:%d\n",Max);for (i=1;i<=n;i++)printf("%d ",ans[i]);return 0;}

(三)卫兵布置问题
1、基本算法原理
从上到下、从左到右的顺序依次考查每一个陈列室设置警卫机器人哨位的情况,以及该陈列室受到监视的情况,用[i,j]表示陈列室的位置,用x[i][j]表示陈列室[i,j]当前设置警卫机器人哨位的状态。当x[i][j]=1时,表示陈列室[i,j]设置了警卫机器人,当x[i][j]=0时,表示陈列室[i,j]没有设置了警卫机器人。用y[i][j]表示陈列室[i,j]当前受到监视的的警卫机器人的数量。当y[i][j]>0时,表示陈列室[i,j]受到监视的警卫机器人的数量,当y[i][j]=0时,表示陈列室[i,j]没有受到监视。设当前已经设置的警卫机器人的哨位数为k,已经受到监视的陈列室的数量为t,当前最优警卫机器人哨位数为bestc。
设回溯搜索时,当前关注的陈列室是[i,j],假设该陈列室已经受到监视,即y[i][j]==1,
此时在陈列室[i,j]处设置一个警卫机器人哨位,即x[i][j]==1,相应于解空间树的一个节点q,在陈列室[i+1,j]处设置一个机器人哨位,x[i+1][j]==1,相应于解空间树的另一个节点p。容易看出,以q为根的子树的解,不优于以p为根的子树的解,以q为根的子树可以剪去。因此,在以从上到下,从左到右的顺序依次考察每一个陈列室时,已受监视的陈列室不必设置警卫机器人哨位。
设陈列室[i,j]是从上到下、从左到右搜索到的第一个未受监视的陈列室,为了使陈列室[i,j]受到监视,可在陈列室[i+1,j]、[i,j]、[i,j+1]处设置警卫机器人哨位,在这3处设置哨位的解空间树中的结点分别为p、q、r。

img

当y[i][j+1]==1时,以q为根的子树的解,不优于以p为根的子树的解,当y[i][j+1]==1且y[i][j+2]==1时,以r为根的子树的解,不优于以p为根的子树的解。搜索时应按照p、q、r的顺序来扩展结点,并检测节点p对节点q和节点r的控制条件。
2、源代码

#include<fstream>
#include<iostream>
using namespace std;ifstream fin("input.txt");
ofstream fout("output.txt");
ofstream testout("testout.txt");class Exhibit_hall {friend void Setrobot(int, int);
private:void set(int i, int j, int a[]);//安排哨兵void recover(int i, int j, int a[]);void Backtrack(int i, int j);void GreedySearch();	//贪婪搜索int search(int i, int j);	//搜索在a[i][j]安排哨兵人时它所监督未被监督的陈列室个数void set(int i, int j);int m, n;	//陈列馆的行数,列数int mn;		//陈列室个数int g_num;	//陈列室中已被监视的个数int num;	//当前哨兵个数int num1;	//用于贪心搜索中哨兵的个数int **x;	//当前解int bestn;	//当前最优解的个数int **bestx;//当前最优解
};void Exhibit_hall::set(int i, int j, int a[])//x[][]为1表示此房间已放置了一个哨兵,为2表示此房间已被监视
{num++;a[0] = x[i][j];if (a[0] == 0) g_num++;//若此陈列室未被监视,则此时已被监视g_num++x[i][j] = 1;//此位置放置了一个哨兵if (x[i - 1][j] == 0) { a[1] = 1;x[i - 1][j] = 2;g_num++; }//若上方未被监视,则此时设置未已被监视if (x[i][j + 1] == 0) { a[2] = 1;x[i][j + 1] = 2;g_num++; }if (x[i + 1][j] == 0) { a[3] = 1;x[i + 1][j] = 2;g_num++; }if (x[i][j - 1] == 0) { a[4] = 1;x[i][j - 1] = 2;g_num++; }
}void Exhibit_hall::recover(int i, int j, int a[])//撤消哨兵
{num--;x[i][j] = a[0];if (a[0] == 0) g_num--;if (a[1]) { x[i - 1][j] = 0;g_num--; }if (a[2]) { x[i][j + 1] = 0;g_num--; }if (a[3]) { x[i + 1][j] = 0;g_num--; }if (a[4]) { x[i][j - 1] = 0;g_num--; }a[0] = 0;a[1] = 0;a[2] = 0;a[3] = 0;a[4] = 0;
}void Exhibit_hall::Backtrack(int i, int j)//回溯
{if (i>m) {if (num<bestn){for (int k = 1;k<m + 1;k++)for (int l = 1;l<n + 1;l++)bestx[k][l] = x[k][l];bestn = num;}return;}if (num + (mn - g_num) / 5 >= bestn) return;//当此陈列室已被监视,则没必要在此陈列室安排哨兵//因为x[i+1][j+1]放置一机器人优于此处哨兵if (x[i][j] != 0)Backtrack(i + j / n, j%n + 1);//在此陈列室被监视else{int a[5] = { 0 };if (i<m)		//在此陈列室下面安排哨兵监视此陈列室{set(i + 1, j, a);Backtrack(i, j);recover(i + 1, j, a);}if ((j<n) && (x[i][j + 1] == 0 || x[i][j + 2] == 0))		//在此陈列室右边安排哨兵监视此陈列室{set(i, j + 1, a);Backtrack(i, j);recover(i, j + 1, a);}if (x[i + 1][j] == 0 && x[i][j + 1] == 0)		//在此陈列室安排哨兵{set(i, j, a);Backtrack(i, j);recover(i, j, a);}}
}
int Exhibit_hall::search(int i, int j)
{if (i == m + 1 || j == n + 1) return 0;int count = 0;if (x[i][j] == 0)count++;if (x[i - 1][j] == 0)count++;if (x[i][j + 1] == 0)count++;if (x[i + 1][j] == 0)count++;if (x[i][j - 1] == 0)count++;return count;
}
void Exhibit_hall::set(int i, int j)
{num1++;x[i][j] = 1;if (x[i - 1][j] == 0)x[i - 1][j] = 2;if (x[i][j + 1] == 0)x[i][j + 1] = 2;if (x[i + 1][j] == 0)x[i + 1][j] = 2;if (x[i][j - 1] == 0)x[i][j - 1] = 2;
}void Exhibit_hall::GreedySearch()
{for (int i = 1;i <= m;i++)for (int j = 1;j <= n;j++){if (x[i][j] == 0){int a1 = 0, a2 = 0, a3 = 0;a1 = search(i, j);a2 = search(i + 1, j);a3 = search(i, j + 1);if (a1 >= a2&&a1 >= a3)set(i, j);else {if (a2 >= a3){if (a2>a3)set(i + 1, j);elseif (x[i + 1][j] != 0 && x[i][j + 1] == 0)set(i, j + 1);else set(i + 1, j);}else set(i, j + 1);}}}for (i = 1;i <= m;i++)for (int j = 1;j <= n;j++){bestx[i][j] = x[i][j];x[i][j] = 0;}bestn = num1;
}void Setrobot(int m, int n)
{Exhibit_hall Ex;Ex.m = m;Ex.n = n;Ex.mn = m*n;Ex.num = 0;Ex.num1 = 0;Ex.bestn = m*n;Ex.g_num = 0;Ex.x = new int*[m + 2];for (int i = 0;i<m + 2;i++){Ex.x[i] = new int[n + 2];for (int j = 0;j<n + 2;j++)Ex.x[i][j] = 0;}Ex.bestx = new int*[m + 2];for (i = 0;i<m + 2;i++){Ex.bestx[i] = new int[n + 2];for (int j = 0;j<n + 2;j++)Ex.bestx[i][j] = 0;}for (int k = 0;k<n + 2;k++) { Ex.x[0][k] = 2;Ex.x[m + 1][k] = 2; }for (k = 1;k<m + 1;k++) { Ex.x[k][0] = 2;Ex.x[k][n + 1] = 2; }Ex.GreedySearch();//cout << Ex.bestn << endl;Ex.Backtrack(1, 1);fout << Ex.bestn << endl;for (int j = 1;j <= m;j++) {for (int k = 1;k <= n;k++){if (Ex.bestx[j][k] == 1)fout << 1 << ' ';else fout << 0 << ' ';testout << Ex.bestx[j][k] << ' ';}fout << endl;testout << endl;}delete[] Ex.x;delete[] Ex.bestx;
}void main()
{int m, n;cin >> m >> n;Setrobot(m, n);
}

(四)圆排列问题

1、基本算法原理
圆排列问题的解空间是一棵排列树。按照回溯法搜索排列树的算法框架,设开始时a=[r1,r2,……rn]是所给的n个元的半径,则相应的排列树由a[1:n]的所有排列构成。

解圆排列问题的回溯算法中,CirclePerm(n,a)返回找到的最小的圆排列长度。初始时,数组a是输入的n个圆的半径,计算结束后返回相应于最优解的圆排列。center计算圆在当前圆排列中的横坐标,由x^2 = sqrt((r1+r2)2-(r1-r2)2)推导出x = 2sqrt(r1r2)。Compoute计算当前圆排列的长度。变量min记录当前最小圆排列长度。数组r表示当前圆排列。数组x则记录当前圆排列中各圆的圆心横坐标。
在递归算法Backtrack中,当i>n时,算法搜索至叶节点,得到新的圆排列方案。此时算法调用Compute计算当前圆排列的长度,适时更新当前最优值。
当i<n时,当前扩展节点位于排列树的i-1层。此时算法选择下一个要排列的圆,并计算相应的下界函数
2、源代码

//圆排列问题 回溯法求解
#include "stdafx.h"
#include <iostream>
#include <cmath>
using namespace std;
float CirclePerm(int n,float *a);
template <class Type>
inline void Swap(Type &a, Type &b);
int main()
{float *a = new float[4];a[1] = 1,a[2] = 1,a[3] = 2;cout<<"圆排列中各圆的半径分别为:"<<endl;for(int i=1; i<4; i++){cout<<a[i]<<" ";}cout<<endl;cout<<"最小圆排列长度为:";cout<<CirclePerm(3,a)<<endl;return 0;
}
class Circle
{friend float CirclePerm(int,float *);private:float Center(int t);//计算当前所选择的圆在当前圆排列中圆心的横坐标void Compute();//计算当前圆排列的长度void Backtrack(int t);float min,	//当前最优值*x,   //当前圆排列圆心横坐标*r;   //当前圆排列int n;      //圆排列中圆的个数
};
// 计算当前所选择圆的圆心横坐标
float Circle::Center(int t)
{float temp=0;for (int j=1;j<t;j++){//由x^2 = sqrt((r1+r2)^2-(r1-r2)^2)推导而来float valuex=x[j]+2.0*sqrt(r[t]*r[j]);if (valuex>temp){temp=valuex;}}return temp;
}
// 计算当前圆排列的长度
void Circle::Compute(void)
{float low=0,high=0;for (int i=1;i<=n;i++){if (x[i]-r[i]<low){low=x[i]-r[i];}if (x[i]+r[i]>high){high=x[i]+r[i];}}if (high-low<min){min=high-low;}
}
void Circle::Backtrack(int t)
{if (t>n){Compute();}else{for (int j = t; j <= n; j++){Swap(r[t], r[j]);float centerx=Center(t);if (centerx+r[t]+r[1]<min)//下界约束{x[t]=centerx;Backtrack(t+1);}Swap(r[t], r[j]);}}
}
float CirclePerm(int n,float *a)
{Circle X;X.n = n;X.r = a;X.min = 100000;float *x = new float[n+1];X.x = x;X.Backtrack(1);delete []x;return X.min;
}
template <class Type>
inline void Swap(Type &a, Type &b)
{  Type temp=a; a=b; b=temp;
}

五、实验结果及算法复杂度分析

(一)八皇后问题
1、实验结果

img

2、时间复杂度
时间复杂度为O(n^2)。
(二)连续邮资问题
1、实验结果

img

2、时间复杂度
时间复杂度为O(n^2)。

(三)卫兵布置问题
1、实验结果

img

2、时间复杂度
时间复杂度为O(n*2^n)。
(四)圆排列问题
1、实验结果

img

2、时间复杂度
最坏时间复杂为O((n+1)!)。

实验小结(包括问题和解决方法、心得体会等)

本次实验的中心思想就是回溯法,回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。在通过本次实验的四道题目的实践,相信自己对回溯法已经足够掌握了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/813034.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue简单使用五(组件的使用)

目录 如何定义组件&#xff1a; 组件的命名&#xff1a; 父组件向子组件传值&#xff1a; 子组件向父组件传值&#xff1a; 如何定义组件&#xff1a; 全局组件定义&#xff1a; 局部组件定义&#xff1a; 组件的基本使用&#xff1a; 打印结果&#xff1a; 组件的命名&#xf…

分类预测 | Matlab实现OOA-BP鱼鹰算法优化BP神经网络数据分类预测

分类预测 | Matlab实现OOA-BP鱼鹰算法优化BP神经网络数据分类预测 目录 分类预测 | Matlab实现OOA-BP鱼鹰算法优化BP神经网络数据分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现OOA-BP鱼鹰算法优化BP神经网络多特征分类预测&#xff08;完整源码和数…

MATLAB Simulink仿真搭建及代码生成技术—01自定义新建模型模板

MATLAB Simulink仿真搭建及代码生成技术 目录 01-自定义新建模型模板点击运行&#xff1a;显示效果&#xff1a;查看模型设置&#xff1a; 01-自定义新建模型模板 新建模型代码如下&#xff1a; function new_model(modelname) %建立一个名为SmartAss的新的模型并打开 open_…

【微服务】------常见模型的分析与比较

DDD 分层架构 整洁架构 整洁架构又名“洋葱架构”。为什么叫它洋葱架构&#xff1f;看看下面这张图你就明白了。整洁架构的层就像洋葱片一样&#xff0c;它体现了分层的设计思想。 整洁架构最主要的原则是依赖原则&#xff0c;它定义了各层的依赖关系&#xff0c;越往里依赖越…

[大模型]Langchain-Chatchat安装和使用

项目地址&#xff1a; https://github.com/chatchat-space/Langchain-Chatchat 快速上手 1. 环境配置 首先&#xff0c;确保你的机器安装了 Python 3.8 - 3.11 (我们强烈推荐使用 Python3.11)。 $ python --version Python 3.11.7接着&#xff0c;创建一个虚拟环境&#xff…

Web前端-Ajax

Ajax 概念:Asynchronous JavaScript And XML,异步的JavaScript和XML。 作用: 1.数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据。 2.异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用的校验等等…

Ubuntu 22上安装Anaconda3。下载、安装、验证详细教程

在Ubuntu 22上安装Anaconda3&#xff0c;你可以遵循以下步骤&#xff1a; 更新系统存储库&#xff1a; 打开终端并运行以下命令来更新系统存储库&#xff1a; sudo apt update安装curl包&#xff1a; 下载Anaconda安装脚本通常需要使用curl工具。如果系统中没有安装curl&#x…

基于springboot的医院挂号取药缴费管理系统

一、基于springboot的医院挂号取药缴费管理系统 简介系统和功能 二、技术框架 这是一款基于SpringbootLAYUIMysql的管理系统 开发语言&#xff1a;Java JDK1.8 数据库&#xff1a;mysql5.7 前端&#xff1a;LAYUI框架 后端&#xff1a;Springboot框架、Spring框架、持久层My…

WinForms零基础进阶控件教程(超实用详细版)

文章目录 树型控件TreeView常用属性常用事件添加、删除树节点通过代码添加树节点通过代码删除树节点&#xff1a;管理节点图标响应事件&#xff0c;获取选中节点 列表视图ListView常用属性常用事件添加、删除项使用ListViewItem集合编辑器添加&#xff0c;删除项&#xff1a;通…

LED显示IC-点阵数码管显示驱动/抗干扰数码管驱动VK1650 SOP16/DIP16

产品品牌&#xff1a;永嘉微电/VINKA 产品型号&#xff1a;VK1650 封装形式&#xff1a;SOP16/DIP16 概述 VK1650是一种带键盘扫描电路接口的 LED 驱动控制专用芯片&#xff0c;内部集成有数据锁存器、LED 驱动、键盘扫描等电路。SEG脚接LED阳极&#xff0c;GRID脚接LED阴极&…

WebGL 2.0相较于1.0有什么不同?

作者&#xff1a;STANCH 1.概述 WebGL 1.0自推出以来&#xff0c;已成为广泛支持的Web标准&#xff0c;既能跨平台&#xff0c;还免版税。它通过插件为Web浏览器带来高质量的3D图形&#xff0c;这是迄今为止市场上使用最广泛的Web图形&#xff0c;并得到Apple&#xff0c;Goog…

ControllerAdvice用法

ControllerAdvice用法 ControllerAdvice是一个组件注解&#xff0c;它允许你在一个地方处理整个应用程序控制器的异常、绑定数据和预处理请求。这意味着你不需要在每个控制器中重复相同的异常处理代码&#xff0c;从而使得代码更加简洁、易于管理。 主要特性 全局异常处理&a…

【vue】v-model.lazy等(非实时渲染)

v-model&#xff1a;实时渲染v-model.lazy&#xff1a;失去焦点/按回车后&#xff0c;才渲染v-model.number&#xff1a;值转换为数字v-model.trim&#xff1a;去除首尾空格 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8&qu…

MDK平台 - Code, RO-data , RW-data, ZI-data详解

文章目录 1 . 前言2 . Code, RO-data , RW-data, ZI-data解析3 . RAM上电复位4 . 细节扩展5 . 总结 【全文大纲】 : https://blog.csdn.net/Engineer_LU/article/details/135149485 1 . 前言 MDK编译后&#xff0c;会列出Code, RO-data , RW-data, ZI-data&#xff0c;以下解析…

股票价格预测 | Python使用LSTM预测股票价格

文章目录 效果一览文章概述代码设计效果一览 文章概述 Python使用LSTM预测股票价格 代码设计 import pandas as pd import matplotlib.pyplot as plt import numpy as np import tensorflowfrom numpy import

2024年蓝牙耳机哪个品牌最好?五大热门机型PK,新手必看!

​随着生活节奏的加快&#xff0c;蓝牙耳机已经成为了我们日常生活中不可或缺的伙伴。它不仅让我们的听音乐、观看视频和通话变得更加便捷&#xff0c;还带来了无线的自由体验。面对市场上众多的选择&#xff0c;我为你精挑细选了几款表现优异的蓝牙耳机&#xff0c;希望能帮助…

mybiats-puls-插入测试以及雪花算法

一&#xff0c;测试 /* * 插入测试 * */ Test public void test01() {User user new User();/** 自动帮我们生成id* */user.setName("kuku");user.setAge(3);user.setEmail("2983394967qq.com");final int insert mapper.insert(user);System.out.print…

Redis从入门到精通(十六)多级缓存(一)Caffeine、JVM进程缓存

文章目录 第6章 多级缓存6.1 什么是多级缓存&#xff1f;6.2 搭建测试项目6.2.1 项目介绍6.2.2 新增商品表6.2.3 编写商品相关代码6.2.4 启动服务并测试6.2.5 导入商品查询页面&#xff0c;配置反向代理 6.3 JVM进程缓存6.3.1 Caffeine6.3.2 实现JVM进程缓存6.3.2.1 需求分析6.…

基于springboot仿雀语的文档管理系统

项目介绍 本项目借鉴了雀语的一些UI设计&#xff0c;实现了文档在线管理的功能&#xff0c;知识库可以对不同分类的文档建立不同的库&#xff0c;知识库里面左边可以维护菜单菜单目录&#xff0c;右边实现在线预览。该项目可以防止用户下载和复制文档&#xff0c;只支持在线预…

TSINGSEE青犀AI智能分析网关V4吸烟/抽烟检测算法介绍及应用

抽烟检测AI算法是一种基于计算机视觉和深度学习技术的先进工具&#xff0c;旨在准确识别并监测个体是否抽烟。该算法通过训练大量图像数据&#xff0c;使模型能够识别出抽烟行为的关键特征&#xff0c;如烟雾、手部动作和口部形态等。 在原理上&#xff0c;抽烟检测AI算法主要…