自动驾驶定位算法-粒子滤波(Particle Filter)

自动驾驶定位算法-粒子滤波(Particle Filter)

自动驾驶对定位的精度的要求在厘米级的,如何实现厘米级的高精度定位呢?一种众所周知的定位方法是利用全球定位系统(GPS),利用多颗卫星的测量结果,通过三角测量(Triangulation)机制确定目标的位置,GPS定位的原理见:https://blog.csdn.net/liuphahaha/article/details/137609080?spm=1001.2014.3001.5501

image

附赠自动驾驶学习资料和量产经验:链接

但是GPS并不总是提供高精度定位数据,在GPS信号强的情况下,定位精度在13m范围内,在GPS信号弱的情况下,定位精度下降到1050m范围内。虽然依赖于RTK,可以将卫星定位的精度提高到厘米级,但是在GPS信号弱的场景下,定位精度仍然不能满足应用需求。所以仅仅使用GPS不能实现高可靠的高精度定位的。

为了达到厘米级(3-10cm)的定位精度,除了GPS之外,还需要借助于其它传感器,如激光传感器(LIDAR)、径向距离和角度传感器(Radial distance and angle sensor,RADAR)、视觉传感器(Camera)等,然后利用特定的算法将这些信息融合起来。粒子滤波(Particle Filter)就是利用这些传感器产生的数据进行高精定位的一种常用方法。

image

Particle Filters From Udacity Lecture

1.粒子滤波(Particle Filter)的算法思想

相对之前提到的标准卡尔曼滤波,粒子滤波(Particle Filter)没有线性高斯分布的假设;相对于直方图滤波,粒子滤波(Particle Filter)不需要对状态空间进行区间划分。粒子滤波算法采用很多粒子对置信度 image进行近似,每个粒子都是对t时刻机器人实际状态的一个猜测。

image

越接近t时刻的Ground Truth状态描述的粒子,权重越高。

粒子更新的过程类似于达尔文的自然选择(Natural Selection)机制,与当前Sensor测量状态越匹配的粒子,有更大的机会生存下来,与Sensor测量结果不符的粒子会被淘汰掉,最终粒子都会集中在正确的状态附近。

2、粒子滤波算法在自动驾驶定位中的应用

以放置在封闭环境(Close Environment)中的自动驾驶车辆(Kidnapped Vehicle)为例,看它是如何通过粒子滤波(Particle Filter)确定自己所在的位置的。

image

2.1 先看看自动驾驶车辆有什么?

1)地图(Map)。每一辆自动驾驶汽车都配备了一幅高精度的地图,地图中包含了大量的地标(Landmark)的位置信息。地标(Landmark)是特定区域内的稳定特征,它们能够在相当长的一段时间内都保持不变,比如路边建筑物、杆状物等。

2)GPS。使用安装在车辆内部的GPS传感器设备,可以提供车辆在地图中的大概的位置范围。基于此局部性范围,仅选择全局地图的一部分用以匹配计算,从而避免大量的冗余计算,提升计算的时效性,从而达到实时定位的目的。

3)Lidar/Radar等传感器。安装在车辆上的Lidar/Radar传感器将测量其与地图路标(Landmark)之间的距离,从而进一步确定车辆的位置。但是Lidar/Radar的测量结果也不准确,存在测量噪声。

2.2 将所有传感器信息组合起来

通过粒子滤波(Particle Filter)将这些所有信息组合在一起,用于实现实时的高精度定位。

image

图片来源:https://github.com/sohonisaurabh/CarND-Kidnapped-Vehicle-Project

粒子滤波(Particle Filter)的主要步骤如下:

1)Initialisation Step:在初始化步骤中,根据GPS坐标输入估算位置,估算位置是存在噪声的,但是可以提供一个范围约束。

2)Prediction Step:在Prediction过程中,对所有粒子(Particles)增加车辆的控制输入(速度、角速度等),预测所有粒子的下一步位置。

3)Update Step:在Update过程中,根据地图中的Landmark位置和对应的测量距离来更新所有粒子(Particles)的权重。

4)Resample Step:根据粒子(Particles)的权重,对所有粒子(Particles)进行重采样,权重越高的粒子有更大的概率生存下来,权重越小的例子生存下来的概率就越低,从而达到优胜劣汰的目的。

2.3 粒子滤波代码实现

1)Initialisation Step:

初始化阶段,车辆接收到来自GPS的带噪声的测量值,并将其用于初始化车辆的位置。GPS的测量值包括车辆的位置P(x,y)和朝向θ,并且假设测量结果的噪声服从正态分布。

我们创建100个粒子,并用GPS的测量值初始化这些粒子的位置和朝向。粒子的个数是一个可调参数,可根据实际效果和实际需求调整。初始化时,所有粒子的权重相同。

void ParticleFilter::init(double x, double y, double theta, double std[]) {// TODO: Set the number of particles. Initialize all particles to first// position (based on estimates of//   x, y, theta and their uncertainties from GPS) and all weights to 1.// Add random Gaussian noise to each particle.// NOTE: Consult particle_filter.h for more information about this method (and// others in this file).// TODO Complete/*Number is particles are chosen in order to run the algorithm in almost realtime and introduce lowest possible error in localization. This is a tunableparameter.*/num_particles = 20;default_random_engine gen;normal_distribution<double> dist_x(x, std[0]);normal_distribution<double> dist_y(y, std[1]);normal_distribution<double> dist_theta(theta, std[2]);int i;for (i = 0; i < num_particles; i++) {Particle current_particle;current_particle.id = i;current_particle.x = dist_x(gen);current_particle.y = dist_y(gen);current_particle.theta = dist_theta(gen);current_particle.weight = 1.0;particles.push_back(current_particle);weights.push_back(current_particle.weight);}is_initialized = true;
}

2)Prediction Step

初始化完成之后,对所有粒子执行车辆运动模型,预测每个粒子下一步出现的位置。粒子的位置更新是通过以下公式完成:

image

图片来源:https://github.com/sohonisaurabh/CarND-Kidnapped-Vehicle-Project

车辆运动过程同样存在噪声,前面的文章提到到,比如车辆发出控制指令velocity=10m/s,但是由于设备测量误差、车轮打滑等原因,实际的运动速度可能大于10m/s,也可能小于10m/s,我们同样假设车辆运动噪声服从正态分布。

void ParticleFilter::prediction(double delta_t, double std_pos[],double velocity, double yaw_rate) {// TODO: Add measurements to each particle and add random Gaussian noise.// NOTE: When adding noise you may find std::normal_distribution and// std::default_random_engine useful.//  http://en.cppreference.com/w/cpp/numeric/random/normal_distribution//  http://www.cplusplus.com/reference/random/default_random_engine/// TODO completedefault_random_engine gen;int i;for (i = 0; i < num_particles; i++) {double particle_x = particles[i].x;double particle_y = particles[i].y;double particle_theta = particles[i].theta;double pred_x;double pred_y;double pred_theta;// Instead of a hard check of 0, adding a check for very low value of// yaw_rateif (fabs(yaw_rate) < 0.0001) {pred_x = particle_x + velocity * cos(particle_theta) * delta_t;pred_y = particle_y + velocity * sin(particle_theta) * delta_t;pred_theta = particle_theta;} else {pred_x = particle_x + (velocity / yaw_rate) *(sin(particle_theta + (yaw_rate * delta_t)) -sin(particle_theta));pred_y = particle_y + (velocity / yaw_rate) *(cos(particle_theta) -cos(particle_theta + (yaw_rate * delta_t)));pred_theta = particle_theta + (yaw_rate * delta_t);}normal_distribution<double> dist_x(pred_x, std_pos[0]);normal_distribution<double> dist_y(pred_y, std_pos[1]);normal_distribution<double> dist_theta(pred_theta, std_pos[2]);particles[i].x = dist_x(gen);particles[i].y = dist_y(gen);particles[i].theta = dist_theta(gen);}
}

3)Update Step

在预测过程中,我们将车辆的速度和角速度合并到粒子滤波器中,在更新过程中,我们将激光雷达(Lidar)/Radar对于Landmark的测量结果集成到粒子滤波(Particle Filter)中,用于更新所有粒子的权重。

Update Step包含三个主要步骤: a)Transformation;b)Association;c) Update Weights。

Transformation(坐标变换):Lidar/Radar对Landmark的测量都是相对于车辆自身坐标系统的,需要先转换到地图坐标系。传感器设备都安装在车上,所以传感器的测量结果都是以车辆为坐标原点,X轴沿车辆方向,Y轴沿垂直于X轴的左侧方向。

image

图片来源:https://github.com/sohonisaurabh/CarND-Kidnapped-Vehicle-Project

image

image

写成非矩阵形式:

image

通过Transformation我们已经将观测值的坐标转换到地图的坐标空间,下一步是将每个转换后的观测值与Map中的LandMark相关联。Associations主要将LandMark的测量结果匹配到Map中的LandMark。

如下图所示,L1,L2,…,L5是地图(Map)中的Landmark;OBS1、OBS2、OBS3是车辆的Observation。红色方块是车辆的GroundTruth位置,蓝色方块是车辆的预测位置。

image

我们可以看到地图有5个LandMark,它们分别被标识为L1、L2、L3、L4、L5,并且每个LandMark都有已知的地图位置。我们需要将每个转换后的观测值TOBS1、TOBS2、TOBS3与这5个标识符中的一个相关联。其中一个直观的做法就是每个转换后的观测LandMark坐标与最近的Map LandMark相关联。

image

void ParticleFilter::dataAssociation(std::vector<LandmarkObs> predicted,std::vector<LandmarkObs> &observations,double sensor_range) {// TODO: Find the predicted measurement that is closest to each observed// measurement and assign the//   observed measurement to this particular landmark.// NOTE: this method will NOT be called by the grading code. But you will// probably find it useful to//   implement this method and use it as a helper during the updateWeights//   phase.// TODO complete/*Associate observations in map co-ordinates to predicted landmarks using
nearest neighbor algorithm. Here, the number of observations may be less than
the total number of landmarks as some of the landmarks may be outside the range
of vehicle's sensor.*/int i, j;for (i = 0; i < observations.size(); i++) {// Maximum distance can be square root of 2 times the range of sensor.double lowest_dist = sensor_range * sqrt(2);int closest_landmark_id = -1;double obs_x = observations[i].x;double obs_y = observations[i].y;for (j = 0; j < predicted.size(); j++) {double pred_x = predicted[j].x;double pred_y = predicted[j].y;int pred_id = predicted[j].id;double current_dist = dist(obs_x, obs_y, pred_x, pred_y);if (current_dist < lowest_dist) {lowest_dist = current_dist;closest_landmark_id = pred_id;}}observations[i].id = closest_landmark_id;}
}

Update Weights:完成观测LandMark坐标转换之后和地图匹配之后,就可以更新粒子的权重了。由于粒子(Particle)对所有LandMark的观测都是独立的,所以粒子的总权重是所有观测LandMark的多元高斯概率密度的乘积。

image

image

void ParticleFilter::updateWeights(double sensor_range, double std_landmark[],std::vector<LandmarkObs> observations,Map map_landmarks) {// TODO: Update the weights of each particle using a mult-variate Gaussian// distribution. You can read//   more about this distribution here://   https://en.wikipedia.org/wiki/Multivariate_normal_distribution// NOTE: The observations are given in the VEHICLE'S coordinate system. Your// particles are located//   according to the MAP'S coordinate system. You will need to transform//   between the two systems. Keep in mind that this transformation requires//   both rotation AND translation (but no scaling). The following is a good//   resource for the theory://   https://www.willamette.edu/~gorr/classes/GeneralGraphics/Transforms/transforms2d.htm//   and the following is a good resource for the actual equation to implement//   (look at equation 3.33 http://planning.cs.uiuc.edu/node99.html//   TODO completeint i, j;/*This variable is used for normalizing weights of all particles and bringthem in the range of [0, 1]*/double weight_normalizer = 0.0;for (i = 0; i < num_particles; i++) {double particle_x = particles[i].x;double particle_y = particles[i].y;double particle_theta = particles[i].theta;/*Step 1: Transform observations from vehicle co-ordinates to map* co-ordinates.*/// Vector containing observations transformed to map co-ordinates w.r.t.// current particle.vector<LandmarkObs> transformed_observations;// Transform observations from vehicle's co-ordinates to map co-ordinates.for (j = 0; j < observations.size(); j++) {LandmarkObs transformed_obs;transformed_obs.id = j;transformed_obs.x = particle_x +(cos(particle_theta) * observations[j].x) -(sin(particle_theta) * observations[j].y);transformed_obs.y = particle_y +(sin(particle_theta) * observations[j].x) +(cos(particle_theta) * observations[j].y);transformed_observations.push_back(transformed_obs);}/*Step 2: Filter map landmarks to keep only those which are in thesensor_range of current particle. Push them to predictions vector.*/vector<LandmarkObs> predicted_landmarks;for (j = 0; j < map_landmarks.landmark_list.size(); j++) {Map::single_landmark_s current_landmark = map_landmarks.landmark_list[j];if ((fabs((particle_x - current_landmark.x_f)) <= sensor_range) &&(fabs((particle_y - current_landmark.y_f)) <= sensor_range)) {predicted_landmarks.push_back(LandmarkObs{current_landmark.id_i, current_landmark.x_f, current_landmark.y_f});}}/*Step 3: Associate observations to lpredicted andmarks using nearest* neighbor algorithm.*/// Associate observations with predicted landmarksdataAssociation(predicted_landmarks, transformed_observations,sensor_range);/*Step 4: Calculate the weight of each particle using Multivariate Gaussian* distribution.*/// Reset the weight of particle to 1.0particles[i].weight = 1.0;double sigma_x = std_landmark[0];double sigma_y = std_landmark[1];double sigma_x_2 = pow(sigma_x, 2);double sigma_y_2 = pow(sigma_y, 2);double normalizer = (1.0 / (2.0 * M_PI * sigma_x * sigma_y));int k, l;/*Calculate the weight of particle based on the multivariate Gaussian* probability function*/for (k = 0; k < transformed_observations.size(); k++) {double trans_obs_x = transformed_observations[k].x;double trans_obs_y = transformed_observations[k].y;double trans_obs_id = transformed_observations[k].id;double multi_prob = 1.0;for (l = 0; l < predicted_landmarks.size(); l++) {double pred_landmark_x = predicted_landmarks[l].x;double pred_landmark_y = predicted_landmarks[l].y;double pred_landmark_id = predicted_landmarks[l].id;if (trans_obs_id == pred_landmark_id) {multi_prob = normalizer *exp(-1.0 * ((pow((trans_obs_x - pred_landmark_x), 2) /(2.0 * sigma_x_2)) +(pow((trans_obs_y - pred_landmark_y), 2) /(2.0 * sigma_y_2))));particles[i].weight *= multi_prob;}}}weight_normalizer += particles[i].weight;}/*Step 5: Normalize the weights of all particles since resmapling using* probabilistic approach.*/for (int i = 0; i < particles.size(); i++) {particles[i].weight /= weight_normalizer;weights[i] = particles[i].weight;}
}

4)Resample Step

重采样(Resample)是从旧粒子(Old Particles)中随机抽取新粒子(New Particles)并根据其权重进行替换的过程。重采样后,具有更高权重的粒子保留的概率越大,概率越小的粒子消亡的概率越大。

常用的Resample技术是Resampling Wheel。Resampling Wheel的算法思想如下:如下图所示的圆环,圆环的弧长正比与它的权重(即权重越大,弧长越长)。

image

下一步就是利用类似于轮盘赌(Roulette Wheel)的方式,将圆环安装固定步长(Resampling Wheel中将圆环切分为2*max(weights))进行等分,选定一个方向进行n次随机旋转,每次旋转获得一个位置,这个位置就是被选中的粒子的索引。

image

Python代码如下:

p3 = []
index = int(random.random()*N)
beta = 0.0
mw = max(w)
for i in range(N):beta += random.random()*2*mwwhile w[index] < beta:beta = beta - w[index]index = index + 1p3.append(p[index]) 

Resample的C++代码如下

void ParticleFilter::resample() {// TODO: Resample particles with replacement with probability proportional to// their weight. NOTE: You may find std::discrete_distribution helpful here.//   http://en.cppreference.com/w/cpp/numeric/random/discrete_distribution//   TODO completevector<Particle> resampled_particles;// Create a generator to be used for generating random particle index and beta// valuedefault_random_engine gen;// Generate random particle indexuniform_int_distribution<int> particle_index(0, num_particles - 1);int current_index = particle_index(gen);double beta = 0.0;double max_weight_2 = 2.0 * *max_element(weights.begin(), weights.end());for (int i = 0; i < particles.size(); i++) {uniform_real_distribution<double> random_weight(0.0, max_weight_2);beta += random_weight(gen);while (beta > weights[current_index]) {beta -= weights[current_index];current_index = (current_index + 1) % num_particles;}resampled_particles.push_back(particles[current_index]);}particles = resampled_particles;
}

最后把这些代码串起来,实现车辆定位的功能。

// Set up parameters here
double delta_t = 0.1;     // Time elapsed between measurements [sec]
double sensor_range = 50; // Sensor range [m]double sigma_pos[3] = {0.3, 0.3, 0.01}; // GPS measurement uncertainty [x [m], y [m], theta [rad]]
double sigma_landmark[2] = {0.3, 0.3}; // Landmark measurement uncertainty [x [m], y [m]]// Read map data
Map map;
if (!read_map_data("../data/map_data.txt", map)) {cout << "Error: Could not open map file" << endl;return -1;
}// Create particle filter
ParticleFilter pf;while (循环接收车辆的控制信息和Sense信息) {if (!pf.initialized()) {// Sense noisy position data from the simulatordouble sense_x = std::stod(j[1]["sense_x"].get<std::string>());double sense_y = std::stod(j[1]["sense_y"].get<std::string>());double sense_theta = std::stod(j[1]["sense_theta"].get<std::string>());pf.init(sense_x, sense_y, sense_theta, sigma_pos);} else {// Predict the vehicle's next state from previous (noiseless// control) data.double previous_velocity =std::stod(j[1]["previous_velocity"].get<std::string>());double previous_yawrate =std::stod(j[1]["previous_yawrate"].get<std::string>());pf.prediction(delta_t, sigma_pos, previous_velocity, previous_yawrate);}// receive noisy observation data from the simulator// sense_observations in JSON format// [{obs_x,obs_y},{obs_x,obs_y},...{obs_x,obs_y}]vector<LandmarkObs> noisy_observations;string sense_observations_x = j[1]["sense_observations_x"];string sense_observations_y = j[1]["sense_observations_y"];std::vector<float> x_sense;std::istringstream iss_x(sense_observations_x);std::copy(std::istream_iterator<float>(iss_x), std::istream_iterator<float>(),std::back_inserter(x_sense));std::vector<float> y_sense;std::istringstream iss_y(sense_observations_y);std::copy(std::istream_iterator<float>(iss_y), std::istream_iterator<float>(),std::back_inserter(y_sense));for (int i = 0; i < x_sense.size(); i++) {LandmarkObs obs;obs.x = x_sense[i];obs.y = y_sense[i];noisy_observations.push_back(obs);}// Update the weights and resamplepf.updateWeights(sensor_range, sigma_landmark, noisy_observations, map);pf.resample();// Calculate and output the average weighted error of the particle// filter over all time steps so far.vector<Particle> particles = pf.particles;int num_particles = particles.size();double highest_weight = -1.0;Particle best_particle;double weight_sum = 0.0;for (int i = 0; i < num_particles; ++i) {if (particles[i].weight > highest_weight) {highest_weight = particles[i].weight;best_particle = particles[i];}weight_sum += particles[i].weight;}
}

在Udacity Simulator上的演示效果如下:

image

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

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

相关文章

spring-cloud微服务openfeign

Spring Cloud openfeign对Feign进行了增强&#xff0c;使其支持Spring MVC注解&#xff0c;另外还整合了Ribbon和Nacos&#xff0c;从而使得Feign的使用更加方便 优势&#xff0c;openfeign可以做到使用HTTP请求远程服务时就像洞用本地方法一样的体验&#xff0c;开发者完全感…

自己动手封装axios通用方法并上传至私有npm仓库:详细步骤与实现指南

文章目录 一、构建方法1、api/request.js2、api/requestHandler.js3、api/index.js 二、测试方法1、api/axios.js2、main.js3、app.vue4、vue.config.js5、index.html 三、打包1、配置package.json2、生成库包3、配置发布信息4、发布 四、使用1、安装2、使用 五、维护1、维护和…

M1 Flutter SDK的安装和环境配置

前言 作为iOS 开发&#xff0c;观望了许久的Flutter &#xff0c;还是对它下手了&#xff0c;不是故意要卷&#xff0c;没办法工作需要&#xff01;既然要学Flutter&#xff0c;首先就得配置Flutter的相关环境&#xff0c;由于我的是M1 芯片的电脑&#xff0c;记录下来配置过程…

spring boot 集成 flyway依赖 做数据库迁移,让部署没烦恼

flyway 是一个敏捷工具&#xff0c;用于数据库的移植。采用 Java 开发&#xff0c;支持所有兼容 JDBC 的数据库。 主要用于在你的应用版本不断升级的同时&#xff0c;升级你的数据库结构和里面的数据。 还是直接上代码 第一步&#xff1a; <!-- Flyway 数据库迁移 依赖 他…

python爬虫-------JsonPath(第十九天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

【一学就会】(一)C++编译工具链——基于VSCode的CMake、make与g++简单理解与应用示例

目录 一、CMake、make与g 1、名词辨析 2、孰优孰劣 二、应用示例 1、工具类安装与配置 1&#xff09;VSCode安装与配置 2&#xff09;CMake下载与安装 3&#xff09;MinGW-W64下载与安装 A、科学上网法 B、无需科学上网法 4&#xff09;VSCode推荐插件 A、c/c编译环…

Linux/Ubuntu/Debian中与进程和系统资源有关的命令top/ps

top命令是Linux系统中非常实用的一个工具&#xff0c;其主要功能是展示当前系统中资源使用情况最高的进程列表。通过这个命令&#xff0c;我们可以一目了然地看到哪些进程正在消耗大量的CPU、内存等资源。top命令默认每3秒更新一次数据&#xff0c;提供了实时的系统资源状态&am…

【Qt 学习笔记】QWidget的geometry属性及window frame的影响

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ QWidget的geometry属性 文章编号&#xff1a;Qt 学习笔记 / 16 文章目…

BK-SDM读图片逻辑-评估结果FID逻辑

以inherit为例 这是借助bksdm的代码用于我的A-sdm的生成 bksdm中2个关键路径是 src/genetate.py script/eval_scores.sh 一 以generate.py文件进行生成 借助ms-coco的csv文件里面的30K个提示词和图片名字&#xff0c;来生成图片&#xff0c;并保存 share/huanggao/zjc/code_i2…

【智能算法】省时方便,智能算法统计指标——一键运行~

目录 1.常用统计指标2.参数统计检验3.结果展示4.自定义修改测试框架 1.常用统计指标 测试智能算法性能时&#xff0c;常常会用到以下5种常用指标&#xff0c;简单不赘述&#xff1a; 最优值、最差值、均值、中位数、标准差 2.参数统计检验 单纯依靠常用统计指标说服力不足&…

07 Php学习:运算符

PHP 算术运算符 在 PHP 中&#xff0c;算术运算符用于执行基本的数学运算&#xff0c;包括加法、减法、乘法、除法、取余数&#xff0c;负数运算、取反和并置运算。以下是这些运算符的详细解释和示例&#xff1a; 加法运算符 &#xff1a;用于将两个数值相加。 $a 5; $b 3;…

初识--数据结构

什么是数据结构&#xff1f;我们为什么要学习数据结构呢....一系列的问题就促使我们不得不了解数据结构。我们不禁要问了&#xff0c;学习C语言不就够了吗&#xff1f;为什么还要学习数据结构呢&#xff1f;这是因为&#xff1a;数据结构能够解决C语言解决不了的问题&#xff0…

【Java基础题型】矩阵的对角线求和

一、题目-矩阵 求一个33矩阵对角线元素之和。 输入格式 矩阵 输出格式 主对角线 副对角线 元素和 样例输入 1 2 3 1 1 1 3 2 1 样例输出 3 7 二、参考的知识 这里给大家送点英语单词&#xff0c;记得学习&#xff1a; p r i m a r y. adj.主要的&#xff1b;初…

软考中级之软件设计师---知识点汇总总结

软考中级之软件设计师---知识点汇总总结 软考介绍资格设置证书样本 计算机组成原理操作系统1. 进程的三态模型2. 磁盘调度算法 计算机网络1. 网络的分类2. 各层的互连设备3. 网络模型&#xff0c;协议簇4. 传输层协议TCP、UDP4.1 TCP (Transmission Control Protocol,传输控制协…

day77 JSPServlet

知识点&#xff1a; 1Web工程 2JSP是什么&#xff1f;JSP页面包含哪些内容&#xff1f;JSP页面执行原理 3JSP九大内置对象&#xff0c;及四个作用域 4什么是SERVLET&#xff1f;及servlet相关API 5MVC模型 6EL表达式及JSTL标签库的使用 7在JSP页面实现分页和多条件查询 …

【UE5 C++】访问修饰符public/protected/private继承

限制类与类之间访问级别的方法 public 在类中创建一个public的部分&#xff0c;即" public: "&#xff0c;public之下的所有内容都是公共的,可以在类之间访问 private&#xff08;最常见&#xff09; 如若没有指明修饰符&#xff0c;则默认为private 不能在类的外…

【LAMMPS学习】七、加速性能(4)加速器包

7. 加速性能 7.1.基准测试 7.2.测试性能 7.3.通用技巧 7.4.加速器包 LAMMPS 中添加了各种pair_style、fixes、compute 和其他命令的加速版本&#xff0c;其运行速度通常比标准非加速版本更快。有些需要您的系统上存在适当的硬件&#xff0c;例如GPU 或 Intel Xeon Phi 协处…

每日OJ题_BFS解决FloodFill②_力扣200. 岛屿数量

目录 力扣200. 岛屿数量 解析代码 力扣200. 岛屿数量 200. 岛屿数量 难度 中等 给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&#xff0c;并且每座岛屿只能由水平方…

聊聊自己12岁车龄的福克斯

1. 2005年&#xff0c;国内进入了 福克斯 ( 参数 | 询价 ) 这台车&#xff0c;中间经历了两次换代&#xff0c;而我自己的这台车则是第一批进入国内的福克斯&#xff0c;它的到来颠覆了大家当时对汽车设计的印象&#xff0c;在十年前家用车都是捷达、桑塔纳等那些古板油腻的车…

全球变暖蓝桥杯2018省赛真题

全球变暖蓝桥杯2018省赛真题 DFS大法 全球变暖 #include <bits/stdc.h> using namespace std; #define int long long bool flag; char a[1010][1010]; int cnt,n,ans0,pre_ans0,d[4][2] {1,0,-1,0,0,1,0,-1}; void dfs(int x,int y){if(x>n||x<0||y>n||y<…