基于遗传算法的试题组卷(二)

实例讲解
在这里插入图片描述
在这里插入图片描述
一、准备工作
1、问题实体
问题实体包含编号、类型(类型即题型,分为五种:单选,多选,判断,填空,问答, 分别用1、2、3、4、5表示)、分数、难度系数、知识点。一道题至少有一个知识点,为简单易懂,知识点用List 表示(知识点编号集合)。
代码如下:

public class Problem 
{public Problem(){ID = 0;Type = 0;Score = 0;Difficulty = 0.00;Points = new List<int>();}public Problem(Problem p){this.ID = p.ID;this.Type = p.Type;this.Score = p.Score;this.Difficulty = p.Difficulty;this.Points = p.Points;}/// <summary>/// 编号/// </summary>public int ID { get; set; }/// <summary>/// 题型(1、2、3、4、5对应单选,多选,判断,填空,问答)/// </summary>public int Type { get; set; }/// <summary>/// 分数/// </summary>public int Score { get; set; }/// <summary>/// 难度系数/// </summary>public double Difficulty { get; set; }/// <summary>/// 知识点/// </summary>public List<int> Points { get; set; }} 

2、题库
为了简单,这里没有用数据库,题目信息临时创建,保存在内存中。因为对不同层次的考生一道题目在不同试卷中的分数可能不一样,因此题目分数一般是老师出卷时定的,不保存在题库中。且单选,多选,判断题每题分数应该相同,填空题一般根据空数来定分数,而问答题一般根据题目难度来定的,因此这里的单选、多选、判断分数相同,填空空数取1-4间的随机数,填空题分数即为空数,问答题即为该题难度系数*10取整。这里各种题型均为1000题,具体应用时改为数据库即可。
代码如下:

public class DB
{/// <summary>/// 题库/// </summary>public List<Problem> ProblemDB;public DB(){ProblemDB = new List<Problem>();Problem model;Random rand = new Random();List<int> Points;for (int i = 1; i <= 5000; i++){model = new Problem();model.ID = i;//试题难度系数取0.3到1之间的随机值model.Difficulty = rand.Next(30, 100) * 0.01;//单选题1分if (i < 1001){model.Type = 1;model.Score = 1;}//单选题2分if (i > 1000 && i < 2001){model.Type = 2;model.Score = 2;}//判断题2分if (i > 2000 && i < 3001){model.Type = 3;model.Score = 2;}//填空题1—4分if (i > 3000 && i < 4001){model.Type = 4;model.Score = rand.Next(1, 5);}//问答题分数为难度系数*10if (i > 4000 && i < 5001){model.Type = 5;model.Score = model.Difficulty > 0.3 ? (int)(double.Parse(model.Difficulty.ToString("f1")) * 10) : 3;}Points = new List<int>();//每题1到4个知识点int count = rand.Next(1, 5);for (int j = 0; j < count; j++){Points.Add(rand.Next(1, 100));}model.Points = Points;ProblemDB.Add(model);}}
} 

3、 试卷实体
试卷一般包含试卷编号,试卷名称,考试时间,难度系数,知识点分布,总题数, 总分数,各种题型所占比率等属性,这里为简单去掉了试卷名称跟考试时间。其中的知识点分布即老师出卷时选定本试卷要考查的知识点,这里用List(知识点编号集合)表示。
代码如下:

public class Paper
{/// <summary>/// 编号/// </summary>public int ID { get; set; }/// <summary>/// 总分/// </summary>public int TotalScore { get; set; }/// <summary>/// 难度系数/// </summary>public double Difficulty { get; set; }/// <summary>/// 知识点/// </summary>public List<int> Points { get; set; }/// <summary>/// 各种题型题数/// </summary>public int[] EachTypeCount { get; set; }
} 

二、开始遗传算法组卷之旅

  准备工作已经OK,下面就按上一篇介绍的流程进行操作啦!

1、产生初始种群
这里保证题数跟总分达到出卷要求即可,但为操作方便,这里再定义一个种群个体实体类Unit,包含编号、适应度、题数、总分、难度系数、知识点分布、包含的题目等信息(也可以修改一下试卷实体,用试卷实体表示):

public class Unit{public Unit(){ID = 0;AdaptationDegree = 0.00;KPCoverage = 0.00;ProblemList = new List<Problem>();}/// <summary>/// 编号/// </summary>public int ID { get; set; }/// <summary>/// 适应度/// </summary>public double AdaptationDegree { get; set; }/// <summary>/// 难度系数(本试卷所有题目分数*难度系数/总分)/// </summary>public double Difficulty{get{double diff = 0.00;ProblemList.ForEach(delegate(Problem p){diff += p.Difficulty * p.Score;});return diff / SumScore;}}/// <summary>/// 题目数量/// </summary>public int ProblemCount{get{return ProblemList.Count;}}/// <summary>/// 总分/// </summary>public int SumScore{get{int sum = 0;ProblemList.ForEach(delegate(Problem p){sum += p.Score;});return sum;}}/// <summary>/// 知识点分布/// </summary>public double KPCoverage { get; set; }/// <summary>/// 题目/// </summary>public List<Problem> ProblemList { get; set; }
}

下面即来产生初始种群,按个体数量,期望试卷知识点分布,各类型题目数等限制产生初始种群:

/// <summary>
/// 初始种群
/// </summary>
/// <param name="count">个体数量</param>
/// <param name="paper">期望试卷</param>
/// <param name="problemList">题库</param>
/// <returns>初始种群</returns>
public List<Unit> CSZQ(int count, Paper paper, List<Problem> problemList)
{List<Unit> unitList = new List<Unit>();int[] eachTypeCount = paper.EachTypeCount;Unit unit;Random rand = new Random();for (int i = 0; i < count; i++){unit = new Unit();unit.ID = i + 1;unit.AdaptationDegree = 0.00;//总分限制while (paper.TotalScore != unit.SumScore){unit.ProblemList.Clear();//各题型题目数量限制for (int j = 0; j < eachTypeCount.Length; j++){List<Problem> oneTypeProblem = problemList.Where(o => o.Type == (j + 1)).Where(p => IsContain(paper, p)).ToList();Problem temp = new Problem();for (int k = 0; k < eachTypeCount[j]; k++){//选择不重复的题目int index = rand.Next(0, oneTypeProblem.Count - k);unit.ProblemList.Add(oneTypeProblem[index]);temp = oneTypeProblem[oneTypeProblem.Count - 1 - k];oneTypeProblem[oneTypeProblem.Count - 1 - k] = oneTypeProblem[index];oneTypeProblem[index] = temp;}}}unitList.Add(unit);}//计算知识点覆盖率及适应度unitList = GetKPCoverage(unitList, paper);unitList = GetAdaptationDegree(unitList, paper, kpcoverage, difficulty);return unitList;
} 

2、计算种群个体的适应度
在上面的代码中最后调用了两个方法,GetKPCoverage跟GetAdaptationDegree,这两个方法分别是计算种群中个体的知识点覆盖率跟适应度。

关于种群个体的知识点覆盖率在上一篇文章中已经说过了(知识点分布用一个个体知识点的覆盖率来衡量,例如期望本试卷包含N个知识点,而一个个体中所有题目知识点的并集中包含M个(M<=N),则知识点的覆盖率为M/N。),具体算法如下:

/// <summary>/// 计算知识点覆盖率
/// </summary>
/// <param name="unitList">种群</param>
/// <param name="paper">期望试卷</param>
/// <returns>List</returns>
public List<Unit> GetKPCoverage(List<Unit> unitList, Paper paper)
{List<int> kp;for (int i = 0; i < unitList.Count; i++){kp = new List<int>();unitList[i].ProblemList.ForEach(delegate(Problem p){kp.AddRange(p.Points);});//个体所有题目知识点并集跟期望试卷知识点交集var common = kp.Intersect(paper.Points);unitList[i].KPCoverage = common.Count() * 1.00 / paper.Points.Count;}return unitList;
}

适应度方法的确定上一篇文章里已经说过,即:
f=1-(1-M/N)*f1-|EP-P|*f2

其中M/N为知识点覆盖率,EP为期望难度系数,P为种群个体难度系数,f1为知识点分布的权重,f2为难度系数所占权重。当f1=0时退化为只限制试题难度系数,当f2=0时退化为只限制知识点分布。 实现代码如下:

/// <summary>/// 计算种群适应度
/// </summary>
/// <param name="unitList">种群</param>
/// <param name="paper">期望试卷</param>
/// <param name="KPCoverage">知识点分布在适应度计算中所占权重</param>
/// <param name="Difficulty">试卷难度系数在适应度计算中所占权重</param>
/// <returns>List</returns>
public List<Unit> GetAdaptationDegree(List<Unit> unitList, Paper paper, double KPCoverage, double Difficulty)
{unitList = GetKPCoverage(unitList, paper);for (int i = 0; i < unitList.Count; i++){unitList[i].AdaptationDegree = 1 - (1 - unitList[i].KPCoverage) * KPCoverage - Math.Abs(unitList[i].Difficulty - paper.Difficulty) * Difficulty;}return unitList;
}

3、选择算子
这里选择算子采用轮盘赌选择法,即适应度越大的被选择到的概率越大。比如说种群中有20个个体,那么每个个体的适应度除以20个个体适应度的和得到的就是该个体的被选择的概率。轮盘赌选择时,每个个体类似于轮盘中的一小块扇形,扇形的大小与该个体被选择的概率成正比。那么,扇形越大的个体被选择的概率越大。这就是轮盘赌选择法。 算法实现代码如下:

/// <summary>
/// 选择算子(轮盘赌选择)
/// </summary>
/// <param name="unitList">种群</param>
/// <param name="count">选择次数</param>
/// <returns>进入下一代的种群</returns>
public List<Unit> Select(List<Unit> unitList, int count)
{List<Unit> selectedUnitList = new List<Unit>();//种群个体适应度和double AllAdaptationDegree = 0;unitList.ForEach(delegate(Unit u){AllAdaptationDegree += u.AdaptationDegree;});Random rand = new Random();while (selectedUnitList.Count != count){//选择一个0—1的随机数字double degree = 0.00;double randDegree = rand.Next(1, 100) * 0.01 * AllAdaptationDegree;//选择符合要求的个体for (int j = 0; j < unitList.Count; j++){degree += unitList[j].AdaptationDegree;if (degree >= randDegree){//不重复选择if (!selectedUnitList.Contains(unitList[j])){selectedUnitList.Add(unitList[j]);}break;}}}return selectedUnitList;
} 

4、交叉算子
交叉算子在上一篇也做了说明,写程序时为方便略做了一点更改,即把多点交叉改为单点交叉。在交叉过程在有几个地方需要注意,一是要保正总分不变,二是保证交叉后没有重复个体,算法实现如下:

   /// <summary>/// 交叉算子/// </summary>/// <param name="unitList">种群</param>/// <param name="count">交叉后产生的新种群个体数量</param>/// <param name="paper">期望试卷</param>/// <returns>List</returns>public List<Unit> Cross(List<Unit> unitList, int count, Paper paper){List<Unit> crossedUnitList = new List<Unit>();Random rand = new Random();while (crossedUnitList.Count != count){//随机选择两个个体int indexOne = rand.Next(0, unitList.Count);int indexTwo = rand.Next(0, unitList.Count);Unit unitOne;Unit unitTwo;if (indexOne != indexTwo){unitOne = unitList[indexOne];unitTwo = unitList[indexTwo];//随机选择一个交叉位置int crossPosition = rand.Next(0, unitOne.ProblemCount - 2);//保证交叉的题目分数合相同double scoreOne = unitOne.ProblemList[crossPosition].Score + unitOne.ProblemList[crossPosition + 1].Score;double scoreTwo = unitTwo.ProblemList[crossPosition].Score + unitTwo.ProblemList[crossPosition + 1].Score;if (scoreOne == scoreTwo){//两个新个体Unit unitNewOne = new Unit();unitNewOne.ProblemList.AddRange(unitOne.ProblemList);Unit unitNewTwo = new Unit();unitNewTwo.ProblemList.AddRange(unitTwo.ProblemList);//交换交叉位置后面两道题for (int i = crossPosition; i < crossPosition + 2; i++){unitNewOne.ProblemList[i] = new Problem(unitTwo.ProblemList[i]);unitNewTwo.ProblemList[i] = new Problem(unitOne.ProblemList[i]);}//添加到新种群集合中unitNewOne.ID = crossedUnitList.Count;unitNewTwo.ID = unitNewOne.ID + 1;if (crossedUnitList.Count < count){crossedUnitList.Add(unitNewOne);}if (crossedUnitList.Count < count){crossedUnitList.Add(unitNewTwo);}}}//过滤重复个体crossedUnitList = crossedUnitList.Distinct(new ProblemComparer()).ToList();}//计算知识点覆盖率及适应度crossedUnitList = GetKPCoverage(crossedUnitList, paper);crossedUnitList = GetAdaptationDegree(crossedUnitList, paper, kpcoverage, difficulty);return crossedUnitList;}

上面过滤重复个体中用到了ProblemComparer类,这是一个自定义的比较类,代码如下:

 public class ProblemComparer : IEqualityComparer<Unit>{public bool Equals(Unit x, Unit y){bool result = true;for (int i = 0; i < x.ProblemList.Count; i++){if (x.ProblemList[i].ID != y.ProblemList[i].ID){result = false;break;}}return result;}public int GetHashCode(Unit obj){return obj.ToString().GetHashCode();}
}

5、 变异算子
在变异过程中主要是要保证替换题目至少包含一个被替换题的有效知识点(期望试卷中也包含此知识点),并要类型相同,分数相同而题号不同。 算法实现代码如下:

/// <summary>
/// 变异算子
/// </summary>
/// <param name="unitList">种群</param>
/// <param name="problemList">题库</param>
/// <param name="paper">期望试卷</param>
/// <returns>List</returns>
public List<Unit> Change(List<Unit> unitList, List<Problem> problemList, Paper paper)
{Random rand = new Random();int index = 0;unitList.ForEach(delegate(Unit u){//随机选择一道题index = rand.Next(0, u.ProblemList.Count);Problem temp = u.ProblemList[index];//得到这道题的知识点Problem problem = new Problem();for (int i = 0; i < temp.Points.Count; i++){if (paper.Points.Contains(temp.Points[i])){problem.Points.Add(temp.Points[i]);}}//从数据库中选择包含此题有效知识点的同类型同分数不同题号试题var otherDB = from a in problemListwhere a.Points.Intersect(problem.Points).Count() > 0select a;List<Problem> smallDB = otherDB.Where(p => IsContain(paper, p)).Where(o => o.Score == temp.Score && o.Type == temp.Type && o.ID != temp.ID).ToList();//从符合要求的试题中随机选一题替换if (smallDB.Count > 0){int changeIndex = rand.Next(0, smallDB.Count);u.ProblemList[index] = smallDB[changeIndex];}});//计算知识点覆盖率跟适应度unitList = GetKPCoverage(unitList, paper);unitList = GetAdaptationDegree(unitList, paper, kpcoverage, difficulty);return unitList;
} 

遗传算法主要算法上面都已实现,现在就是调用了。调用过程按如下流程图进行:
在这里插入图片描述
这里初始种群大小设定为20,最大迭代次数为500,适应度为0.98,选择算子选择次数为10次,交叉算子产生的个体数量为20,期望试卷难度系数为0.72,总分为100分,各种题型题数为:20(单选), 5(多选), 10(判断), 7(填空), 5(问答),包含的知识点为:1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81。代码如下:

  /// <summary>/// 调用示例/// </summary>public void Show(){//题库DB db = new DB();//期望试卷Paper paper = new Paper(){ID = 1,TotalScore = 100,Difficulty = 0.72,Points = new List<int>() { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81 },EachTypeCount = new[] { 20, 5, 10, 7, 5 }};//迭代次数计数器int count = 1;//适应度期望值double expand = 0.98;//最大迭代次数int runCount = 500;//初始化种群List<Unit> unitList = CSZQ(20, paper, db.ProblemDB);Console.WriteLine("\n\n      -------遗传算法组卷系统(http://www.cnblogs.com/durongjian/)---------\n\n");Console.WriteLine("初始种群:");ShowUnit(unitList);Console.WriteLine("-----------------------迭代开始------------------------");//开始迭代while (!IsEnd(unitList, expand)){Console.WriteLine("在第 " + (count++) + " 代未得到结果");if (count > runCount){Console.WriteLine("计算 " + runCount + " 代仍没有结果,请重新设计条件!");break;}//选择unitList = Select(unitList, 10);//交叉unitList = Cross(unitList, 20, paper);//是否可以结束(有符合要求试卷即可结束)if (IsEnd(unitList, expand)){break;}//变异unitList = Change(unitList, db.ProblemDB, paper);}if (count <= runCount){Console.WriteLine("在第 " + count + " 代得到结果,结果为:\n");Console.WriteLine("期望试卷难度:" + paper.Difficulty + "\n");ShowResult(unitList, expand);}} 
最后在控制台中调用此方法即可。 

7、其他辅助方法
在上面的代码中还调用了几个辅助方法,下面一并给出:

#region 是否达到目标/// <summary>/// 是否达到目标/// </summary>/// <param name="unitList">种群</param>/// <param name="endcondition">结束条件(适应度要求)</param>/// <returns>bool</returns>public bool IsEnd(List<Unit> unitList, double endcondition){if (unitList.Count > 0){for (int i = 0; i < unitList.Count; i++){if (unitList[i].AdaptationDegree >= endcondition){return true;}}}return false;}#endregion#region 显示结果/// <summary>/// 显示结果/// </summary>/// <param name="unitList">种群</param>/// <param name="expand">期望适应度</param>public void ShowResult(List<Unit> unitList, double expand){unitList.OrderBy(o => o.ID).ToList().ForEach(delegate(Unit u){if (u.AdaptationDegree >= expand){Console.WriteLine("第" + u.ID + "套:");Console.WriteLine("题目数量\t知识点分布\t难度系数\t适应度");Console.WriteLine(u.ProblemCount + "\t\t" + u.KPCoverage.ToString("f2") + "\t\t" + u.Difficulty.ToString("f2") + "\t\t" + u.AdaptationDegree.ToString("f2")+"\n\n");}});}#endregion#region 显示种群个体题目编号/// <summary>/// 显示种群个体题目编号/// </summary>/// <param name="u">种群个体</param>public void ShowUnit(Unit u){Console.WriteLine("编号\t知识点分布\t难度系数");Console.WriteLine(u.ID + "\t" + u.KPCoverage.ToString("f2") + "\t\t" + u.Difficulty.ToString("f2"));u.ProblemList.ForEach(delegate(Problem p){Console.Write(p.ID + "\t");});Console.WriteLine();}#endregion 
#region 题目知识点是否符合试卷要求
/// <summary>
/// 题目知识点是否符合试卷要求
/// </summary>
/// <param name="paper">期望试卷</param>
/// <param name="problem">一首试题</param>
/// <returns>bool</returns>
private bool IsContain(Paper paper, Problem problem)
{for (int i = 0; i < problem.Points.Count; i++){if (paper.Points.Contains(problem.Points[i])){return true;}}return false;
}
#endregion

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

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

相关文章

C++ 智能指针

C 智能指针 为什么需要智能指针&#xff1f;auto_ptrunique_ptrshared_ptrweak_ptr智能指针的核心实现unique_ptr的简单实现Counter的简单实现share_ptr的简单实现weak_ptr简单实现 shared_ptr的线程安全性多线程无保护读写 shared_ptr 可能出现的问题make_shared()share_ptr/u…

卸载本机已安装的node.js(v.16.13.0版本)

因为要用多版本的node&#xff0c;准备安装一个nvm管理&#xff0c;所以需要先卸载掉原来安装的v.16.13.0版本。 记录一下卸载过程 1、在系统设置-应用里卸载node 妈蛋这样卸载报错。。找了下根本没有这个路径 那就只能最简单的方法了&#xff0c;全部删掉 1、删除node的安装…

IDEA用Gradle构建项目时,lombok插件无效的解决办法

Lombok 可用来帮助开发人员消除 Java 的重复代码&#xff0c;尤其是对于简单的 Java 对象&#xff08;POJO&#xff09;&#xff0c;比如说getter/setter/toString等方法的编写。它通过注解实现这一目的。 正确使用姿势 一、安装Lombok插件 菜单栏File -> Settings ->…

通过MySQL删除Hive元数据信息

之前遇到过一个问题&#xff0c;在进行Hive的元数据采集时&#xff0c;因为Hive表的文件已经被删除了&#xff0c;当时是无法删除表&#xff0c;导致元数据采集也发生了问题&#xff0c;所以希望通过删除Hive表的元数据解决上述问题。 之前安装时&#xff0c;经过特定的配置后…

Qt实现自定义QDoubleSpinBox软键盘

在Qt应用程序开发中&#xff0c;经常会遇到需要自定义输入控件的需求。其中&#xff0c;对于QDoubleSpinBox控件&#xff0c;如果希望在点击时弹出一个自定义的软键盘&#xff0c;以便用户输入数值&#xff0c;并将输入的值设置给QDoubleSpinBox&#xff0c;该如何实现呢&#…

【MySQL】MySQL数据类型

文章目录 一、数据类型的分类二、tinyint类型2.1 创建有符号数值2.2 创建无符号数值 三、bit类型三、浮点类型3.1 float3.2 decimal类型 四、字符串类型4.1 char类型4.2 varchar类型 五、日期和时间类型六、枚举和集合类型6.1 enum的枚举值和set的位图结构6.2 查询集合find_in_…

大数据技术之Clickhouse---入门篇---SQL操作、副本

星光下的赶路人star的个人主页 积一勺以成江河&#xff0c;累微尘以崇峻极 文章目录 1、SQL操作1.1 Insert1.2 Update 和 Delete1.3 查询操作1.4 alter操作1.5 导出数据 2、副本2.1 副本写入流程2.2 配置步骤 1、SQL操作 基本上来说传统关系型数据库&#xff08;以 MySQL 为例…

Java 使用 Google Guava 实现接口限流

一、引入依赖 <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.0-jre</version> </dependency>二、自定义注解及限流拦截器 自定义注解&#xff1a;Limiter package com.haita…

linux 常用命令

防火墙 1.查看下防火墙的状态&#xff1a;systemctl status firewalld systemctl stop firewalld 关闭 systemctl disable firewalld 开机不启永久关闭 2.查看已开放的端口firewall-cmd --zonepublic --list-ports firewall-cmd --permanent --zonepublic --…

【Android Framework系列】第9章 AMS之Hook实现登录页跳转

1 前言 前面章节我们学习了【Android Framework系列】第5章 AMS启动流程和【Android Framework系列】第6章 AMS原理之Launcher启动流程&#xff0c;大概了解了AMS的原理及启动流程&#xff0c;这一章节我们通过反射和动态代理对不同Android版本下的AMS进行Hook&#xff0c;实现…

SpringCloudAlibaba:服务网关之Gateway的cors跨域问题

目录 一&#xff1a;解决问题 二&#xff1a;什么是跨域 三&#xff1a;cors跨域是什么&#xff1f; 一&#xff1a;解决问题 遇到错误&#xff1a; 前端请求时报错 解决&#xff1a; 网关中添加配置文件&#xff0c;注意springboot版本&#xff0c;添加配置。 springboo…

【FPGA IP系列】FIFO的通俗理解

FPGA厂商提供了丰富的IP核&#xff0c;基础性IP核都是可以直接免费调用的&#xff0c;比如FIFO、RAM等等。 本文主要介绍FIFO的一些基础知识&#xff0c;帮助大家能够理解FIFO的基础概念。 一、FIFO介绍 FIFO全称是First In First Out&#xff0c;即先进先出。 FIFO是一个数…

Go学习第三天

map的三种声明定义方式 声明map后&#xff0c;一定要make开辟空间&#xff0c;否则会报越界且不能使用 package mainimport "fmt"func main() {// 第一种声明方式// 声明myMap1是一种map类型 key是string value是stringvar myMap1 map[string]string// 判断一下map在…

ad+硬件每日学习十个知识点(20)23.7.31 (芯片和天线间的巴伦电路)

文章目录 1.什么是前端电路&#xff1f;2.什么是巴伦电路&#xff1f;3.巴伦电路的性能参数4.LC巴伦电路5.ADS是干什么的&#xff1f;6.HFSS是干什么的&#xff1f;7.ANSYS有限元软件8.常用的电路仿真软件都有什么&#xff1f;9.巴伦电路的复端阻抗LC10.微带巴伦&#xff08;不…

数据可视化(七)常用图表的绘制

1. #seaborn绘制常用图表 #折线图 #replot&#xff08;x&#xff0c;y&#xff0c;kind&#xff0c;data&#xff09; #lineplot&#xff08;x&#xff0c;y&#xff0c;data&#xff09; #直方图 #displot&#xff08;data&#xff0c;rug&#xff09; #条形图 #barplot&…

【雕爷学编程】 MicroPython动手做(35)——体验小游戏

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

机器学习笔记之优化算法(九)收敛速度的简单认识

机器学习笔记之优化算法——收敛速度的简单认识 引言收敛速度的判别标准 Q \mathcal Q Q-收敛速度 R \mathcal R R-收敛速度关于算法复杂度与收敛速度 引言 本节对收敛速度简单介绍。 收敛速度的判别标准 我们之前几节介绍了线搜索方法 ( Line Search Method ) (\text{Line …

bash的特性(二)IO重定向与管道

bash的I/O重定向及管道 一、概述 在shell中&#xff0c;最常使用的fd(file descriptor)有三个&#xff0c;标准输入&#xff0c;标准输出&#xff0c;错误输出。进程用文件描述符来管理打开的文件。 名称 文件描述符 标准输入&#xff08;stdin) 0 键盘&#xff0c;也可以…

【BEV感知】3-BEV开源数据集

3-BEV开源数据集 1 KITTI1.1 KITTI数据怎么采集?1.2 KITTI数据规模有多大?1.3 KITTI标注了哪些目标?1.4 转换矩阵1.5 标签文件 2 nuScenes2.1 nuScenes Vs KITTI2.2 标注文件 1 KITTI KITTI 1.1 KITTI数据怎么采集? 通过车载相机、激光雷达等传感器采集。 只提供了相机正…

【BEV感知】1-BEV感知算法介绍

1-BEV感知算法介绍 1 什么是BEV感知算法&#xff1f;1.1 什么是BEV&#xff1f;1.2 什么是感知&#xff1f;1.3 什么是算法&#xff1f;1.4 什么是BEV感知&#xff1f; 1 什么是BEV感知算法&#xff1f; 1.1 什么是BEV&#xff1f; Bird’s-Eye-View&#xff0c;尺度变化小、…