3D激光里程计其一:ICP

news2024/9/29 23:30:14

这里写目录标题

  • 1. ICP 整体流程
  • 2. ICP 的数学表示
  • 3. 基于 SVD 的 ICP
    • 3.1 旋转部分求解
    • 3.2 平移部分求解
  • 4. 基于优化的 ICP
  • 5. ICP 系列汇总

Reference:

  1. 深蓝学院-多传感器融合

1. ICP 整体流程

在这里插入图片描述
目的:有两个相似的刚体点云,它们之间没有做好配准,现在想将它们之间的旋转和平移找出来。

在这里插入图片描述

解决思路:如上图所示,从蓝色的点云里面选一些点,根据这些点,在红色的点云里面找离它最近的一些点,根据这些匹配点,可以将 R, t 计算出来。

存在问题:在找配准点的时候,找的点是最近的,但是找的这个点不见得是真正在刚体里面匹配的点。这个时候点找错了,那么根据这个点计算出来的 R, t,肯定是不精确的。就会出现中间图片的样子------两个刚体点云并没有完全重合。但是经过一次匹配后,俩点云至少更接近了,这时可以再做一次上面的流程。循环几次之后,可能就完全重合了。

2. ICP 的数学表示

  • 点集:
    X = { x 1 , x 2 , ⋯   , x N x } Y = { y 1 , y 2 , ⋯   , y N y } \begin{aligned} & X=\left\{x_1, x_2, \cdots, x_{N_x}\right\} \\ & Y=\left\{y_1, y_2, \cdots, y_{N_y}\right\} \end{aligned} X={x1,x2,,xNx}Y={y1,y2,,yNy}

    其中 X X X Y Y Y原始点云的子集,选取的是两个点集中能够互相关联的那些点,即 N x = N y N_x=N_y Nx=Ny

  • 目标:找到一组(R, t),使误差的二范数最小化
    min ⁡ E ( R , t ) = min ⁡ 1 N y ∑ i = 1 N y ∥ x i − R y i − t ∥ 2 \min E(R, t)=\min \frac{1}{N_y} \sum_{i=1}^{N_y}\left\|x_i-R y_i-t\right\|^2 minE(R,t)=minNy1i=1NyxiRyit2

3. 基于 SVD 的 ICP

SVD 的好处在于一步求解。完成了点的关联后,就可以通过一步运算将 R 和 t 求出来。
现在来看看公式上怎样解决这个问题:
E ( R , t ) = 1 N y ∑ i = 1 N y ∥ x i − R y i − t − u x + R u y + u x − R u y ∥ 2 = 1 N y ∑ i = 1 N y ( ∥ x i − u x − R ( y i − u y ) + ( u x − R u y − t ) ∥ 2 ) = 1 N y ∑ i = 1 N y ( ∥ x i − u x − R ( y i − u y ) ∥ 2 + ∥ u x − R u y − t ∥ 2 + 2 ( x i − u x − R ( y i − u y ) ) T ( u x − R u y − t ) ) = 1 N y ∑ i = 1 N y ( ∥ x i − u x − R ( y i − u y ) ∥ 2 + ∥ u x − R u y − t ∥ 2 ) \begin{aligned} E(R, t)&=\frac{1}{N_y} \sum_{i=1}^{N_y}\left\|x_i-R y_i-t-u_x+R u_y+u_x-R u_y\right\|^2 \\ & =\frac{1}{N_y} \sum_{i=1}^{N_y}\left(\left\|x_i-u_x-R\left(y_i-u_y\right)+\left(u_x-R u_y-t\right)\right\|^2\right) \\ & =\frac{1}{N_y} \sum_{i=1}^{N_y}\left(\left\|x_i-u_x-R\left(y_i-u_y\right)\right\|^2+\left\|u_x-R u_y-t\right\|^2+2\left(x_i-u_x-R\left(y_i-u_y\right)\right)^T\left(u_x-R u_y-t\right)\right) \\ & =\frac{1}{N_y} \sum_{i=1}^{N_y}\left(\left\|x_i-u_x-R\left(y_i-u_y\right)\right\|^2+\left\|u_x-R u_y-t\right\|^2\right) \\ & \end{aligned} E(R,t)=Ny1i=1NyxiRyitux+Ruy+uxRuy2=Ny1i=1Ny(xiuxR(yiuy)+(uxRuyt)2)=Ny1i=1Ny(xiuxR(yiuy)2+uxRuyt2+2(xiuxR(yiuy))T(uxRuyt))=Ny1i=1Ny(xiuxR(yiuy)2+uxRuyt2)

其中 u x u_x ux u y u_y uy 分别是点集 X X X Y Y Y 的质心,即:
u x = 1 N x ∑ i = 1 N x x i u y = 1 N y ∑ i = 1 N y y i u_x=\frac{1}{N_x} \sum_{i=1}^{N_x} x_i \quad u_y=\frac{1}{N_y} \sum_{i=1}^{N_y} y_i ux=Nx1i=1Nxxiuy=Ny1i=1Nyyi

  1. 在第一步加了几项进公式中: − u x + R u y + u x − R u y -u_x+R u_y+u_x-R u_y ux+Ruy+uxRuy,用来化简方程;
  2. 公式移项,就变成了 ∣ ∣ a + b ∣ ∣ 2 ||a+b||^2 ∣∣a+b2这样了;
  3. 根据 ∣ ∣ a + b ∣ ∣ 2 = ∣ ∣ a ∣ ∣ 2 + ∣ ∣ b ∣ ∣ 2 + 2 a T b ||a+b||^2=||a||^2+||b||^2+2a^Tb ∣∣a+b2=∣∣a2+∣∣b2+2aTb,将公式拆开,可以发现 2 ( x i − u x − R ( y i − u y ) ) T ( u x − R u y − t ) 2\left(x_i-u_x-R\left(y_i-u_y\right)\right)^T\left(u_x-R u_y-t\right) 2(xiuxR(yiuy))T(uxRuyt)累加和为零。
    ∑ i = 1 N y ( x i − u x − R ( y i − u y ) ) \sum_{i=1}^{N_y} \left(x_i-u_x-R\left(y_i-u_y\right)\right) i=1Ny(xiuxR(yiuy)),其中 ∑ i = 1 N y ( x i − u x ) = 0 \sum_{i=1}^{N_y} (x_i-u_x)=0 i=1Ny(xiux)=0 ∑ i = 1 N y R ( y i − u y ) = 0 \sum_{i=1}^{N_y} R\left(y_i-u_y\right)=0 i=1NyR(yiuy)=0

下面继续化简:
E ( R , t ) = 1 N y ∑ i = 1 N y ( ∥ x i − u x − R ( y i − u y ) ∥ 2 + ∥ u x − R u y − t ∥ 2 ) = E 1 ( R , t ) + E 2 ( R , t ) \begin{aligned} E(R, t)&=\frac{1}{N_y} \sum_{i=1}^{N_y}\left(\left\|x_i-u_x-R\left(y_i-u_y\right)\right\|^2+\left\|u_x-R u_y-t\right\|^2\right) \\ &=E_1(R, t)+E_2(R, t) \end{aligned} E(R,t)=Ny1i=1Ny(xiuxR(yiuy)2+uxRuyt2)=E1(R,t)+E2(R,t)

其中: E 1 ( R , t ) = 1 N y ∑ i = 1 N y ∥ x i − u x − R ( y i − u y ) ∥ 2 (只与旋转有关)  E 2 ( R , t ) = ∥ u x − R u y − t ∥ 2 (用于求平移部分)  \begin{aligned} &E_1(R, t)=\frac{1}{N_y} \sum_{i=1}^{N_y}\left\|x_i-u_x-R\left(y_i-u_y\right)\right\|^2 \quad \text {(只与旋转有关) } \\ & E_2(R, t)=\left\|u_x-R u_y-t\right\|^2 \quad\text {(用于求平移部分) } \end{aligned} E1(R,t)=Ny1i=1NyxiuxR(yiuy)2(只与旋转有关E2(R,t)=uxRuyt2(用于求平移部分

可以发现的是,在 E 1 E_1 E1里面只有 R R R没有 t t t了。我们的目标是让 E 1 + E 2 E_1+E_2 E1+E2最小。在 E 1 E_1 E1里面,可以找到一个 R R R,使结果最小。在 E 2 E_2 E2里面不管 R R R是什么,都可以让 t = u x − R u y t=u_x-Ru_y t=uxRuy,即这个值总是零。

因此,可以先根据 E 1 ( R , t ) E_1(R, t) E1(R,t)求旋转,再根据 E 2 ( R , t ) E_2(R,t) E2(R,t)求平移。

3.1 旋转部分求解

接下来就是看怎么把这个旋转求出来:
E 1 ( R , t ) = 1 N y ∑ i = 1 N y ∥ x i − u x − R ( y i − u y ) ∥ 2 = 1 N y ∑ i = 1 N y ∥ x i ′ − R y i ′ ∥ 2 = 1 N y ∑ i = 1 N y ( x i ′ T x i ′ + y i ′ R T R y i ′ − 2 x i ′ T R y i ′ ) \begin{aligned} E_1(R, t) & =\frac{1}{N_y} \sum_{i=1}^{N_y}\left\|x_i-u_x-R\left(y_i-u_y\right)\right\|^2 \\ & =\frac{1}{N_y} \sum_{i=1}^{N_y}\left\|x_i^{\prime}-R y_i^{\prime}\right\|^2 \\ & =\frac{1}{N_y} \sum_{i=1}^{N_y}( x_i^{\prime T} x_i^{\prime}+y_i^{\prime} R^T R y_i^{\prime}-2 x_i^{\prime T} R y_i^{\prime}) \end{aligned} E1(R,t)=Ny1i=1NyxiuxR(yiuy)2=Ny1i=1NyxiRyi2=Ny1i=1Ny(xiTxi+yiRTRyi2xiTRyi)

x i ′ x_i' xi 表示 x i − u x x_i-u_x xiux y i ′ y_i' yi 表示 y i − u y y_i-u_y yiuy,公式展开。其中 x ′ i T x ′ i {x'}_i^T{x'}_i xiTxi R R R 无关,而 R T R R^TR RTR 是单位阵也没什么关系(旋转矩阵都是单位正交阵)。这时需要考虑的就只有 − 2 x i ′ T R y i ′ -2 x_i^{\prime T} R y_i^{\prime} 2xiTRyi 这一项了。令 :
E 1 ′ ( R , t ) = ∑ i = 1 N y x i ′ T R y i ′ E_1^{\prime}(R, t)=\sum_{i=1}^{N_y} x_i^{\prime T} R y_i^{\prime} E1(R,t)=i=1NyxiTRyi

则:
arg ⁡ min ⁡ R E 1 ( R , t ) = arg ⁡ max ⁡ R E 1 ′ ( R , t ) = arg ⁡ max ⁡ R ∑ i = 1 N y x i ′ T R y i ′ \begin{aligned} & \arg \min _R E_1(R, t) \\ = & \arg \max _R E_1^{\prime}(R, t) \\ = & \arg \max _R \sum_{i=1}^{N_y} x_i^{\prime T} R y_i^{\prime}\end{aligned} ==argRminE1(R,t)argRmaxE1(R,t)argRmaxi=1NyxiTRyi

即求最小的 E 1 E_1 E1 也就是求最大的 x i ′ T R y i ′ x_i^{\prime T} R y_i^{\prime} xiTRyi(因为该项带负号)。
E 1 ′ ( R , t ) = ∑ i = 1 N y x i ′ T R y i ′ ( 1 ) = ∑ i = 1 N y Trace ⁡ ( x i ′ T R y i ′ ) ( 2 ) = ∑ i = 1 N y Trace ⁡ ( R y i ′ x i ′ T ) = Trace ⁡ ( ∑ i = 1 N y R y i ′ x i ′ ) ( 3 ) = Trace ⁡ ( R H ) E_1^{\prime}(R, t)=\sum_{i=1}^{N_y} x_i^{\prime T} R y_i^{\prime}{}^{(1)}=\sum_{i=1}^{N_y} \operatorname{Trace}\left(x_i^{\prime T} R y_i^{\prime}\right)^{(2)}=\sum_{i=1}^{N_y} \operatorname{Trace}\left(R y_i^{\prime} x_i^{\prime T}\right)=\operatorname{Trace}\left(\sum_{i=1}^{N_y} R y_i^{\prime} x_i^{\prime}\right)^{(3)}=\operatorname{Trace}(R H) E1(R,t)=i=1NyxiTRyi(1)=i=1NyTrace(xiTRyi)(2)=i=1NyTrace(RyixiT)=Trace i=1NyRyixi (3)=Trace(RH)

  • 等式(1):常数的迹等于它自身,因此上式是相等的
  • 等式(2): tr ⁡ ( A B ) = ∑ i = 1 m ∑ j = 1 n a i j b j i = ∑ i = 1 m ∑ j = 1 n b j i a i j = tr ⁡ ( B A ) \operatorname{tr}(A B)=\sum_{i=1}^m \sum_{j=1}^n a_{i j} b_{j i}=\sum_{i=1}^m \sum_{j=1}^n b_{j i} a_{i j}=\operatorname{tr}(B A) tr(AB)=i=1mj=1naijbji=i=1mj=1nbjiaij=tr(BA)
  • 等式(3): H = ∑ i = 1 N y y i ′ x i ′ T H=\sum_{i=1}^{N_y} y_i^{\prime} x_i^{\prime T} H=i=1NyyixiT

问题转化为,找到合适的 R R R,使 Trace ⁡ ( R H ) \operatorname{Trace}(R H) Trace(RH) 达到最大值。

  • 定理:若有正定矩阵 A A T A A^T AAT ,则对于任意正交矩阵 B B B ,有 Trace ⁡ ( A A T ) ≥ Trace ⁡ ( B A A T ) \operatorname{Trace} (A A^T) \geq \operatorname{Trace}\left(B A A^T\right) Trace(AAT)Trace(BAAT)
    意义:若能找到 R R R,把 Trace ⁡ ( R H ) \operatorname{Trace}(R H) Trace(RH) 转换成 Trace ( A A T ) \left(A A^T\right) (AAT) 的形式,则该 R R R 就是我们要找的旋转矩阵证明(只要变成这种形式,再把 R R R变成任意的旋转矩阵,都不可能比这个要大了。而我们的目标就是让这个值达到最大。):
    tr ⁡ ( B A A T ) = tr ⁡ ( A T B A ) = ∑ i a i T ( B a i ) \operatorname{tr}\left(B A A^T\right)=\operatorname{tr}\left(A^T B A\right)=\sum_i a_i^T\left(B a_i\right) tr(BAAT)=tr(ATBA)=iaiT(Bai)

    其中 a i \mathrm{a}_{\mathrm{i}} ai A A A 的列向量。根据柯西-施瓦茨不等式(有两向量 x 、 y x、y xy x T y ≤ ( x T x ) ( y T y ) x^Ty\leq\sqrt{(x^Tx)(y^Ty)} xTy(xTx)(yTy) ),有
    a i T ( B a i ) ≤ ( a i T a i ) ( a i T B T B a i ) = a i T a i a_i^T\left(B a_i\right) \leq \sqrt{\left(a_i^T a_i\right)\left(a_i^T B^T B a_i\right)}=a_i^T a_i aiT(Bai)(aiTai)(aiTBTBai) =aiTai

    因此,
    tr ⁡ ( B A A T ) = ∑ i a i T ( B a i ) ≤ ∑ i a i T a i = tr ⁡ ( A A T ) \operatorname{tr}\left(B A A^T\right)=\sum_i a_i^T\left(B a_i\right) \leq \sum_i a_i^T a_i=\operatorname{tr}\left(A A^T\right) tr(BAAT)=iaiT(Bai)iaiTai=tr(AAT)

  • 目的:找到 R R R,把 Trace ⁡ ( R H ) \operatorname{Trace}(R H) Trace(RH) 转换成 Trace ⁡ ( A A T ) \operatorname{Trace}\left(A A^T\right) Trace(AAT) 的形式
    方法:
    H H H 进行SVD分解: H = U Σ V T H=U \Sigma V^T H=UΣVT
    R = V U T R=V U^T R=VUT
    则有: R H = V U T U Σ V T = V Σ V T = V Σ 1 2 Σ 1 2 V T = V Σ 1 2 ( V Σ 1 2 ) T R H=V U^T U \Sigma V^T=V \Sigma V^T=V \Sigma^{\frac{1}{2}} \Sigma^{\frac{1}{2}} V^T=V \Sigma^{\frac{1}{2}}\left(V \Sigma^{\frac{1}{2}}\right)^T RH=VUTUΣVT=VΣVT=VΣ21Σ21VT=VΣ21(VΣ21)T
    其中 U T U U^TU UTU 能消掉是奇异值分解中的性质。也就是说,找到了 R = V U T R=V U^T R=VUT,那就是要找的东西。

3.2 平移部分求解

旋转 R R R 确定之后,可根据
E 2 ( R , t ) = ∥ u x − R u y − t ∥ 2 E_2(R, t)=\left\|u_x-R u_y-t\right\|^2 E2(R,t)=uxRuyt2

直接得到平移量为
t = u x − R u y t=u_x-R u_y t=uxRuy

4. 基于优化的 ICP

优化的思想在于让点逐渐收敛,不想做 SVD 分解,就给一初值,让这个初值按照一定策略逐渐搜索,直到搜索到要的 R 和 t 满足一定条件,就认为得到了最终确定的结果。

非线性优化要求雅可比,而基于优化的ICP对应的雅可比推导在李代数模式下会更加简洁。ICP求解问题,可以重新表示为:
min ⁡ T = 1 2 ∑ i = 1 n ∥ ( x i − T y i ) ∥ 2 2 \min _T=\frac{1}{2} \sum_{i=1}^n\left\|\left(x_i-T y_i\right)\right\|_2^2 Tmin=21i=1n(xiTyi)22

在李代数模式下,又可以重新表示为:
min ⁡ ξ = 1 2 ∑ i = 1 n ∥ ( x i − exp ⁡ ( ξ ∧ ) y i ) ∥ 2 2 \min _{\xi}=\frac{1}{2} \sum_{i=1}^n\left\|\left(x_i-\exp \left(\xi^{\wedge}\right) y_i\right)\right\|_2^2 ξmin=21i=1n(xiexp(ξ)yi)22

其中 ξ \xi ξ T T T 对应的李代数。
残差对应的雅可比为:
J = ∂ e ∂ δ ξ = − ( exp ⁡ ( ξ ∧ ) y i ) ⊙ J=\frac{\partial e}{\partial \delta \xi}=-\left(\exp \left(\xi^{\wedge}\right) y_i\right)^{\odot} J=δξe=(exp(ξ)yi)
随后,便可根据优化的固定步骤求解位姿。

5. ICP 系列汇总

在这里插入图片描述

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

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

相关文章

Golang原理分析:闭包及for range延迟绑定问题原理及解决

1.Golang中的闭包 1.1.什么是闭包 当一个函数引用了环境的变量,被引用的变量与该函数同时存在组成的系统,被称为闭包。 闭包 环境的变量 函数。 以下JavaScript代码展示了一个基础的闭包: name是init函数中的内部变量displayName()是i…

机器学习 鸢尾花(Iris Flower)数据集分析

目录 一:加载数据 二:提取特征数据 三:提取标签数据 四:数据划分 一:加载数据 加载数据,查看数据特征 from sklearn.datasets import load_iris# 1 加载数据 鸢尾花load_iris iris_datasets load_iri…

数据校验及在数据校验的情况下增加headers拿回数据

什么是数据校验: 当你向一个数据端口请求数据时,如果这个数据端口没有设置:Access-Control-Allow-Origin:*,那就是存在跨域限制了,你是拿不回来数据的。图示: 但是有些数据端口是设置了 Access…

【JS ES6】了解学习set类型和weakset类型

✍️ 作者简介: 前端新手学习中。 💂 作者主页: 作者主页查看更多前端教学 🎓 专栏分享:css重难点教学 Node.js教学 从头开始学习 ajax学习 目录set类型与array和object的区别set元素检测与管理类型转换的重要性遍历set类型的方式使用set…

Spring - 事件监听机制 源码解析

文章目录Pre概述ApplicationEvent ------ 事件ApplicationListener ------ 事件监听器ApplicationEventPublisher ------ 事件发布者ApplicationEventMulticaster ------ 事件广播器spring主要的内置事件ContextRefreshedEventContextStartedEventContextStoppedEventContextCl…

设计模式概述之单例模式(四)

很多小伙伴,不知道设计模式是什么? 通常我们所说的设计模式是一种设计方案,是前人留下的经验及最佳实践。 想要学习设计模式,至少要把面向对象的基本结构全部了解。 设计模式,是建立在一定基础上的思维训练。 学习…

喜报 | 中关村发来贺电

2022年12月14日,由中关村金融科技产业发展联盟、中关村互联网金融研究院举办的“中关村金融科技系列活动——2023第十届中关村金融科技论坛年会暨2022“光大杯”中关村番钛客金融科技国际创新大赛颁奖典礼”已圆满落幕。本次会议为建设金融科技中心,共建…

【Pintos】实现自定义 UserProg 系统调用

💭 写在前面:本文讲解的内容不属于 Pintos 的 Project 项目,而是关于 userprog 如何添加系统调用的,学习如何额外实现一些功能到系统调用中以供用户使用。因为涉及到 src/example 下的Makefile 的修改、lib 目录下 syscall-nr 系统…

搜索二叉树详解

🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸 文章目录一、搜索二叉树框架二、搜索二叉树概念三、搜索二叉树操作①Erase②Find递归③Insert递归④Erase递归,比Erase更简洁⑤析构函数⑥…

unity学习笔记--day01

今天学习制作了一个简单的抽卡功能,学习结束后目录结构如下: .mate文件是unity生成的配置文件,不用管 制作第一张卡片 创建一个空物体,改名为Card。 在Card下挂载以下UI组件: 编写数据脚本并挂载,unity采用…

Nginx教程(4)—Keepalived

文章目录4.1 高可用集群架构Keepalived双机主备原理4.2 安装Keepalived4.3 Keepalived核心配置文件4.4 Keepalived实现双主机主备高可用测试4.5 高可用集群架构Keepalived双主热备原理Nginx教程一 Nginx教程二 Nginx教程三 4.1 高可用集群架构Keepalived双机主备原理 我们知道…

【计算机毕业设计】78.汽车租赁系统源码

一、系统截图(需要演示视频可以私聊) 目 录 摘 要 前 言 第1章 概述 1.1 研究背景 1.2 研究目的 1.3 研究内容 第二章 开发技术介绍 2.1 Java技术 2.2 Mysql数据库 2.3 B/S结构 2.4 SSM框架 第三章 系统分析 3.1 可行性分析 3.1.1 技术…

UnrealUBlueprintAsyncActionBase的使用

实现异步调用,之前我们介绍过一种FLatentActionInfo的方法,还有另外一种UBlueprintAsyncActionBase方法,可以实现异步节点,用于异步监听然后进行回调。按照如下步骤进行使用,我们同样以Delay一定帧数,并每帧…

面对新技术,必须找到与其发展相辅相成的长期主义的方法

从Meta股价的一路走低到扎克伯格发布的头显并不被用户买账,Facebook全力拥抱Meta正在经历一场过山车。   扎克伯格和他所带领下的Meta遭遇到的如此多的困境和难题,越来越多地让我们开始相信:所谓的元宇宙并非是一蹴而就的,它是一…

【云原生 Kubernetes】基于 Minikube 搭建第一个k8s集群

一、前言 对于k8s来说,搭建方式有多种,如果是生产环境,一般来说,至少需要3台节点确保服务的高可用性,常用的搭建方式列举如下(提供参考): kubeadm搭建(推荐) …

postman测试环境的创建及发送请求方式

目录 一、创建工作环境 1、打开postman,点击工作区 2、点击新建 3、添加名字,点击创建 4、工作区可以自由切换工作区 5、点击创建发送请求 6、更换请求方式 7、保存测试 二、测试发送请求,使用的时候服务一定要启动 1、普通传参&…

C++ 类型转换

目录 C语言中的类型转换 为什么C需要四种类型转换 C:命名的强制类型转换 static_cast reinterpret_cast const_cast dynamic_cast C语言中的类型转换 在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配&#xff0c…

信息学奥赛一本通——1163:阿克曼(Ackmann)函数

文章目录1163:阿克曼(Ackmann)函数【题目描述】【输入】【输出】【输入样例】【输出样例】分析代码1163:阿克曼(Ackmann)函数 时间限制:1000ms内存限制:65536KB提交数:24804通过数:20247时间限制: 1000 ms 内存限制: 65536 KB 提交数: 24804 通过数: 202…

第三十章 linux-模块的文件格式与EXPORT_SYMBOL的实现

第三十章 linux-模块的文件格式与EXPORT_SYMBOL的实现 文章目录第三十章 linux-模块的文件格式与EXPORT_SYMBOL的实现模块的文件格式EXPORT_SYMBOL的实现模块的文件格式 以内核模块形式存在的驱动程序,比如demodev.ko,其在文件的数据组织形式上是ELF&am…

数据结构---快速排序

快速排序分治法思想基准元素的选择元素交换双边循环法JAVA实现单边循环法JAVA实现快速排序也是从冒泡排序演化而来使用了 分治法(快的原因)快速排序和冒泡排序共同点:通过元素之间的比较和交换位置来达到排序的目的。 快速排序和冒泡排序不同…