当前位置:首页 » 操作系统 » 全变差算法

全变差算法

发布时间: 2023-05-13 07:39:51

算法基础

谨以此文,感谢我在这个学校最喜欢的两个老师之一——肖my老师。本文基本为老师上课说讲授内容加上一部分自己的感悟拼凑而来,写作文本的目的是为自己的算法课程留下一点点东西,站在老师肩膀上形成粗糙的框架,方便以后的复习以及深入。文笔有限,其中包含的错误还请多多包容,不吝赐教。

to do list:

时间复杂度中递归树法;动规,分治新的感悟;

点覆盖:一组点的集合,使得图中所有边都至少与该集合中一个点相连。

支配集:一组点的集合,使得图中所有的点要么属于该集合,要么与该集合相连。

最大团:在一个无向图中找出点数最多的完全图。

独立集:一组点的集合,集合中的顶点两两不相邻。(团转过来)

SAT问题:也称布尔可满足性问题。给一组变

其中Ci被称为句子。

点覆盖<->独立集<->最大团

最小割:割是一组边集。如s-t割就是如果去掉这些边,将把原图划分为两个点集,其中一个点集包含s,一个点集包含t。(两个是指不相连,而不是代表不存在边相连,如反向边)

decision problem: 是否存在。

search problem:找到一个解。

(这个还能扩展,比如decision problem在多项式时间内解决,所以他是P问题吗)

渐进符号:

注意以上三种都是紧的,对应的两个小写的符号是不紧的,即如下图所示:

概念:算法的时间复杂度是一个函数,用于定性描述算法的运行时间。注意,这个一个代表算法输入字符串长度的函数。

[注]输入字符串长度是一个比较关键的理解,比如在背包问题中,其时间复杂度为O(nW),因为W不定,所以只能是一个伪多项式时间。

比较:c < log2N < n < n * Log2N < n^2 < n^3 < 2^n < 3^n < n! < n^n

大致:常数<对数<幂函数<指数函数<阶乘

对于指数是n相关的进行比较,优先比较指数,再比较底数。

记住一个特例:n (logn)<n!<n n

计算:

一般来说,计算采用主方法和递归树法,其中递归树技巧性比较强,主方法其实也是递归树推导归纳而来,且主方法能得到一个比较紧的结果。

主方法:

f(n) = af(n-b)+g(n) =>O( a^(n/b) *g(n) )

P:decision problems有一个多项式算法。

NP(nondeterministic polynomial-time):decision problems能够在多项式时间内验证。

NPC:NP完全问题,首先这个问题是NP的,其次,其他所有问题都可以多项式时间内归约到它。

NPH:如果所有NP问题都可以多项式时间归约到某个问题,则称该问题为NP困难。

因为NP困难问题未必可以在多项式时间内验证一个解的正确性(即不一定是NP问题),因此即使NP完全问题有多项式时间的解(P=NP),NP困难问题依然可能没有多项式时间的解。因此NP困难问题“至少与NP完全问题一样难”。

一些NP问题能在多项式时间内解决,因为 P∈NP

NP难类型问题的证明:

先选好一个已知NP难的问题,然后将已知NP难问题多项式归约到要证明的问题上。先给出这个归约,然后再证明这个归约的正确性。

NPC类型问题的证明:

证明一个问题Y是NPC问题,先说明Y是NP的,然后找到一个NPC问题X,将这个问题X归约到问题Y上,即证明完成。

常见的NPC问题(重要,规约的时候有用!):

packing problems: set-packing,独立集

覆盖问题:集合覆盖问题,顶点覆盖问题

严格满足问题(constraint satisfaction problems):SAT,3SAT

序列问题:哈密尔顿回路,旅行商问题

划分问题:3D-matching, 3着色问题

数字问题:子集合问题(子集元素之和为t),背包问题

其他:分团问题(是否存在一个规模为k的团)

规约的概念与理解

规约:意味着对问题进行转换,例如将一个未知的问题转换成我们能够解决的问题,转换的过程可能涉及到对问题的输入输出的转换。

自归约:search problem <=p decision problem

归约:A归约到B,也就是说,我们对A套一个函数f,在f函数的作用下形成一个新的问题,对这个问题运用B的黑盒解法,能够解决问题A。

(B <=p A)一般说来,B问题如果可以归约到A问题,也就是说,一个解决A问题的算法可以被用做子函数(子程序)来解决B问题,也就是说,求解B问题不会比求解A问题更困难。因此,如果B问题是困难的,那么A问题也就是困难的,因为不存在求解A问题的高效算法。(最后一句不懂)

我简单说一下我理解的规约,以X规约到Y为准,大概分成两个方面:

注:在 的一些实例中细品。

概念:在对问题求解时,总是做出在当前看来是最好的选择。

贪心的证明:先假设贪心算法得到的解不是最优解,假设S1是贪心算法得到的解,而S2是所有最优解中和S1具有最多相同元素的解,然后比较S1和S2,观察S1和S2中第一个(最前面一个)不一样的元素,然后在贪心解S2中将不一样的元素换成S1中的那个元素得到另一个最优解S3,这样S3和S1比S2和S1有更多相同元素,和假设S2是与S1有最多相同元素的最优解矛盾,这样来推导S1是最优解。

我的理解:假设这个不是最优的,但是一定存在一个最优的解在某一个位置之前和我当前解结构是一样的,那么在这个位置,选最优解也可以选当前解,不影响最终答案。

[注]概念很简单,但是实际操作的时候,贪心的角度很重要,同样的贪心,方向对了,算法就是对的。

例子:

给你一系列活动,每个活动有一个起始时间和一个结束时间,要求在活动不冲突的情况下找到一种有最多活动的安排。

对于这个问题,我们有一下几种贪心的角度:

①将任务按照 开始时间 升序排列。

②将任务按照 结束时间 升序排列。

③将任务按照 任务时长 升序排列。

④对于每一个任务,都记录与其他任务冲突的数量,按照 冲突数量 的升序排列。

其中1,3,4都是不可以的。

任务结束时间的贪心证明(反证法):

假设贪心不是最最优的,那我们在最优解中找一个与当前解有最相似的解。

由图可以知道,贪心贪的就是最早结束,所以如果不是最优,那么最优的结束时间一定晚于贪心的结束时间。

由上图就可以证明。

最大流通常与最小割相联系。

f 为任意一个流,cap为容量,对于任意的s-t割出来的点集(A,B),v( f ) <= cap(A, B)。

当流增加到与割的容量相等时候,就不可能再有增长空间了,称为最大流。

对于割的容量来说,不同的割法会有不同流量,有些割法永远不会有流达到,比如部分A = {s}, B = {V - s},这种把源点割出来的割法。

综上,通过这种感性的认识,如果能找到一个最小的割,那么这个割就一定是最大能跑到的流(如果流能更高的话在这个割上就会超过容量,反证。)

上图为一条增广路,一条增广路即为一条s-t的路径,在路径上仍有流可以跑,其曾广的流就是该条路径上最小的剩余容量。(相当于每找一条增广路,就至少有一条边达到满流。)

直到在图中找不到增广路,此时已经达到了最大流。

找ST集合:把满流的边去掉,从S出发走到能到的点,遍历的点就是S集合;剩下的点就属于T集合。注意,如果找到了在找S集合的时候找到了T点,说明还可以继续找增广路。

[补]有一个很有趣的延伸,如多源点多终点问题。问:如果我有两个源点s1,s2,两个终点t1,t2,我想求一组流,使得s1-t1,s2-t2的流达到最大,是否可以加一个源点S,S与s1,s2相连,边流无限大;加一个终点T,T与t1,t2相连,边流无限大,然后这组ST的最大流即可。——答案是No,无法保证是s1-t1,s2-t2,有可能交错。

例子讲的感觉不是特别好,对理解感觉起不到很大作用,希望以后有新的想法后进行补充。

规约是一个重要的概念和思想。

一个图的 最大独立集 与 最小点覆盖 是不相交的两个点集,它们的并就是整个点集。

个人理解:独立集和点覆盖都是从点的角度进行划分的,如果我们从边的角度来看,①一个最小的点覆盖即为我集合中的每一个点都尽可能与更多的边相连,②同时,一条边的两个端点中,只能有一个端点在最小点覆盖中[下注]

[注]我们假设有一条边两个端点(u,v)都在点覆盖之中,首先显然u,v都不是端点,因为假设u是端点的话只需要选择v即可;

给一个集合S和一堆S的子集S1,S2,...,Sm,问是否存在存在k个子集,使它们的并集为S。

构造:

集合为点,集合中的元素为边,有相同元素的边相连。(注意如果某一元素只在一个子集中出现,应该怎么处理呢!)

规约:在构造的图中找最小的点覆盖,选中的点能覆盖所有的边即为对应集合的并集能包含所有的元素。所以就完成了集合覆盖到点覆盖的规约。

构造:每个句子构造一个三角形,把对应变量但是相反取值的点相连。

规约:3SAT的有一个特点就是,每一个句子中至少有一个为真即可,每个句子都必须是真。将相同变量相反取值相连的目的就是,在最大独立集中,比如选择x为真,则剩下所有句子中x-ba一定不会被选中,同时由独立集和构造出来三角形的性质可以知道,每一个句子,有且仅有一个会被选中(为真)。如上图,x1-ba为真,x2-ba和x3任选一个为真即可满足。

search problem <=p decision version

比如:如果能在多项式时间内找到一个哈密尔顿圈,那么就能在多项式时间内找到一个哈密尔顿圈(删边)

在此再谈P和NP:

我们知道有些问题是可以从搜索问题规约到判断问题的,也就是所该问题如果能在多项式内判断,那么久能在多项式中搜索到,那么我们只需要说,这个判断问题能在多项式时间内求解,就叫做P问题,也就是上图红字的意思;那NP问题呢,必须要给出一个解的实例,判断的是这个实例是否满足求解问题,这个才是上图中的红字。比如,我如果能在多项式时间内判断哈密尔顿圈是否(Yes/No)存在,那这个就是ploy-time algorithm,如果我给出了一系列点,能过多项式时间内判断这些点能否构成哈密尔顿圈,那这个就是poly-time certifier。

构造:把一个点拆分成三个点。

构造:(下面两个图要连在一起看)

从行的角度看,一行代表一个变量;从列的角度来看,每三列代表一个句子。两边中一边是两个点,一边是一个点,所以有k个句子的话,每一行有3k+3个节点。从哈密尔顿圈的答案转到3SAT的答案看这个圈在每一行是从左到右还是从右到左。

子集和问题:给一个集合S,问是否能在集合中选取元素,使得总和为W。

构造:如下图,按照前六行和前三列进行分割,可以分成4部分,其中1,3,4部分是固定的,即在第一部分,变量v列和 变量为v(包括变量及取反)的行对应的格子为0,其余为0;第三部分全为0;第四部分按照12依次写下来。第二部分,如果Ci句子中有变量v,则记为1,因为一个句子只有三个变量,可以简单通过第二部分每一列和为3进行判定。此时集合已经构造出来,W为111444,与上面的规约相似,可以通过3SAT的简单性质进行感性的认知。

近似的想法很简单,要解决一个问题,我们希望能够做到①求解结果是最优的 ②在多项式时间内解决 ③对于任意的实例都能够通过该算法解决。现在对于部分问题,无法完全满足以上要求,所以就牺牲了①,但是我们希望结果不是盲目的,所以就引入了近似的概念。

近似算法。比如2-近似,认为W为近似解,W 为最优解,在求最小值的情况下W<=2W ;在求最大值的情况下,W>=1/2W*

给m个机器和n个任务,每个任务有一个ti的执行时间,我们认为完成最后一个任务所需的时间为负载时间,希望能够让这个负载时间最短。

第一种:将任务依次放在机器上,当某个机器空闲时立即放入新任务。此时是2近似的。

证明:

引理1.最短时间安排是大于等于任务中时间最长的任务,L* >= max tj

我们在考虑放入最后一个任务前,根据我们放置的规则,该机器是耗时最短,也就是说,该机器此时的用时是低于除掉最后一个任务后的平均时长,更低于所有任务的平均时长(引理2);再根据引理1,最后一个任务应该是小于最优解的。

补充:

在这里,我还想讨论一下这个近似算法的中等于符号,先上结论:等号不一定能够找到一个实例,但是可以构造出一种结构,通过取极限求得,我们认为这样 也算是紧的。

构造实例:有m个机器,其中m(m-1)个任务的用时为1,1个任务的用时为m。肯定有一种任务集合,可以按照以下方式进行安排,此时的贪心解为19。

此时最佳的解为10,如下图:

通过推广可以知道此时的比为(2m-1)/m,当m取极限,能够达到2倍。

第二种:将任务从大到小排序,然后依次放在机器上,当某个机器空闲时立即放入新任务。此时是2近似的。

引理3:如果有大于m个任务,那么L*>=2t(m-1)。证明:t(m+1)是目前最短的任务,且目前所有机器上都有任务了,所以该任务加入时最优的情况不过是加入设备的原有任务刚好和t(m+1)相等,即等号。

(2近似)在n个点中,选取k个中心点,使得这些中心点能够以半径R的圆包含所有的点,让其中最大的半径最小,如下图所示:

基础:距离需要满足的三个定理①(同一性)dist(x, x) = 0 ②(自反)dist(x, y) = dist(y, x) ③(三角不等式)dist(x, y) <=dist(x, z)+dist(z, y)

r(C)为C集合中所有点的最大覆盖半径。(需要求min r(C))

算法:在点集中任选一个作为中心点,然后重复以下步骤k-1次:选取距离已选点集中最远的点,加入点集。

证明:先假设r(C )< 1/2 * r(C)以选好的点画半径为1/2 * r(C)的圆,显然可知[注],这个圆里有且仅有一个r(C )中的点。那么根据在下图中,根据三角不等式可以得出:

[注]在每个点上r(c )一定会包含到c点,而r(C )<1/2 * r(C),相当于大圆套小圆,所以c*一定在c的圆中。

(2近似)问题还是很好理解的,在点上加权值,要找一个点覆盖,使得权值最小。如下图左边就是一个带权的最小点覆盖。

算法: 任选一条边(i, j)加上代价,这个代价从零开始,且这个代价的最大值低于i和j节点的权值。显然,这个边权值的最大值取决于两个端点权值的最小值,我们认为当边权值与点权值相等时,对应的那个点是紧的。把所有紧的点找出来即为点覆盖。

流程:

证明:

引理:边权之和小于等于点覆盖的点权之和。这主要是由于涉及到一条边上两个点都被选(紧的)的情况,感性认知可以看上图,缩放证明如下:

w(S)是等于所选的节点的权值之和的,等于所选节点节点所对应的边权之和,可以把它放大到所有节点对应边权之和,这样因为一条边(u, v)在u上算过一次后还要在v上算一次,所以等于边权和的两倍。再由上面引理可得。

主要为了线性规划和整数规划。

(2近似)没啥好说的,只需要把方程构造出来就行了。

由于求解出来结果不一定是整数,所以我们认为某一点的值大于1/2,就选入点集。

证明:

因为xi+xj >=1,且都是正数,那必至少一个点是大于1/2的(反证,两个都小于1/2则和小于1)。

给你n个物品和一个背包,每个物品有一个价值v和一个大小w,背包的容量是W,要求让背包装下尽可能大价值。

背包的时间复杂度:O(nW)

注意其中n表示物品的个数,无论是1个还是999个,他都是多项式的,这个很好理解。但是W就不一样了,这是一个数字。我理解的是这个数字会很奇特,比如1.00001,比如99999,这些有可能看起来不大但是实际在处理的时候很难处理的数字,统一的来说,如果我们把这些数字放在电脑上,都会以二进制的方式存储起来,有些数字用十进制表示很小,但是放在二进制上面就会很大,由W导致不能在多项式时间内解决(找不到一个范围/上界来框它)。

算法: 为了处理这个问题,我们改动了dp的状态转移方程,要让这个转移方程和W无关[注]。

此时还不是多项式的,然后我们再对value进行约。[注]

[注]这两步中,我们把w改成v,并对v进行近似处理。OPT的含义变成了,在面对是否选择第i个物品时,要想让价值达到当前值,最少的weight。理由是更改后的误差是可以忍受的:对v进行近似,结果只会出现最大价值的上下误差,如果对w进行近似,则有可能出现该物品不能放入背包中,导致整个物品直接放弃的情况。

㈡ 简评三个基于VRF的共识算法

上交所技术公司  朱立

Algorand、Dfinity和Ouroboros Praos三个共识算法(Dfinity虽然是项目名,这里用来称呼其共识算法也应无不妥)近期较受关注,而且都是基于VRF(Verifiable Random Function) 设计,可以对照学习。Algorand的版本很多,以下单指  1607.01341v9 ,暂称其为Algorand'(笔者手中另有Algorand的 最新版本 ,其中已对下文提及的几处问题完成了修正,可与本文参看)。

一、VRF的共性

VRF的意义很好理解——用以完成出块人(群)的随机选择。为此,VRF的返回值应尽力难以预测。先看Algorand'和Dfinity的套路是怎么做的:大体上是先将前一个随机数(最初的随机数却是协议给定的)和某种代表高度、轮次的变量进行组合,用某种私钥对之进行签名(或者是先签名再组合),最后哈希一下得出最新的随机数。这样产生的随机数旁人很容易验证其合乎算法,"V"就这样得到了;而哈希返回值又是随机分布的,“R”也因此得到保证。在此过程中,为降低操纵结果的可能性,有两个注意事项: A) 签名算法应当具有唯一性,也就是用同一把私钥对同样的信息进行签名,只有一个合法签名可以通过验证——普通的非对称加解密算法一般不具备这个属性,如SM2。如果用的签名算法没有这种uniqueness属性,那在生成新随机数的时候就存在通过反复多次尝试签名以挑出最有利者的余地,会降低安全性。 B) 避免在生成新随机数时将当前块的数据作为随机性来源之一,比如引用本块交易列表的merkle root值等等,因为这样做会给出块人尝试变更打包交易顺序、尝试打包不同交易以产生最有利的新随机数的余地。在设计和检视新的共识算法时,以上两个注意事项是要特别留意的。

考察一下VRF的返回结果应该如何运用。目前所见用法中,VRF的返回结果可以用来公开完成节点或节点群体的选择,也可以私密地完成选择。以Dfinity为例,它是利用mod操作来唯一、公开地确定一个Group。Algorand'、Ouroboros Praos是私密选择的范例,大致套路是对VRF的最新返回值,配上轮次等变量后用私钥进行签名并哈希,如果哈希值小于某个阈值,节点就可以私密地知道自己被选中。这种方法很可能在网络节点数较多时的表现会更稳定,否则幸运儿个数上下波动会较大,进而影响协议表现,包括空块和分叉。

二、简评强同步假设版本的Algorand'

私密选择提供了较强的抗击定点攻击的能力,但由于幸运儿的总数对于任何一个幸运儿都是不能预知的,也因此给后续共识算法的设计和区块链的优化带来了困难。Algorand‘采用了很强的同步网络假设(同步网络假设下的共识算法当然容易做一些),要求预先知道网络消息传播时间的上限:在固定时间内完成对固定比例的用户的网络传播。比如要知道,1KB消息,在1秒钟内完成全网95%的传播,而1MB消息需要1.5分钟完成全网95%的传播。但这个传输上限应该如何选择? 通过一段时间的统计结果再乘以一个系数这种经验统计?只能说“感觉上可以”,但如果要严谨和安全,Algorand‘算法应该补充证明即使在遭遇DDOS或互联网拥堵的情况下消息传播严重超限后算法仍然能够保证安全——然而这个证明是缺失的。作为对照,Ouroboros Praos公开承认之前在同步网络假设下设计的Ouroboros协议在异步网络条件下会出错,所以才又做了Ouroboros Praos;新版本的Algorand承认在弱同步网络时会在不同的块上达成共识(后续网络恢复强同步时分叉可以得到解决)云云,这些都可资参考。

即使我们暂且认可Algorand'算法可以通过设定一个很大的传播时间上限来回应上述问题,但随之而来的是此时可以看出此算法缺乏一个非常好的特性:Responsiveness。这个特性指的是:若一个协议被设计为在一个较大的传播时间上限DELTA下工作,但若实际传播时间是较小的delta,则协议的实际推进步调将只和delta有关,这种协议被称为Responsive的。具有Responsive特性的共识算法再配以同步网络假设会非常理想——出于安全,上限可以设置很大,然而协议执行速度只和当时网络条件有关。Algorand'并不具有这种特性。平均而言,Algorand'完成共识所需的消息传送次数是11轮,每轮如果要确保安全,完成共识的时间就会很长,单个分区的吞吐量就不会太高。当然,架构设计涉及很多取舍,最终评价一个算法好还是不好还是要回到初心——准备拿来实现的目标是什么。上述分析只是尝试客观地指出Algorand'算法的几个少为人知的固有特征,供读者自行评估。

三、简评Dfinity的可扩展性问题

私密选择并且立即上任的做法,也给系统分片带来了极大挑战。Dfinity是明确要做分片(Sharding)的,所以必须直面挑战。可扩展性问题非常复杂,完整解决这个问题需要通盘考虑网络、存储、计算三方面的可扩展性——时下大多数区块链3.0项目只注意到计算的分片和可扩展性,忽略了其余二者,从而不可能真正实现理想的扩展。由于公链节点网络带宽的制约,计算合约所需的数据通常很难迅速地从一个节点拷贝到另一节点,所以就算用VRF实现了飘忽来去的出块节点选择,存储节点是没法同样飘逸如风的。明显的选择有那么几个:全部节点存储全部数据,不同节点静态地分配用来存储不同分区。前者的可扩展性很差,对于后者而言,如果出块节点漂浮不定且出块节点还需要完成合约运算,就意味着基于P2P网络来回远程访问存储,性能多半急剧下降;动态决定的出块节点只完成排序共识,计算能力和存储捆绑,通过静态分区提供可扩展性,可能是合理的应对。然而,最可恨的就是“然而”二字——即使如此,系统还存在一处对存储和网络构成压力的所在:最终用户提交的待打包交易。普通公链(先不考虑EOS那种)的带宽有限,如果用户提交的待打包交易必须粗放型地全网泛滥传播,那现有网络带宽可以提供多少TPS?如果出块节点是静态分区或者至少提前一段时间公开知晓,事情尚有回旋余地;如果出块节点是如此飘忽不定,而且直到最后一刻也只有这些节点自己知道,那无论是用户还是出块节点候选人看起来最直接的应对之道就是全网泛滥传播全部待打包交易、保存全部待打包交易,这样带宽和存储仍然成为系统瓶颈。

所以这里碰到的,本质上还是安全、可扩展性、去中心化的不可能三角。

四、简评Ouroboros Praos

BM怼 Ouroboros的文字已经流传广泛。BM的话当然有些明显是不对的,比如Ouroboros的DPOS是指"Dynamic [stake distribution] POS"而不是BM的Delegate POS,但其关于Pareto分布的评论则值得玩味。如果我们仔细浏览后出的Ouroboros Praos,可以发现协议的安全假设和安全证明完全没有考虑经济博弈因素,因此洋洋洒洒的证明很可能会不得要领而错过真正需要防护的方向——毕竟一直以来POS/DPOS这些协议的血管里面流淌的就是基于经济博弈和人性进行设计的血液。最明显的例子是在forward secure signature的实现方法上,协议目前的设计是要求每个好的节点自觉主动地安全删除用过的私钥,而完全没有考虑近乎零的私钥保存成本如何面对bribe attack的诱惑,然而这却是值得考虑的。除了形式化证明之外,Ouroboros Praos本身并没有太多值得关注的协议特征,总体上就是用VRF抽签结合POS算法并针对某些安全假设进行了形式化证明,其做事的态度是非常值得赞赏的。

五、总结

这几个算法本身颇有创意,也很值得学习。与此同时,在看过以太坊CASPER目前披露的分区技术后,笔者的体会是:区块链3.0的竞争才刚刚开始,从以太坊团队的技术路线看,他们的技术考量和选择要比很多宣称要超越以太坊的团队来得深刻和全面。如果当真要超越以太坊,还是应该先从理解以太坊开始。

顺便感谢趣链邱炜伟博士对本文的贡献!

㈢ GIS 学科都是有哪些重要的算法谢谢

一 空间数据压缩算法
1 基于矢量的压缩算法
2 基于栅格的压缩算法

二 空间数据内插算法
1 点的内插算法
2 区域内插算法
3 采样点曲线拟合

三 空间数据转换算法
1 矢量数据向栅格数据转换
2 栅格数据向矢量数据转换
3 TIN向规则格网DEM转换

四 空间数据误差分析算法
1 属性误差的分析算法
2 位置误差分析算法

五 多边形自动生成与裁剪算法
1 多边形性质及有关处理
2 弧-弧拓扑生成算法
3 多边形自动生成算法
4 多边形图裁剪算法

六 TIN的构建算法
1 基于离散点的构TIN算法
2 基于等高线的构TIN算法

七 Voronoi图构建算法
1 平面点集Voronoi图构建算法
2 线/面集Voronoi图构建算法
3 球面Voronoi图构建算法

八 空间变换算法
1 地图坐标变换算法
2 地图投影变换算法
3 透视投影变换算法

九 空间度量算法
1 空间距离与方向度量算法
2 面向度量算法
3 体积度量算法
4 坡度坡向度量算法

十 数字地形分析算法
1 基本地形因子分析算法
2 地形特征提取算法
3 数字地形典型应用算法

十一 空间统计分析算法
1 多变量统计分析算法
2 空间分类统计算法
3 层次分析算法

十二 空间分析算法
1 路径分析算法
2 资源分配算法
3 缓冲区分析算法
4 叠置分析算法

十三 GIS可视化操纵算法
1 地形简化算法
2 多分辨率纹理生成算法
3 纹理映射算法
4 光相关算法

十四 空间数据挖掘与知识发现算法

㈣ 深入浅出BP神经网络算法的原理

深入浅出BP神经网络算法的原理
相信每位刚接触神经网络的时候都会先碰到BP算法的问题,如何形象快速地理解BP神经网络就是我们学习的高级乐趣了(画外音:乐趣?你在跟我谈乐趣?)
本篇博文就是要简单粗暴地帮助各位童鞋快速入门采取BP算法的神经网络。
BP神经网络是怎样的一种定义?看这句话:一种按“误差逆传播算法训练”的多层前馈网络。
BP的思想就是:利用输出后的误差来估计输出层前一层的误差,再用这层误差来估计更前一层误差,如此获取所有各层误差估计。这里的误差估计可以理解为某种偏导数,我们就是根据这种偏导数来调整各层的连接权值,再用调整后的连接权值重新计算输出误差。直到输出的误差达到符合的要求或者迭代次数溢出设定值。
说来说去,“误差”这个词说的很多嘛,说明这个算法是不是跟误差有很大的关系?
没错,BP的传播对象就是“误差”,传播目的就是得到所有层的估计误差。
它的学习规则是:使用最速下降法,通过反向传播(就是一层一层往前传)不断调整网络的权值和阈值,最后使全局误差系数最小。
它的学习本质就是:对各连接权值的动态调整。

拓扑结构如上图:输入层(input),隐藏层(hide layer),输出层(output)
BP网络的优势就是能学习和储存大量的输入输出的关系,而不用事先指出这种数学关系。那么它是如何学习的?
BP利用处处可导的激活函数来描述该层输入与该层输出的关系,常用S型函数δ来当作激活函数。

我们现在开始有监督的BP神经网络学习算法:
1、正向传播得到输出层误差e
=>输入层输入样本=>各隐藏层=>输出层
2、判断是否反向传播
=>若输出层误差与期望不符=>反向传播
3、误差反向传播
=>误差在各层显示=>修正各层单元的权值,直到误差减少到可接受程度。
算法阐述起来比较简单,接下来通过数学公式来认识BP的真实面目。
假设我们的网络结构是一个含有N个神经元的输入层,含有P个神经元的隐层,含有Q个神经元的输出层。

这些变量分别如下:

认识好以上变量后,开始计算:
一、用(-1,1)内的随机数初始化误差函数,并设定精度ε,最多迭代次数M
二、随机选取第k个输入样本及对应的期望输出

重复以下步骤至误差达到要求:
三、计算隐含层各神经元的输入和输出

四、计算误差函数e对输出层各神经元的偏导数,根据输出层期望输出和实际输出以及输出层输入等参数计算。

五、计算误差函数对隐藏层各神经元的偏导数,根据后一层(这里即输出层)的灵敏度(稍后介绍灵敏度)δo(k),后一层连接权值w,以及该层的输入值等参数计算
六、利用第四步中的偏导数来修正输出层连接权值

七、利用第五步中的偏导数来修正隐藏层连接权值

八、计算全局误差(m个样本,q个类别)

比较具体的计算方法介绍好了,接下来用比较简洁的数学公式来大致地概括这个过程,相信看完上述的详细步骤都会有些了解和领悟。
假设我们的神经网络是这样的,此时有两个隐藏层。
我们先来理解灵敏度是什么?
看下面一个公式:

这个公式是误差对b的一个偏导数,这个b是怎么?它是一个基,灵敏度δ就是误差对基的变化率,也就是导数。
因为?u/?b=1,所以?E/?b=?E/?u=δ,也就是说bias基的灵敏度?E/?b=δ等于误差E对一个节点全部输入u的导数?E/?u。
也可以认为这里的灵敏度等于误差E对该层输入的导数,注意了,这里的输入是上图U级别的输入,即已经完成层与层权值计算后的输入。
每一个隐藏层第l层的灵敏度为:

这里的“?”表示每个元素相乘,不懂的可与上面详细公式对比理解
而输出层的灵敏度计算方法不同,为:

而最后的修正权值为灵敏度乘以该层的输入值,注意了,这里的输入可是未曾乘以权值的输入,即上图的Xi级别。

对于每一个权值(W)ij都有一个特定的学习率ηIj,由算法学习完成。

㈤ SAM算法理解

SAM算法过程基于数据的噪音分析。一般的,信噪比会随着信号的降低而减小。然而当人们针对每一个基因进行分析时,发现即使他们的信号在同一水平,每一个基因的表达噪音都不一样。所以无法笼统地给出一个具体地线性方程来分析全部基因,必须一个一个基因单独分析。假设有对照实验I和U两组局拆,I和U实验各有平行实验w组,对于某个指定的基因i,定义相对差异值 (relative difference(d(i)))为基因i在实验组I和U当中的平均值之差除以I和U的总体标准误差均值。因为当标准误差均值过低时,会产生一个较高的d(i)值,所以总体的标准误差均值增加了一个较正项。具体公式如下:

其中上划线表示平均值 ,å m 和å n 表示实验组I和U的基因i表达的样本标准差,n1和n2表示实验组I和U当中基因i参与统计的探针的个数。S0为较正谈腊陆项,它可以由计算机自动给出,也可以由人手动指定。S0的取值标准是:将所有的d(i)值排序后100等分,每一等分先求得中位数绝对离差,然后计算这些中位数绝对离差值的变异系数。取s0分别等于100等分当中的s(i)的最小值,依次计算。最终s0的值就是在这些计算中,使变异系数最小的s0。

我们来比较一下它和t-test的异同:

[图片上传失败...(image-92c592-1597045517277)]

比较之下,我们就会发现两者十分的相同。左边是两组具有不同探针数和不同标准差的非平行实验t-test计算公式,右边就是具有不同探针数和不同标准差的非平行实验的SAM公式,我们可以看到,它们的最终差别,只在那个s0附加项上。由此我们可以知道,实际上SAM就是t-test的一个具体应用。

在计算得到所有的d(i)值之后,重排样含顷品计算d(i)期待值d E (i)。然后用期待值d E (i)对实测值d(i)做图。如果期待值和实测值相同,那么作图点就应该落在斜率为1的直线上,如果不同,作图点就落在其外。差别越大,距离该直线就越远。给定一个D值(默认的话,可以设置为1.2),当期待值和实测值差别比D大时,就认为有显着差异。这就是SAM算法。

下面我们就来使用R来实践一下SAM算法。

<pre style="box-sizing: border-box; font-family: "Roboto Slab", Georgia, Times, serif; font-size: 1em; font-weight: 300; font-style: inherit; margin: -2px 0px 27px; padding: 0px; vertical-align: baseline; border: 0px; outline: 0px; line-height: 27px; overflow: auto; max-width: 100%; background: transparent; color: rgb(102, 102, 102);">##安装SAM库

--- Please select a CRAN mirror for use in this session ---

also installing the dependency ‘impute’

trying URL ' http://software.rc.fas.harvard.e/mirrors/R/bin/windows/contrib/2.11/impute_1.24.0.zip'

Content type 'application/zip' length 1205991 bytes (1.2 Mb)

opened URL

downloaded 1.2 Mb

trying URL ' http://software.rc.fas.harvard.e/mirrors/R/bin/windows/contrib/2.11/samr_1.28.zip'

Content type 'application/zip' length 80418 bytes (78 Kb)

opened URL

downloaded 78 Kb

package 'impute' successfully unpacked and MD5 sums checked

package 'samr' successfully unpacked and MD5 sums checked

The downloaded packages are in

Loading required package: impute

Background correcting

Normalizing

Calculating Expression

</pre>

SAM分析。我们首先来了解一下samr函数。

我们注意到其参数resp.type有以下几种类型:"quantitative" 定量反应,其中data参数当中的y必须是数值型数组; "Two class unpaired" 比较两种不同条件下的结果,其中data参数当中的y必须是1或者2数组,即要么值属于其中一种条件,要么属于另外一种条件; "Survival" for censored survival outcome; "Multiclass" : 两组以上实验条件,其中data参数当中的y是自然数数组,指定实验条件编号; "One class" 单组实验,y是1的数组; "Two class paired" 比较两种不同条件下的结果,并且实验是成对进行的,其中data参数当中的y是-1,1,-2,2……-k,k这样成对出现的数组; "Two class unpaired timecourse", "One class time course", "Two class.paired timecourse" or "Pattern discovery"与时间相关的比较,y值必须是kTimet这种形式,其中k是组编号,t是时间,Time就是字符Time,起始的时间点要为kTimetStart格式,结束的点要为kTimetEnd格式。

Table 1 Resp.type取值范围

| Resp.type | 取值 |
| Quantitative | 实数,例:27.4 或者-45.34 |
| Two class (unpaired) | 整数1,2 |
| Multiclass | 整数1,2,3,…… |
| Paired | 整数-1,1,-2,2等等成对出现,通常认为负号代表未处理的对照组,正号代表实验组;-1总是与1配对,-2与2配对直至-k与k |
| Survival data | (Time, status)这种成对的数字,比如(50,1),(120,0)。第一个数字代表时间,第二个数字代表状态(1=死亡,0=存活) |
| One class | 整数1 |

在示例的数据中,实验设计为estrogen存在与不存在,及作用10及48小时的比较。因为时间点过少,不足以形成timecourse,所以我们用多组来比较吧。

<pre style="box-sizing: border-box; font-family: "Roboto Slab", Georgia, Times, serif; font-size: 1em; font-weight: 300; font-style: inherit; margin: -2px 0px 27px; padding: 0px; vertical-align: baseline; border: 0px; outline: 0px; line-height: 27px; overflow: auto; max-width: 100%; background: transparent; color: rgb(102, 102, 102);">> gp=rep(1:4,each=2)

</pre>

SAM算法因为其提供有 Microsoft Excel插件,所以使用非常广泛,相反,其在R当中的应用却显得相对较少。有研究表明,SAM对FDR的控制并不是很好,这是它最主要的不足。

㈥ 什么是H-K算法

其实HK算法思想很朴实,就是在最小均方误差准则下求得权矢量.
他相对于感知器算法的优点在于,他适用于线性可分和非线性可分得情况,对于线性可分的情况,给出最优权矢量,对于非线性可分得情况,能够判别出来,以退出迭代过程.
2.在程序编制过程中,我所受的最大困扰是:关于收敛条件的判决.
对于误差矢量:e=x*w-b
若e>0 则继续迭代
若e=0 则停止迭代,得到权矢量
若e〈0 则停止迭代,样本是非线性可分得,
若e有的分量大于0,有的分量小于0 ,则在各分量都变成零,或者停止由负值转变成正值时,停机.
3.在程序编制中的注意点:
1)关于0的判断,由于计算机的精度原因,严格等于零是很不容易的,而且在很多情况下也没有必要,则只要在0的一个可以接受的delta域内就可接受为零
2)关于判断,迭代前后,变量是否发生变化
在判断时,显然也不能直接判断a(i)==a(i+1)
而应该|a(i)-a(i+1)|〈err
4.HK详细代码如下:
unction [w,flag]=HK(data)
Iteration=20;
flag=0;
% [n,p]=size(data);
n=size(data,1);
b=ones(n,1)./10;
c=0.6;
xx=inv(data'*data)*data';
w=xx*b;
e=data*w-b;
t=0;
while (1)
temp=min(e);
temp1=max(e);
if temp>-1e-4 && temp1e-3
deltab=e+abs(e);
b=b+c.*deltab;
w=w+c.*xx*deltab;
e=data*w-b;
else
if temp>=0 && temp1

H-K算法是求解Xw=b,式中b=( b1, b2, …, bn)T,b的所有分量都是正值。这里要同时计算w和b,我们已知X不是N*N的方阵,通常是行多于列的N*(n+1)阶的长方阵,属于超定方程,因此一般情况下,Xw=b没有唯一确定解,但可求其线性最小二乘解。
设Xw=b的线性最小二乘解为w*,即使||Xw*-b||=极小 采用梯度法,定义准则函数:
)bXw()bXw(2
1bXw21)bxw(21)b,x,w(JT2
n1i2iiT
当Xw=b的条件满足时,J达到最小值。由于上式中包括的
n
1
i2iiT
)bxw
(项为两个数量方差的和,且我们将使其最小化,因此也
称之为最小均方误差算法。
使函数J同时对变量w和b求最小。对于w的梯度为:
)bXw(Xw
J
T 使0w
J
,得XT(Xw-b)=0,从而XTXw=XTb。因为XTX为(n+1)*(n+1)阶方阵,因此可求得解:
w = (XTX)-1XTb = X#b
这里X#= (XTX)-1XT称为X的伪逆,X是N*(n+1)阶的长方阵。
由上式可知,只要求出b即可求得w。利用梯度法可求得b的迭代公式为:
)
k(bbbJC)k(b)1k(b

根据上述约束条件,在每次迭代中,b(k)的全部分量只能是正值。由J的准则函数式,J也是正值,因此,当取校正增量C为正值时,为保证每次迭代中的b(k)都是正值,应使)
k(bbbJ

为非正值。在此条件下,准则函数J的微分为:
|bXw|)bXw(bJ2)
k(bb

该式满足以下条件:
若[Xw(k) – b(k)] > 0,则)k(b)k(XwbJ)
k(bb

 若[Xw(k) – b(k)] < 0,则0bJ)
k(bb 由b的迭代式和微分,有:
b(k+1) = b(k) +δb(k)
δb(k) = C[Xw(k) – b(k) + | Xw(k) – b(k)|]
将此式代入w=X#b,有:
w(k+1) = X#b(k+1) = X#[b(k) +δb(k)] = w(k) + X#δb(k)
为简化起见,令e(k) = Xw(k) – b(k),可得H-K算法的迭代式。
设初值为b(1),其每一分量均为正值,则:
w(1) = X#b(1) e(k) = Xw(k) – b(k)
w(k+1) = w(k) + X#{C[Xw(k) – b(k) + |Xw(k) – b(k)|]}
= w(k) + CX#[e(k) + |e(k)|]
由于
X#e(k) = X#[Xw(k) – b(k)] = (XTX)-1XT[Xw(k) – b(k)]

= w(k) –X#b(k) = 0
因此
w(k+1) = w(k) + CX#|e(k)|
b(k+1) = b(k) + C[Xw(k) – b(k) + |Xw(k) – b(k)|]
= b(k) + C[e(k) + |e(k)|]

㈦ 算法与计算公式的区别请举例说明

算法是程序执行的一系列步骤和方法。
计算公式是计算的方法。
计算公式也可以用于算法当中,算法不仅是数的运算步骤,也是其他非数的执行的步骤和方法,如华罗庚的烧水,做饭的步骤一样。计算公式就是用来提供给算法应用的一种而已。

㈧ 基因组序列比对算法介绍(一)

基因组重测序中序列比对介绍

重测序基因组数据比对,是指将测序仪下机fastq数据(NGS read序列,通常100-150bp),与人类参考基因组(reference)进行匹配,允许错配(mismatch),插入缺失(indel),目的是在参考基因组找到序列最相似的位置,通常是基因组分析(包括 variation calling,ChIP-seq,RNA-seq,BS-seq)流程的第一步。

常用算法

图一

汉明距离(Hamming distance)表示两个(相同长度)字对应位置不同的数量,我们以d(x,y)表示两个字x,y之间的汉明距离。对两个字符串进行异或运算,并统计结果为1的个数,那么这个数就是汉明距离。图中read1最佳位置的方法,就是通过查找最小汉明距离的实现的。

编辑距离(Edit distance)是针对二个字符串(例如英文字)的差异程度的量化量测,量测方式是看至少需要多少次的处理才能将一个字符串变成另一个字符串。图中read3最佳位置,通过查找最我辑距离的方法实现。

图二

全局比对(Global alignment):全局比对是指将参与比对的两条序列里面的所有字符进行比对。全局比对在全局范围内对两条序列进行比对打分,找出最佳比对,主要被用来寻找关系密切的序列。其可以用来鉴别或证明新序列与已知序列家族的同源性,是进行分子进化分析的重要前提。其代表是Needleman-Wunsch算法。图一中,read3使用全部比对。

局部比对(Local alignment):与全局比对不同,局部比对不必对两个完整的序列进行比对,而是在每个序列中使用某些局部区域片段进行比对。其产生的需求在于、人们发现有的蛋白序列虽然在序列整体上表现出较大的差异性,但是在某些局部区域能独立的发挥相同的功能,序列相当保守。这时候依靠全局比对明显不能得到这些局部相似序列的。其次,在真核生物的基因中,内含子片段表现出了极大变异性,外显子区域却较为保守,这时候全局比对表现出了其局限性,无法找出这些局部相似性序列。其代表是Smith-Waterman局部比对算法。图一中,read2使用局部比对。

图三

Smith-Waterman算法介绍

Smith-Waterman是由Temple F. Smith和Michael S. Waterman于1981年提出的一种进行局部序列比对(相对于全局比对)的算法,用于找出两个核苷酸序列或蛋白质序列之间的相似区域。该算法的目的不是进行全序列的比对,而是找出两个序列中具有高相似度的片段。S-W算法基于动态规划,它接受任意长度、任意位置、任意序列的对齐,并确定是否能找到最优的比对。

简单地说就是,动态规划找到问题中较小部分的解,然后把它们放在一起,形成整个问题的一个完整的最优最终解。

它优于BLAST和FASTA算法,因为它搜索了更大的可能性,具有更高的敏感性。

S-W算法不是一次查看整个序列,而是对多个长度的片段进行比较,寻找能够最大化得分的片段。算法本身本质上是递归的:

图四

算法步骤如下:

基因组分析***** 微信 公众号推出 《50篇文章深入理解NGS》系列文章, 第三篇文章 《基因组序列比对算法介绍(一)》,争取每周更新一篇高质量生信干货帖子。

关注 "基因组分析" 微信公众号,了解最新最全生信分析知识。

㈨ 阿里面试官:恕我直言,搞懂这10道算法题,轻松拿20K不是问题

01打怪兽

难度:容易

现在有3只怪兽,他们的都有自己的血量a,b,c(1<=a,b,c<=100),当Tom打死第一怪兽的时候花费的代价为0,其余的怪兽的代价为当前的怪兽的血量减去上一个怪兽的血量的绝对值。问Tom打死这些怪兽所需要的最小代价

02数组变换

难度:中等

给出一个长度为 n 的数组,和一个正整数 d。 你每次可以选择其中任意一个元素 a[i] 将其变为 a[i] + d 或 a[i] - d,这算作一次操作。你需要将所有的元素全部变成相等元素,如果有解,请输出最小操作次数,如果无解请输出-1。

01超级区间

难度:中等

Tom现在有一个长度为n的数组,Jerry给Tom定义了一种超级区间,如果区间[l,r]满足(a[l]+…+a[r])>=k,则区间[l,r]被称为超级区间,现在Jerry想让Tom告诉他数组中有多少个超级区间。

02能量半径

难度:中等

codancer来到了一个能量平面上的中心,坐标为(0,0),接下来巫师Tom会在q个坐标上放置能量点,每个能量点的能量值为1,为了打败哥斯拉,他需要至少k点的能量,因此他想确定一个最小的整数半径r使得codancer能够从这个圆心为(0,0),半径为r的圆形区域内得到至少k个能量值,请你帮他确定最小的整数半径r。

01找出二叉搜索树的第2大的数

难度:容易

给定一个二叉搜索树,找出其第二大的数。

02字符配对

难度:中等

给你一个字符串,字符串中仅包含"A","B",现在有四种字符串"AA","AB","BA","BB",每种字符串都有他们的权值,问从给出的字符串中能够得到的最大权值为多少(一个字符只能属于一个子字符串)?

01斐波那契字符串

难度:中等

Tom发现了一种神奇的字符串-斐波那契字符串,定义f[1]=0,f[2]=1,对于所有的i>2都有f[i]=f[i-2]+f[i-1],其中“+”代表拼接,比如01+10=0110,现在对于字符串f[n],请判断f[n]的第k项是0,还是1?

01Hikari and Interstellar Experience

难度:容易

在无垠的宇宙中,有 n 个星球,第 i 个星球有权值vi 。由于星球之间距离极远,因此想在有限的时间内在星际间旅行,就必须要在星球间建立传送通道。 任意两个星球之间均可以建立传送通道,不过花费并不一样。 第 i 个星球与第 j 个星球的之间建立传送通道的花费是lowbit(vi ⊕ vj) ,其中⊕为二进制异或,而lowbit(x)为 x 二进制最低位的值,例如lowbit(5) = 1,lowbit(8) = 8 。 特殊地,lowbit(0) = 0。 Hikari 想在这 n 个星球间穿梭,于是――你需要告诉 Hikari,要使这 n 个星球相互可达,需要的花费最少是多少?

02二进制字符串

难度:中等

Tom得到了一个二进制字符串s,即s只由Ɔ'和Ƈ'组成,现在令d(t)代表二进制字符串t在十进制下的值。 那么d(“011”)=3,d(“0001000”)=4,如果t的长度等于d(t),那么就称t是奇妙串,现在Tom想知道s中有多少个子串是奇妙串?

01小明的数学作业

难度:容易

众所周知,小明是一个数学小能手,有一天数学老师给了小明一个长度为n(2<=n<=5000)的序列,其中第i个数是ai(0<=ai<=1e9),数学老师想知道这个序列排序后,其中最长的等差子序列的长度是多长,聪明的你能帮小明解决这个问题吗?

02Codancer上楼

codancer来到了一栋大楼前,现在他要上楼。

如果codancer从第x层走楼梯到第y层(y>x),那么他所花费的时间是a[x]+a[x+1]+…+a[y];

如果他从x层坐电梯到第y层,那么他所花费的时间是c+(b[x]+b[x+1]+…+b[y]),因为他等电梯的时间为c。

现在codancer想知道从第1层到第n层需要最少需要多长时间?

01变换的秘钥

难度:中等

Tom最开始有一个密钥s1,s1是长度为n的由小写字母组成的字符串。Jerry也有一个长度为n的由小写字母组成的密钥s2。现在有m组关系,每组关系由两个数字[u,v]构成(1<=u,v<=26),表示26个字母表中的第u个小写字母可以直接转换为第v个小写字母。假设u=1,v=2,那么说明字母'a'可以直接转换为字母'b'。现在Tom对于s1的每个字母使用无数次转换,请判断s1能否转换为s2?

01最大边权和

难度:简单

现在有n个点(1<=n<=1000),每个点都有一个值称为点权ai(ai为偶数,1<=ai<=1000),现在可以将任意两个点相连,连起来以后这条边也有一个值称为边权,这个边的边权为这两个点的点权之和的一半。现在需要你添加n-1条边,问将这n个点连通以后(连通是指任意两个点都能互相到达)的最大的边权和是多少?

02钱庄

难度:中等

钱庄每天能够收到很多散钱,第i个散钱的值2 wi。为了便于管理,钱庄每天都会向中央银行申请兑换钱币,假设钱庄有一些散钱使得2 k1+2 k2+...+2 km=2^x(x为非负整数),那么就可以将这些散钱兑换成一个大钱币,问在钱庄收到的这些散钱最终最少能变成几个钱币?

01codancer的旅行

难度:困难

期末考试终于结束啦,Codancer开始了他的旅行,现在整个地图上有n个城市,这些城市之间有n-1条道路相连,每条道路都有一个距离,并且保证整个图是连通的,即这个地图可以看作是一棵树,现在假设Codancer要从城市A到城市B,那么他的路费就是从A-B的路径上边权最大的边的权值wmaxx元。现在Codancer有k元,他想知道他能选择那些(A,B)并且A<B使得codancer能够到达?

HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干。

01全奇数组

难度:中等

codancer现在有n个正整数a[1],a[2]…a[n],Tom告诉codancer他可以进行下列操作,选择某个偶数x,把这n个数中全部等于x的数字除2,Tom想知道把这n个数字全部变成奇数最少需要几次这样的操作?

以上十道算法题你都能搞定嘛?备战大厂每日刷一道算法题来提升自己,坚持坚持再坚持,必然会有收获。为大家整理一份781页的高分宝典,知识较为全面,可分享给想要学习提升自己的朋友。

领取方式:私信【面试宝典】或点击右方链接: https://shimo.im/docs/QVy8HrQgPYkx9Ddg/ 即可免费领取,喜欢本文不妨关注+转发支持一下~~

热点内容
dns服务器怎么看 发布:2025-05-15 22:17:27 浏览:149
3dm的压缩包 发布:2025-05-15 22:09:23 浏览:661
和存储字长 发布:2025-05-15 21:54:09 浏览:514
用什么写c语言 发布:2025-05-15 21:35:56 浏览:418
linux读取u盘 发布:2025-05-15 21:32:13 浏览:508
c语言dos 发布:2025-05-15 21:18:17 浏览:664
sci编译英文 发布:2025-05-15 21:16:57 浏览:383
大猫如何设置密码 发布:2025-05-15 21:15:32 浏览:765
什么叫苹果版的和安卓版的手机 发布:2025-05-15 21:05:18 浏览:254
编程找点 发布:2025-05-15 20:43:10 浏览:588