人工智能原理实验一:知识的表示与推理实验
一、实验目的
本实验课程是计算机、智能、物联网等专业学生的一门专业课程,通过实验,帮助学生更好地掌握人工智能相关概念、技术、原理、应用等;通过实验提高学生编写实验报告、总结实验结果的能力;使学生对智能程序、智能算法等有比较深入的认识。本实验通过不同知识的表达与推理问题,强化学生对知识表示的了解和应用,为人工智能后续环节的课程奠定基础。
二、基本要求
1、实验前,复习《人工智能》课程中的有关内容。
2、准备好实验数据。
3、编程或验证需要独立完成,程序应加适当的注释。
4、完成实验报告。
三、实验软件
使用C或C++(Visual studio平台等),或其它语言,如matlab或Python。
四、实验内容:
(一)猴子摘香蕉问题
利用一阶谓词逻辑求解猴子摘香蕉问题:房内有一个猴子,一个箱子,天花板上挂了一串香蕉,其位置如图1所示,猴子为了拿到香蕉,它必须把箱子搬到香蕉下面,然后再爬到箱子上。请定义必要的谓词,列出问题的初始化状态(即下图所示状态),目标状态(猴子拿到了香蕉,站在箱子上,箱子位于位置b)。(附加:从初始状态到目标状态的谓词演算过程。)
1、定义描述环境状态的谓词。
AT(x,w):x在w处,个体域:x?{monkey},w?{a,b,c,box};
HOLD(x,t):x手中拿着t,个体域:t?{box,banana};
EMPTY(x):x手中是空的;
ON(t,y):t在y处,个体域:y?{b,c,ceiling};
CLEAR(y):y上是空的;
BOX(u):u是箱子,个体域:u?{box};
BANANA(v):v是香蕉,个体域:v?{banana};
2、使用谓词、连结词、量词来表示环境状态。
问题的初始状态可表示为:So:AT(monkey,a)->EMPTY(monkey)->ON(box,c)->ON(banana,ceiling)->CLEAR(b)->BOX(box)->BANANA(banana)
要达到的目标状态为:Sg:AT(monkey,box)->HOLD(monkey,banana)->ON(box,b)->CLEAR(ceiling)->CLEAR(c)->BOX(box)->BANANA(banana)
3、从初始状态到目标状态的转化, 猴子需要完成一系列操作, 定义操作类谓词表示其动作。
WALK(m,n):猴子从m走到n处,个体域:m,n?{a,b,c};
CARRY(s,r):猴子在r处拿到s,个体域:r?{c,ceiling},s?{box,banana};
CLIMB(u,b):猴子在b处爬上u;
这3个操作也可分别用条件和动作来表示。条件直接用谓词公式表示,是为完成相应操作所必须具备的条件;当条件中的事实使其均为真时,则可激活操作规则,于是可执行该规则中的动作部分。动作通过前后状态的变化表示,即通过从动作前删除或增加谓词公式来描述动作后的状态。
4、按照行动计划, 一步步进行状态替换, 直至目标状态
AT(monkey,a)?EMPTY(monkey)?ON(box,c)?ON(banana,ceiling)?CLEAR(b)?BOX(box)?
BANANA(banana)
AT(monkey,c)?EMPTY(monkey)?ON(box,c)?ON(banana,ceiling)?CLEAR(b)?BOX(box)?
BANANA(banana)
AT(monkey,c)?HOLD(monkey,box)?ON(banana,ceiling)?CLEAR(b)?CLEAR(c)?BOX(box)?
BANANA(banana)
AT(monkey,b)?HOLD(monkey,box)?ON(banana,ceiling)?CLEAR(b)?CLEAR(c)?BOX(box)?
BANANA(banana)
AT(monkey,box)?EMPTY(monkey)?ON(box,b)?ON(banana,ceiling)?CLEAR(c)?BOX(box)?
BANANA(banana)
AT(monkey,box)?HOLD(monkey,banana)?ON(box,b)?CLEAR(ceiling)?CLEAR(c)?BOX(box)?
BANANA(banana)(目标得解)
猴子行动的规则序列是:WALK(a,c)→CARRY(c,box)→WALK(c,b)→CLIMB(box,b)→
CARRY(banana,ceiling)
5、参考代码:
#include <stdio.h>
struct State
{int monkey; /*-1:Monkey at A;0: Monkey at B;1:Monkey at C;*/int box; /*-1:box at A;0:box at B;1:box at C;*/int banana; /*Banana at B,Banana=0*/int monbox; /*-1: monkey on the box;1: monkey the box;*/
};
struct State States [150];
char* routesave[150];
/*function monkeygoto,it makes the monkey goto the other place*/
void monkeygoto(int b,int i)
{ int a;a=b;if (a==-1){routesave[i]="Monkey go to A";States[i+1]=States[i];States[i+1].monkey=-1;}else if(a==0){routesave[i]="Monkey go to B";States[i+1]=States[i];States[i+1].monkey=0;}else if(a==1){routesave[i]="Monkey go to C";States[i+1]=States[i];States[i+1].monkey=1;}else{printf("parameter is wrong");}
}
/*end function monkeyygoto*/
/*function movebox,the monkey move the box to the other place*/
void movebox(int a,int i)
{ int B;B=a;if(B==-1){routesave[i]="monkey move box to A";States[i+1]=States[i];States[i+1].monkey=-1;States[i+1].box=-1;}else if(B==0){routesave[i] = "monkey move box to B";States[i+1]=States[i];States[i+1].monkey=0;States[i+1].box=0;}else if(B==1){routesave[i] = "monkey move box to C";States[i+1]=States[i];States[i+1].monkey=1;States[i+1].box=1;}else{printf("parameter is wrong");}
}
/*end function movebox*/
/*function climbonto,the monkey climb onto the box*/
void climbonto(int i)
{routesave[i]="Monkey climb onto the box";States[i+1]=States[i];States[i+1].monbox=1;
}
/*function climbdown,monkey climb down from the box*/
void climbdown(int i)
{ routesave[i]="Monkey climb down from the box";States[i+1]=States[i];States[i+1].monbox=-1;
}
/*function reach,if the monkey,box,and banana are at the same place,the monkey reach banana*/
void reach(int i)
{ routesave[i]="Monkey reach the banana";
}
/*output the solution to the problem*/
void showSolution(int i)
{int c;printf ("%s \n", "Result to problem:");for(c=0; c<i+1; c++){printf ("Step %d : %s \n",c+1,routesave[c]);}printf("\n");
}
/*perform next step*/
void nextStep(int i)
{int c;int j;if(i>=150){printf("%s \n", "steplength reached 150,have problem ");return;}for (c=0; c<i; c++) /*if the current state is same to previous,retrospect*/{if(States[c].monkey==States[i].monkey&&States[c].box==States[i].box&&States[c].banana==States[i].banana&&States[c].monbox==States[i].monbox){return;}}if(States[i].monbox==1&&States[i].monkey==0&&States[i].banana==0&&States[i].box==0){showSolution(i);printf("Press any key to continue \n");getchar();/*to save screen for user,press any key to continue*/return;} j=i+1; if(States[i].monkey==0){ if(States[i].box==0){if(States[i].monbox==-1){climbonto(i);reach(i+1);nextStep(j);/*monkeygoto(-1,i);nextStep(j);monkeygoto(0,i);nextStep(j);movebox(-1,i);nextStep(j);movebox(0,i);nextStep(j);*/}else{reach(i+1);nextStep(j);/*climbdown(i);nextStep(j);*/}}else if(States[i].box==1){/*monkeygoto(-1,i);nextStep(j);*/monkeygoto(1,i);nextStep(j);movebox(0,i);nextStep(j);climbonto(i);reach(i+1);nextStep(j);}else /*box==-1*/{monkeygoto(-1,i);nextStep(j);movebox(0,i);nextStep(j);climbonto(i);reach(i+1);nextStep(j);}}/*end if*/if(States[i].monkey==-1){ if(States[i].box==-1){if(States[i].monbox==-1){ movebox(0,i);nextStep(j);climbonto(i);reach(i+1);nextStep(j);}else{climbdown(i);nextStep(j);movebox(0,i);nextStep(j);climbonto(i);reach(i+1);nextStep(j);}}else if(States[i].box==0){ monkeygoto(0,i);nextStep(j);climbonto(i);reach(i+1);nextStep(j);}else{monkeygoto(1,i);nextStep(j);movebox(0,i);nextStep(j);climbonto(i);reach(i+1);nextStep(j);}}/*end if*/if(States[i].monkey==1){ if (States[i].box==1){if(States[i].monbox==-1){ movebox(0,i);nextStep(j);climbonto(i);reach(i+1);nextStep(j);}else{climbdown(i);nextStep(j);movebox(0,i);nextStep(j);climbonto(i);reach(i+1);nextStep(j); }}else if(States[i].box==-1){ monkeygoto(-1,i);nextStep(j);movebox(0,i);nextStep(j);movebox(0,i);nextStep(j);climbonto(i);reach(i+1);nextStep(j);}else{monkeygoto(0,i);nextStep(j);movebox(0,i);nextStep(j);climbonto(i);reach(i+1);nextStep(j);}}/*end if*/
}/*end nextStep*/
int main()
{States[0].monkey=-1;States[0].box=1;States[0].banana=0;States[0].monbox=-1;nextStep(0);
}
(二)传教士(牧师)与野人问题
问题描述:
有n个牧师和n个野人准备渡河,但只有一条能容纳c个人的小船,为了防止野人侵犯牧师,要求无论在何处,牧师的人数不得少于野人的人数(除非牧师人数为0),且假定野人与牧师都会划船,试设计一个算法,确定他们能否渡过河去,若能,则给出小船来回次数最少的最佳方案。
实验步骤:
输入:牧师人数(即野人人数):n;小船一次最多载人量:c。
输出:若问题无解,则显示Failed,否则,显示Successed输出所有可行方案,并标注哪一组是最佳方案。用三元组(X1, X2, X3)表示渡河过程中的状态。并用箭头连接相邻状态以表示迁移过程:初始状态->中间状态->目标状态。
例:当输入n=2,c=2时,输出:221->200->211->010->021->000;
其中:X1表示起始岸上的牧师人数;X2表示起始岸上的野人人数;X3表示小船现在位置(1表示起始岸,0表示目的岸)。
要求:写出算法的设计思想和源程序,并有用户界面实现人机交互(控制台或者窗口都可以),进行输入和输出结果,如:
Please input n: 2 Please input c: 2
Optimal Procedure: 221->200->211->010->021->000
Successed or Failed?: Successed
五、学生实验报告要求
(1)对于猴子摘香蕉问题根据自己编写代码或者参考代码,用不同的初始状态测试代码,记录每种初始状态下的输出结果,并对每个结果进行解释。
(2)完善猴子摘香蕉问题参考代码,参考代码中有什么问题?应该如何修改会更好。
问题:
1. 数组索引和函数调用:
使用数组索引i访问和更新状态。确保数组索引在范围内,以避免潜在的内存问题。
考虑将状态数组封装在结构体内部或将其作为参数传递给函数,而不是使用全局数组。
2. 字符串赋值:
避免直接将字符串赋值给 routesave[i],例如 routesave[i] = "Monkey go to A";,使用strcpy或类似的函数进行字符串赋值,以避免潜在的问题。
3. 未使用的变量:
movebox函数中声明了变量int B;但未使用。移除它以避免混淆。
4. 递归函数:
nextStep 函数是递归的,它一直调用自身。这可能会导致大量步骤时发生堆栈溢出。考虑使用迭代方法,或者根据需要增加堆栈大小。
5. 内存管理:
代码使用一个固定大小的数组 (States[150]) 存储状态。如果状态数量不能事先确定,考虑使用动态内存分配或其他数据结构。
(3)传教士(牧师)与野人问题,写出状态表示的数据结构,还有每种解的状态迁移图示。
struct State {int m;//传教士int c;//野人int dep;//已划船次数int boat;//左岸是否有船bool friend operator <(const struct State& a, const struct State& b)//为实现自定义类型的set提供排序规则{return a.dep < b.dep;//升序排序}
};
例:n=2,c=2时:
1.(2,2,1) -> (2,0,0) -> (2,1,1) -> (0,1,0) -> (0,2,1) -> (0,0,0)
2.(2,2,1) -> (2,0,0) -> (2,1,1) -> (0,1,0) -> (1,1,1) -> (0,0,0)
3.(2,2,1) -> (1,1,0) -> (2,1,1) -> (0,1,0) -> (0,2,1) -> (0,0,0)
4.(2,2,1) -> (1,1,0) -> (2,1,1) -> (0,1,0) -> (1,1,1) -> (0,0,0)
(4)写出传教士(牧师)与野人问题的程序清单(语言不限)
#include<iostream>
#include<set>
#include<vector>
using namespace std;int n, c;//传教士的人数及船的载客量
int min_deep = INT_MAX;//船的最小来回次数
int path = 0;//可达路径的数量struct State {int m;//传教士int c;//野人int dep;//已划船次数int boat;//左岸是否有船bool friend operator <(const struct State& a, const struct State& b)//为实现自定义类型的set提供排序规则{return a.dep < b.dep;//升序排序}
};
set<State> Set;//自定义类型State实现set
vector<vector<State>> res;//保存所有路径//判断状态是否已经在当前路径中,避免重复加入
bool isExist(State next)
{for (auto it = Set.begin(); it != Set.end(); it++)if (it->m == next.m && it->c == next.c && it->boat == next.boat)return true;return false;
}
//输出路径
void output()
{for (int i = 0; i < res.size(); i++){if (res[i].size() == min_deep + 1)//判断是否为最优路径cout << "optimal" << endl;cout << "Solution" << i + 1 << endl;for (int j = 0; j < res[i].size(); j++)//依次输出路径上的各个状态cout << "(" << res[i][j].m << "," << res[i][j].c << "," << res[i][j].boat << ")" << endl;cout << endl;}
}
//用深度优先进行搜索
void dfs(State s)
{Set.insert(s);//加入当前路径的集合中(已按状态的先后顺序排序)if (s.m == 0 && s.c == 0)//目标状态{if (s.dep < min_deep)//记录最短路径的划船次数min_deep = s.dep;path++;vector<State> v(Set.begin(), Set.end());res.push_back(v);//保存该路径Set.erase(--Set.end());//已达终点,进行回退return;}if (s.boat == 1)//左岸{for (int i = c; i >= 1; i--)//船载i从左往右划{if (i > s.m + s.c)//i多于左岸的总人数continue;for (int j = i; j >= 0; j--)//船上有j个野人{if (j > s.c || i - j > s.m)//多于左岸传教士、野人的实际人数continue;if (j != i && j > i - j)//船上传教士的人数少于野人的人数continue;if (s.m - (i - j) != 0 && s.m - (i - j) != n && s.m - (i - j) != s.c - j)//左岸剩下的传教士与野人的人数不相等continue;State next;next.boat = 0;next.m = s.m - (i - j);next.c = s.c - j;next.dep = s.dep + 1;if (!isExist(next))//判断当前路径是否存在该状态dfs(next);}}}else//右岸{for (int i = c; i >= 1; i--)//船载i个人从右往左划{if (i > (n - s.m) + (n - s.c))//i多于右岸的总人数continue;for (int j = i; j >= 0; j--)//船上有j个野人{if (j > n - s.c || i - j > n - s.m)//多于右岸传教士、野人的实际人数continue;if (j != i && j > i - j)//船上野人的数量大于传教士的数量continue;if (n - s.m - (i - j) != 0 && n - s.m - (i - j) != n && n - s.m - (i - j) != n - s.c - j)//右岸剩下的传教士人数与野人不相等continue;State next;next.boat = 1;next.m = s.m + (i - j);next.c = s.c + j;next.dep = s.dep + 1;if (!isExist(next))//判断当前路径是否存在该状态dfs(next);}}}Set.erase(--Set.end());//无路可走,进行回退
}int main()
{cout << "请输入传教士(野人)人数:";cin >> n;cout << endl;cout << "请输入船的载人量:";cin >> c;State start;//初始状态start.m = start.c = n;start.boat = 1;start.dep = 0;dfs(start);cout << "Successed or Failed?:";if (path == 0)cout << "failed" << endl;else{cout << "Successed" << endl;output();cout << "共有" << path << "条路径。" << endl;cout << "min_deep=" << min_deep << endl;}
}
(5)实验结果讨论。
这是n=2,c=2的情况,共有四种情况的最短路径,最短路径为5
这是n=3,c=2的情况,共有四种情况的最短路径,最短路径为11
3 汉诺塔问题
汉诺塔问题来自一个古老的传说:在世界刚被创建的时候有一座钻石宝塔(塔A),其上有64个金碟。所有碟子按从大到小的次序从塔底堆放至塔顶。紧挨着这座塔有另外两个钻石宝塔(塔B和塔C)。从世界创始之日起,婆罗门的牧师们就一直在试图把塔A上的碟子移动到塔C上去,其间借助于塔B的帮助。每次只能移动一个碟子,任何时候都不能把一个碟子放在比它小的碟子上面。当牧师们完成任务时,世界末日也就到了。
采用问题归约法把汉诺塔问题分成以下三个步骤实现:
- 将塔A上的n-1个碟子借助塔C先移到塔B上
- 把塔A上剩下的一个碟子移到塔C上
- 把n-1个碟子从塔B借助于塔A移到塔C上
实验要求:
- 让盘子数从2 开始到7进行实验,记录程序运行时间和递归调用次数。
2.画出盘子数n和运行时间t 、递归调用次数m的关系图,并进行分析
分析:
运行时间 vs 盘子数(n): 通常来说,汉诺塔问题的解决时间呈指数增长。图表中应该看到一个指数曲线,显示随着盘子数的增加,解决问题所需的时间迅速增加。但是运行时间都太短了,看不出明显趋势。
递归调用次数 vs 盘子数(n): 递归调用次数也是指数级增长的,因为每增加一个盘子,递归调用次数就翻倍。这与汉诺塔问题的递归性质相一致。
在解决类似指数级增长问题时,递归算法可能会面临的性能挑战。
实验代码:
import timedef hanoi(n, source, target, auxiliary):global recursive_callsif n > 0:recursive_calls += 1hanoi(n - 1, source, auxiliary, target)# 移动盘子# print(f"Move disk {n} from {source} to {target}")hanoi(n - 1, auxiliary, target, source)def run_experiment(n):global recursive_callsrecursive_calls = 0start_time = time.time()hanoi(n, 'A', 'C', 'B')end_time = time.time()execution_time = end_time - start_timereturn execution_time, recursive_calls# 实验
results = []
for i in range(2, 8):time_taken, calls_made = run_experiment(i)results.append((i, time_taken, calls_made))# 打印结果
print("n\tTime(s)\tRecursive Calls")
for result in results:print(f"{result[0]}\t{result[1]:.6f}\t{result[2]}")import matplotlib.pyplot as pltdef plot_results(results):n_values = [result[0] for result in results]time_values = [result[1] for result in results]calls_values = [result[2] for result in results]# Plotting time vs nplt.figure(figsize=(10, 5))plt.subplot(1, 2, 1)plt.plot(n_values, time_values, marker='o')plt.title('Time vs Number of Disks')plt.xlabel('Number of Disks (n)')plt.ylabel('Time (s)')# Plotting recursive calls vs nplt.subplot(1, 2, 2)plt.plot(n_values, calls_values, marker='o', color='r')plt.title('Recursive Calls vs Number of Disks')plt.xlabel('Number of Disks (n)')plt.ylabel('Recursive Calls')plt.tight_layout()plt.show()# 实验
results = []
for i in range(2, 8):time_taken, calls_made = run_experiment(i)results.append((i, time_taken, calls_made))# 绘制图表
plot_results(results)
相关文章:
人工智能原理实验一:知识的表示与推理实验
一、实验目的 本实验课程是计算机、智能、物联网等专业学生的一门专业课程,通过实验,帮助学生更好地掌握人工智能相关概念、技术、原理、应用等;通过实验提高学生编写实验报告、总结实验结果的能力;使学生对智能程序、智能算法等有…...
自学C语言——VS实用调试技巧总结
接上一篇:自学C语言——扫雷游戏(无递归) 什么是bug “bug”本意是昆虫或虫子,一般指电脑系统或程序中,隐藏着一些未被发现的缺陷或者问题,简称程序漏洞。 第一代的计算机是由许多庞大且昂贵的真空管组成&…...
VC2012创建弹出式菜单
首先为视类添加鼠标右键单击处理函数,添加如下代码, void CMFCApplication1View::OnRButtonDown(UINT nFlags, CPoint point) {// TODO: 在此添加消息处理程序代码和/或调用默认值CView::OnRButtonDown(nFlags, point);CMenu menu;menu.CreatePopupMenu…...
Google 第三季度季报出炉
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
入职总结(更新中)
【STEP 1/3】短信1之后:材料准备阶段 填写 新进教职工“入职一件事”线上办理 系统档案转递证明(需档案到校); 档案:为规范管理,请拟报到人员将个人档案寄至浙江财经大学人事处,有专职人员进行…...
@DeleteMapping和@PostMapping和@GetMapping和Content-Type使用记录
代码例子,有注释大家可以自己试一下 RestController RequestMapping(value "demo") public class TestController {//Content-Type:application/x-www-form-urlencoded;表单提交form-dataPostMapping("/demo1")public String test…...
unity 中使用zeroMq和Mqtt 进行通讯
最近我在做一个车上的HMI项目,也就是车机应用,需要与云端和域控进行通信。HMI的功能已经外包了,但消息的统一层留给我自己来做。因为项目组其他人都没有经验,所以这个任务就落到了我头上,尽管我自己也没有太多经验&…...
四、k8s快速入门之Kubernetes资源清单
kubernetes中的资源 ⭐️ k8s中所有的内容都抽象为资源,资源实列化之后,叫做对象 1️⃣名称空间级别 ⭐️ kubeadm在执行k8s的pod的时候会在kube-system这个名称空间下执行,所以说当你kubectl get pod 的时候是查看不到的查看的是默认的po…...
掌握ElasticSearch(六):分析过程
文章目录 一、什么是分析1. 字符过滤 (Character Filtering)2. 分词 (Breaking into Tokens)3. 词条过滤 (Token Filtering)4. 词条索引 (Token Indexing) 二、内置分析器分类1. 标准分析器 (Standard Analyzer)2. 简单分析器 (Simple Analyzer)3. 语言分析器 (Language Analyz…...
【设计模式】使用python 实践框架设计
单一职责原则(SRP):一个类应该只有一个职责,意味着该类只应该有一个引起变化的原因。这使得代码更易于维护和理解。 开放封闭原则(OCP):软件实体(类、模块、函数等)应该…...
Apache paimon-CDC
CDC集成 paimon支持五种方式通过模式转化数据提取到paimon表中。添加的列会实时同步到Paimon表中 MySQL同步表:将MySQL中的一张或多张表同步到一张Paimon表中。MySQL同步数据库:将MySQL的整个数据库同步到一个Paimon数据库中。API同步表:将您的自定义DataStream输入同步到一…...
如何分析算法的执行效率和资源消耗
分析算法的执行效率和资源消耗可以从以下几个方面入手: 一、时间复杂度分析 定义和概念 时间复杂度是衡量算法执行时间随输入规模增长的速度的指标。它通常用大 O 符号表示,表示算法执行时间与输入规模之间的关系。例如,一个算法的时间复杂度为 O(n),表示该算法的执行时间…...
提示工程(Prompt Engineering)指南(进阶篇)
在 Prompt Engineering 的进阶阶段,我们着重关注提示的结构化、复杂任务的分解、反馈循环以及模型的高级特性利用。随着生成式 AI 技术的快速发展,Prompt Engineering 已经从基础的单一指令优化转向了更具系统性的设计思维,并应用于多轮对话、…...
音视频入门基础:FLV专题(19)——FFmpeg源码中,解码Audio Tag的AudioTagHeader,并提取AUDIODATA的实现
一、引言 从《音视频入门基础:FLV专题(18)——Audio Tag简介》可以知道,未加密的情况下,FLV文件中的一个Audio Tag Tag header AudioTagHeader AUDIODATA。本文讲述FFmpeg源码中是怎样解码Audio Tag的AudioTagHead…...
前端零基础入门到上班:【Day3】从零开始构建网页骨架HTML
HTML 基础入门:从零开始构建网页骨架 目录 1. 什么是 HTML?HTML 的核心作用 2. HTML 基本结构2.1 DOCTYPE 声明2.2 <html> 标签2.3 <head> 标签2.4 <body> 标签 3. HTML 常用标签详解3.1 标题标签3.2 段落和文本标签3.3 链接标签3.4 图…...
字符脱敏工具类
1、字符脱敏工具类 import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils;/*** 数据脱敏工具类** date 2024/10/30 13:44*/Slf4j public class DataDesensitizationUtils {public static final String STAR_1 "*";public static final …...
【jvm】jvm对象都分配在堆上吗
目录 1. 说明2. 堆上分配3. 栈上分配(逃逸分析和标量替换)4. 方法区分配5. 直接内存(非堆内存) 1. 说明 1.JVM的对象并不总是分配在堆上。2.堆是JVM用于存储对象实例的主要内存区域,存在一些特殊情况,对象…...
@AutoWired和 @Resource原理深度分析!
嗨,你好呀,我是猿java Autowired和Resource是 Java程序员经常用来实现依赖注入的两个注解,这篇文章,我们将详细分析这两个注解的工作原理、使用示例和它们之间的对比。 依赖注入概述 依赖注入是一种常见的设计模式,…...
C++设计模式创建型模式———原型模式
文章目录 一、引言二、原型模式三、总结 一、引言 与工厂模式相同,原型模式(Prototype)也是创建型模式。原型模式通过一个对象(原型对象)克隆出多个一模一样的对象。实际上,该模式与其说是一种设计模式&am…...
重学SpringBoot3-Spring WebFlux之SSE服务器发送事件
更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ Spring WebFlux之SSE服务器发送事件 1. 什么是 SSE?2. Spring Boot 3 响应式编程与 SSE为什么选择响应式编程实现 SSE? 3. 实现 SSE 的基本步骤3.…...
YOLO即插即用模块---AgentAttention
Agent Attention: On the Integration of Softmax and Linear Attention 论文地址:https://arxiv.org/pdf/2312.08874 问题: 普遍使用的 Softmax 注意力机制在视觉 Transformer 模型中计算复杂度过高,限制了其在各种场景中的应用。 方法&a…...
探索开源语音识别的未来:高效利用先进的自动语音识别技术20241030
🚀 探索开源语音识别的未来:高效利用自动语音识别技术 🌟 引言 在数字化时代,语音识别技术正在引领人机交互的新潮流,为各行业带来了颠覆性的改变。开源的自动语音识别(ASR)系统,如…...
学习路之TP6--workman安装
一、安装 首先通过 composer 安装 composer require topthink/think-worker 报错: 分析:最新版本需要TP8,或装低版本的 composer require topthink/think-worker:^3.*安装后, 增加目录 vendor\workerman vendor\topthink\think-w…...
.NET内网实战:通过白名单文件反序列化漏洞绕过UAC
01阅读须知 此文所节选自小报童《.NET 内网实战攻防》专栏,主要内容有.NET在各个内网渗透阶段与Windows系统交互的方式和技巧,对内网和后渗透感兴趣的朋友们可以订阅该电子报刊,解锁更多的报刊内容。 02基本介绍 03原理分析 在渗透测试和红…...
AI Agents - 自动化项目:计划、评估和分配
Agents: Role 角色Goal 目标Backstory 背景故事 Tasks: Description 描述Expected Output 期望输出Agent 代理 Automated Project: Planning, Estimation, and Allocation Initial Imports 1.本地文件helper.py # Add your utilities or helper functions to…...
Git的.gitignore文件
一、各语言对应的.gitignore模板文件 项目地址:https://github.com/github/gitignore 二、.gitignore文件不生效 .gitignore文件只是ignore没有被追踪的文件,已被追踪的文件,要先删除缓存文件。 # 单个文件 git rm --cached file/path/to…...
网站安全,WAF网站保护暴力破解
雷池的核心功能 通过过滤和监控 Web 应用与互联网之间的 HTTP 流量,功能包括: SQL 注入保护:防止恶意 SQL 代码的注入,保护网站数据安全。跨站脚本攻击 (XSS):阻止攻击者在用户浏览器中执行恶意脚本。暴力破解防护&a…...
深度学习:梯度下降算法简介
梯度下降算法简介 梯度下降算法 我们思考这样一个问题,现在需要用一条直线来回归拟合这三个点,直线的方程是 y w ^ x b y \hat{w}x b yw^xb,我们假设斜率 w ^ \hat{w} w^是已知的,现在想要找到一个最好的截距 b b b。 一条…...
SparkSQL整合Hive后,如何启动hiveserver2服务
当spark sql与hive整合后,我们就无法启动hiveserver2的服务了,每次都要先启动hive的元数据服务(nohup hive --service metastore)才能启动hive,之前的beeline命令也用不了,hiveserver2的无法启动,这也导致我…...
前端路由如何从0开始配置?vue-router 的使用
在 Web 开发中,路由是指根据 URL 的不同部分将请求分发到不同的处理函数或页面的过程。路由是单页应用(SPA, Single Page Application)和服务器端渲染(SSR, Server-Side Rendering)应用中的一个重要概念。 在开发中如何…...
做面食网站/seo难不难
Elite Sybil Attacks in User-Review Social Networks 之前阅读的论文都是关于Online Social Networks(在线社交网络)中的 Malicious Account Detction(恶意用户检测),这次的这篇也是Social Network,不过不…...
企业网站管理系统如何上传图片/东莞seo整站优化火速
题意: 给一个有向图,问该图是不是强连通图,且图中每条边仅属于一个环。 分析: 如果一个节点已经在栈中,当该点被访问到即又出现了一条连向该点的横向边,且该点不是根节点,这条边 就是一条属于两…...
全国建设地产网站/seo首页网站
判断App版本号/iOS系统版本号/4gWiFi环境判断当前设备类型://判断当前设备的类型改变左右两边约束的距离if([UIDevice currentDevice].userInterfaceIdiom UIUserInterfaceIdiomPhone){self.leftConstraint.constant 10;self.rightConstraint.constant 10;}判断是否是横屏: 1.i…...
慈溪想做网站的公司/快速推广
Python 2.x的官方支持要到2020就截止了,djagon 2.0以上的版本则明确不支持python 2.7版本,需要python 3.5,而有的项目有的需要兼容性,比如要连接Mysql数据库的第三方库, Python 2.x使用的是MySQLdb模块,Pyt…...
网站开发助理工程师/郑州seo顾问培训
1. 前言 Druid 的目标是提供一个能够在大数据集上做实时数据摄入与查询的平台,然而对于大多数系统而言,提供数据的快速摄入与提供快速查询是难以同时实现的两个指标。例如对于普通的RDBMS,如果想要获取更快的查询速度,就会因为创建索引而牺牲…...
合肥的网站建设/营销方案案例
## 字符串比较python 字符串的比较法则:从左至右每个字符依据ASCII码值进行比较,直至比较出结果,返回结果,结束。 ## 形参与实参python 实参:具有实际意义,有具体类型,在函数调用的时候…...