2020-01-27 20:30:21 +08:00
<!DOCTYPE html>
< html lang = "zh-CN" class = "loading" >
< head >
2020-02-06 14:52:17 +08:00
<!-- hexo - inject:begin --> <!-- hexo - inject:end --> < meta charset = "UTF-8" / >
2020-01-27 20:30:21 +08:00
< meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" / >
< meta name = "viewport" content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" >
2020-02-14 14:43:05 +08:00
< title > ANU COMP2310(2019) Assignment 1 - Blog< / title >
2020-01-27 20:30:21 +08:00
< meta name = "apple-mobile-web-app-capable" content = "yes" / >
< meta name = "apple-mobile-web-app-status-bar-style" content = "black-translucent" >
< meta name = "google" content = "notranslate" / >
< meta name = "keywords" content = "Developer, Python, C++, JavaScript, Java," >
< meta name = "description" content = "DavidZ's Blog ,
2020-02-22 14:53:35 +08:00
原创发表于 DavidZ Blog, 遵循 CC 4.0 BY-NC-SA 版权协议,转载请附上原文出处链接及本声明。
2020-01-27 20:30:21 +08:00
敬告
2020-02-22 15:03:09 +08:00
本博客仅供参考,请不要抄袭。
2020-01-27 20:30:21 +08:00
2020-02-13 20:39:56 +08:00
¶前言
2020-02-22 14:53:35 +08:00
这是 ANU COMP231,">
2020-01-27 20:30:21 +08:00
< meta name = "author" content = "DavidZ" >
< link rel = "alternative" href = "atom.xml" title = "Blog" type = "application/atom+xml" >
< link rel = "icon" href = "/img/favicon.png" >
< link href = "https://fonts.loli.net/css?family=Roboto+Mono|Rubik&display=swap" rel = "stylesheet" >
< link rel = "stylesheet" href = "//at.alicdn.com/t/font_1429596_nzgqgvnmkjb.css" >
< link rel = "stylesheet" href = "//cdn.bootcss.com/animate.css/3.7.2/animate.min.css" >
2020-02-13 21:45:16 +08:00
< link rel = "stylesheet" href = "//cdn.bootcss.com/social-share.js/1.0.16/css/share.min.css" >
2020-01-27 20:30:21 +08:00
< link rel = "stylesheet" href = "//cdn.bootcss.com/codemirror/5.48.4/codemirror.min.css" >
< link rel = "stylesheet" href = "//cdn.bootcss.com/codemirror/5.48.4/theme/dracula.css" >
< link rel = "stylesheet" href = "/css/obsidian.css" >
< link rel = "stylesheet" href = "/css/ball-atom.min.css" >
2020-02-06 14:52:17 +08:00
< meta name = "generator" content = "Hexo 4.2.0" > <!-- hexo - inject:begin --> <!-- hexo - inject:end --> < / head >
2020-01-27 20:30:21 +08:00
< body class = "loading" >
2020-02-06 14:52:17 +08:00
<!-- hexo - inject:begin --> <!-- hexo - inject:end --> < div class = "loader" >
2020-01-27 20:30:21 +08:00
< div class = "la-ball-atom la-2x" >
< div > < / div >
< div > < / div >
< div > < / div >
< div > < / div >
< / div >
< / div >
< span id = "config-title" style = "display:none" > Blog< / span >
< div id = "loader" > < / div >
< div id = "single" >
< div class = "scrollbar gradient-bg-rev" > < / div >
< div id = "top" style = "display: block;" >
< div class = "bar" style = "width: 0;" > < / div >
< div class = "navigation animated fadeIn fast delay-1s" >
< img id = "home-icon" class = "icon-home" src = "/img/favicon.png" alt = "" data-url = "https://blog.davidz.cn" >
< div id = "play-icon" title = "Play/Pause" class = "iconfont icon-play" > < / div >
2020-02-14 14:43:05 +08:00
< h3 class = "subtitle" > ANU COMP2310(2019) Assignment 1< / h3 >
2020-01-27 20:30:21 +08:00
< div class = "social" >
<!-- <div class="like - icon"> -->
<!-- <a href="javascript:;" class="likeThis active"><span class="icon - like"></span><span class="count">76</span></a> -->
<!-- </div> -->
< div >
< div class = "share" >
< a href = "javascript:;" class = "iconfont icon-share1" > < / a >
< div class = "share-component-cc" data-disabled = "facebook,douban,linkedin,diandian,tencent,google" > < / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< div class = "section" >
< div class = article-header-wrapper >
< div class = "article-header" >
< div class = "article-cover animated fadeIn" style = "
animation-delay: 600ms;
animation-duration: 1.2s;
background-image:
radial-gradient(ellipse closest-side, rgba(0, 0, 0, 0.65), #100e17),
2020-09-07 21:52:27 +08:00
url(https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/截图-1599486510.png) ">
2020-01-27 20:30:21 +08:00
< / div >
< div class = "else" >
< p class = "animated fadeInDown" >
< a href = "/categories/Study" > < b > 「
< / b > STUDY< b > 」< / b > < / a >
一月 11, 2020
< / p >
2020-02-14 14:43:05 +08:00
< h3 class = "post-title animated fadeInDown" > < a href = "/anu-comp2310-assignment1/" title = "ANU COMP2310(2019) Assignment 1" class = "" > ANU COMP2310(2019) Assignment 1< / a >
2020-01-27 20:30:21 +08:00
< / h3 >
< p class = "post-count animated fadeInDown" >
< span >
< b class = "iconfont icon-text2" > < / b > < i > 文章字数< / i >
2020-09-07 21:52:27 +08:00
18k
2020-01-27 20:30:21 +08:00
< / span >
< span >
< b class = "iconfont icon-timer__s" > < / b > < i > 阅读约需< / i >
16 mins.
< / span >
< span id = "busuanzi_container_page_pv" >
< b class = "iconfont icon-read" > < / b > < i > 阅读次数< / i >
< span id = "busuanzi_value_page_pv" > 0< / span >
< / span >
< / p >
2020-02-01 21:30:36 +08:00
< ul class = "animated fadeInDown post-tags-list" itemprop = "keywords" > < li class = "animated fadeInDown post-tags-list-item" > < a class = "animated fadeInDown post-tags-list-link" href = "/tags/ANU/" rel = "tag" > ANU< / a > < / li > < li class = "animated fadeInDown post-tags-list-item" > < a class = "animated fadeInDown post-tags-list-link" href = "/tags/Ada/" rel = "tag" > Ada< / a > < / li > < / ul >
2020-01-27 20:30:21 +08:00
< / div >
< / div >
< / div >
< div class = "screen-gradient-after" >
< div class = "screen-gradient-content" >
< div class = "screen-gradient-content-inside" >
< div class = "bold-underline-links screen-gradient-sponsor" >
< p >
< span class = "animated fadeIn delay-1s" > < / span >
< / p >
< / div >
< / div >
< / div >
< / div >
< div class = "article" >
< div class = 'main' >
< div class = "content markdown animated fadeIn" >
< blockquote >
2020-02-22 14:53:35 +08:00
< p > 原创发表于 < a href = "https://blog.davidz.cn" > DavidZ Blog< / a > ,遵循 < a href = "https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode" target = "_blank" rel = "noopener" > CC 4.0 BY-NC-SA< / a > 版权协议,转载请附上原文出处链接及本声明。< / p >
< / blockquote >
< blockquote >
2020-01-27 20:30:21 +08:00
< p > < strong > 敬告< / strong > < / p >
2020-02-22 15:03:09 +08:00
< div style = "color: red" > 本博客仅供参考,请不要抄袭。< / div >
2020-01-27 20:30:21 +08:00
< / blockquote >
2020-02-13 20:39:56 +08:00
< h2 id = "前言" > < a class = "header-anchor" href = "#前言" > ¶< / a > 前言< / h2 >
2020-01-27 20:30:21 +08:00
< p > 这是 ANU < a href = "http://courses.cecs.anu.edu.au/courses/COMP2310/" target = "_blank" rel = "noopener" > COMP2310< / a > 的第一次大作业,历时一个月左右,也是这个学期我写的最认真的一次作业,所以在博客搭建伊始,我先把这个记录下来。< / p >
< h2 id = "问题" > < a class = "header-anchor" href = "#问题" > ¶< / a > 问题< / h2 >
2020-09-09 15:27:17 +08:00
< p > 根据< a href = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/asset/Assignment1.pdf" target = "_blank" rel = "noopener" > Assignment 1 PDF< / a > 中的描述,大概的意思就是在三维空间中有许多的< code > 车< / code > ,具有速度和加速度(都是三维向量),而且不管是否加速,都会消耗一定的能量,当然加速也会加快能量的消耗。然后就是有一个或多个< code > 能量球< / code > ,当然也是在运动中的,同样具有速度和加速度。当< code > 车< / code > 和< code > 能量球< / code > 靠近的时候,< code > 车< / code > 能够获取到< code > 能量球< / code > 的信息(加速度,速度,位置),并且加满能量,而当< code > 车< / code > 与< code > 车< / code > 靠近的时候,能够互相交换一次信息,这个信息的内容是自己定义的。< code > 车< / code > 在能量耗尽后就消失了,而我们需要做的就是在一定的时间内,保证尽可能多的< code > 车< / code > 存活。< / p >
2020-01-27 20:30:21 +08:00
< h2 id = "分析" > < a class = "header-anchor" href = "#分析" > ¶< / a > 分析< / h2 >
< p > 其实这个问题最关键的地方在于,没有一个中央的控制节点,也就是说对于每一个< code > 车< / code > 来说都是完全平等且独立的。所以我们需要他们能够尽可能的一直处在能够交流的状态,并且都能知道< code > 能量球< / code > 在哪里。< / p >
< blockquote >
< p > < strong > 注意< / strong > < br >
这个问题在没有中央控制时< strong > 不存在< / strong > 最优解,我们只能无线接近最优解。< br >
我采用的是< strong > 球形模型< / strong > ,这个模型参考于这次作业的 < a href = "https://cs.anu.edu.au/courses/comp2310/1-Labs-Assignments.html" target = "_blank" rel = "noopener" > Examples< / a > 。< br >
在和我的同学互相交流时,这个模型是最普遍的,解决方案是最多的,效果也是相对最好的。< / p >
< / blockquote >
2020-09-07 21:52:27 +08:00
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/3D%E7%90%83%E5%BD%A2%E6%A8%A1%E5%9E%8B-1599486499.png" alt = "3D球形模型" > < / p >
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/2D%E7%90%83%E5%BD%A2%E6%A8%A1%E5%9E%8B-1599486500.png" alt = "2D球形模型" > < / p >
2020-01-27 20:30:21 +08:00
< p > 球形模型设计的两大重点是:< / p >
< ol >
< li > 所有的< code > 车< / code > 都均匀平等地分布在球面上(球面是个相对概念,可以是球壳???)。< / li >
< li > 所有的< code > 车< / code > 都能随时交流,也就是说大家形成一个通讯网络。< / li >
< / ol >
< h2 id = "实现" > < a class = "header-anchor" href = "#实现" > ¶< / a > 实现< / h2 >
< blockquote >
< p > < strong > 注意< / strong > < br >
所有的 Ada 代码都是示意性的,有可能不能直接在项目中使用。< / p >
< / blockquote >
< h3 id = "Stage-A-B" > < a class = "header-anchor" href = "#Stage-A-B" > ¶< / a > Stage A& B< / h3 >
< p > 这个阶段中,能量球只有一个,我们让所有的< code > 车< / code > 都围绕这个能量球运动来实现一个基本的球形模型。< / p >
< h4 id = "基本程序结构( Basic-Program-Structure) " > < a class = "header-anchor" href = "#基本程序结构( Basic-Program-Structure) " > ¶< / a > 基本程序结构( Basic Program Structure) < / h4 >
< p > 程序基本的结构是一个死循环,每次循环分为 4 个步骤:< / p >
< ol >
< li > 判断< code > 能量球< / code > 信息< / li >
< li > 发送信息< / li >
< li > 接受信息< / li >
< li > 设置目的地和油门< / li >
< / ol >
< h4 id = "消息结构( Message-Structure) " > < a class = "header-anchor" href = "#消息结构( Message-Structure) " > ¶< / a > 消息结构( Message Structure) < / h4 >
< p > 最基础的消息需要包括:< / p >
< ol >
< li > < code > 能量球< / code > 的信息< / li >
< li > 获得< code > 能量球< / code > 信息的时间戳< / li >
< / ol >
< h4 id = "中央控制( Central-Control) " > < a class = "header-anchor" href = "#中央控制( Central-Control) " > ¶< / a > 中央控制( Central Control) < / h4 >
< p > 允许中央控制是 Stage 1 中的条件,我在作业中跳过了这一部分,因为< / p >
< ol >
< li > 在允许中央控制时,该问题存在最优解,该最优解应该是一个数学问题,对我来说难度过大。< / li >
< li > 后面的 Stage 2,3,4 均不允许中央控制。< / li >
< / ol >
< h4 id = "能量球位置估计( Energy-Globe-Position-Estimation) " > < a class = "header-anchor" href = "#能量球位置估计( Energy-Globe-Position-Estimation) " > ¶< / a > 能量球位置估计( Energy Globe Position Estimation) < / h4 >
2020-09-07 21:52:27 +08:00
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/%E8%83%BD%E9%87%8F%E7%90%83%E4%BD%8D%E7%BD%AE%E4%BC%B0%E8%AE%A1-1599486501.png" alt = "能量球位置估计" > < / p >
2020-01-27 20:30:21 +08:00
< p > 这个问题类似于一个追击问题(红球是一个匀速导弹,蓝球是拦截导弹),我们需要求的是预计追击时间$T_e$。< / p >
< p > < code > 能量球< / code > 到追击点$P_m$,两个坐标相同,所以,< / p >
< p > $$< br >
P_m=VeT_{total}+P_e< br >
$$< / p >
< p > 易得总时间,< / p >
< p > $$< br >
T_{total}=T_f-T_n+T_e< br >
$$< / p >
< p > 通过边相等得,< / p >
< p > $$< br >
P_e+(T_f-T_n+T_e)V_e=V_vT_e+\frac{1}{2}A_vT_e^2+P_v< br >
$$< / p >
< p > 即可解出$T_e$。< / p >
< blockquote >
< p > < strong > 注意< / strong > < br >
存在无法追击的情况,即($\Delta< 0$),因为我们这里是严格的计算,实际上整个追击过程只有 1-2 秒,并且在不断地更新< code > 能量球< / code > 的信息,所以预计的那一段时间$T_e$通常可以忽略不计。但是在可以计算时,能够提供更加准确的预计到达时间,从而让< code > 车< / code > 能够更加精准的决策何时去充电。< / p >
< / blockquote >
< h4 id = "充电决策( Charge-Determination) " > < a class = "header-anchor" href = "#充电决策( Charge-Determination) " > ¶< / a > 充电决策( Charge Determination) < / h4 >
< p > 当同时满足以下两个条件时:< / p >
< ol >
< li > < code > 车< / code > 知道< code > 能量球< / code > 的信息< / li >
< li > < code > 车< / code > 的预计剩余能量小于等于警戒能量< / li >
< / ol >
< p > 预计剩余能量:< / p >
< pre > < code class = "language-ada" > Left_Charge := Current_Charge - Current_Discharge_Per_Sec * Estimated_Time;
< / code > < / pre >
< h4 id = "半径决策( Radius-Determination) " > < a class = "header-anchor" href = "#半径决策( Radius-Determination) " > ¶< / a > 半径决策( Radius Determination) < / h4 >
2020-09-07 21:52:27 +08:00
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/%E5%8D%8A%E5%BE%84%E5%86%B3%E7%AD%96-1599486502.png" alt = "半径决策" > < / p >
2020-01-27 20:30:21 +08:00
< p > 半径向量:< / p >
< pre > < code class = "language-ada" > Radius_Vector := Radius_Distance * Norm (Position - Vehicle_Message.EG.Position);
< / code > < / pre >
< p > < code > 车< / code > 的位置:< / p >
< pre > < code class = "language-ada" > Destination := Vehicle_Message.EG.Position + Radius_Vector;
< / code > < / pre >
< p > 其中有些变量的值或初始值是由经验确定的< / p >
< ol >
< li > < code > Radius_Distance< / code > 的值是< code > 0.3< / code > ,是因为多次实验发现在 64 个, 128 个, 256 个< code > 车< / code > 的情况下< code > 0.3< / code > 表现均衡。< / li >
< li > < code > Destination< / code > 的初始值是< code > (0, 0, 0)< / code > ,这样能够避免一开始时< code > 车< / code > 四散,导致失去联系,不能构成球形。< / li >
< / ol >
< h4 id = "使用当前能量优化半径( Radius-Optimization-With-Current-Charge) " > < a class = "header-anchor" href = "#使用当前能量优化半径( Radius-Optimization-With-Current-Charge) " > ¶< / a > 使用当前能量优化半径( Radius Optimization With Current Charge) < / h4 >
2020-09-07 21:52:27 +08:00
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/%E4%BD%BF%E7%94%A8%E5%BD%93%E5%89%8D%E8%83%BD%E9%87%8F%E4%BC%98%E5%8C%96%E5%8D%8A%E5%BE%84-1599486502.png" alt = "使用当前能量优化半径" > < / p >
2020-01-27 20:30:21 +08:00
< pre > < code class = "language-ada" > Radius_Vector = (0.75 + 0.25 * Current_Charge) * Radius_Vector;
< / code > < / pre >
< p > < code > 0.75< / code > 和< code > 0.25< / code > 都是人为确定的,没什么依据😄。< / p >
< h4 id = "一个解决碰撞的机制( A-Solution-To-Collision) " > < a class = "header-anchor" href = "#一个解决碰撞的机制( A-Solution-To-Collision) " > ¶< / a > 一个解决碰撞的机制( A Solution To Collision) < / h4 >
< blockquote >
< p > < strong > 注意< / strong > < br >
这个机制未经过控制变量实验验证,只是理论上分析得到的。< / p >
< / blockquote >
2020-09-07 21:52:27 +08:00
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/%E4%B8%80%E4%B8%AA%E8%A7%A3%E5%86%B3%E7%A2%B0%E6%92%9E%E7%9A%84%E6%9C%BA%E5%88%B6-1599486503.png" alt = "一个解决碰撞的机制" > < / p >
2020-01-27 20:30:21 +08:00
< p > 因为< code > 车< / code > 和< code > 车< / code > 离的足够近时会发生碰撞,表现为大家都减速不动。所以当一个< code > 车< / code > 从外层到< code > 能量球< / code > 去加油时,周围的< code > 车< / code > 减速会一定程度的减少碰撞的发生。< / p >
< p > 实现时,需要在消息结构中添加< code > Vehicle_Charge< / code > 来判断谁的能量更低。< / p >
< h3 id = "Stage-C" > < a class = "header-anchor" href = "#Stage-C" > ¶< / a > Stage C< / h3 >
< p > 这个阶段中,能量球有两个或更多。我们遇到的新问题有:< / p >
< ol >
< li > 如何决策去围绕哪一个< code > 能量球< / code > 运动< / li >
< li > 如何自适应球形模型大小的变化< / li >
< / ol >
< h4 id = "多个能量球决策( Multiple-Energy-Globes-Decision) " > < a class = "header-anchor" href = "#多个能量球决策( Multiple-Energy-Globes-Decision) " > ¶< / a > 多个< code > 能量球< / code > 决策( Multiple Energy Globes Decision) < / h4 >
< p > 当有多个< code > 能量球< / code > 时(< code > 能量球< / code > 还有可能凭空消失),每个< code > 车< / code > 都要独立的选择其中一个作为他所在球形模型的球心,而且这个过程时动态的。< / p >
< p > 我们分两种情况去讨论这个问题:< / p >
< h5 id = "1-车发现了两个以上能量球" > < a class = "header-anchor" href = "#1-车发现了两个以上能量球" > ¶< / a > 1. < code > 车< / code > 发现了两个以上< code > 能量球< / code > < / h5 >
< p > 这种情况比较简单,我们只需要从中选择最近的哪一个即可。距离公式如下:< / p >
< pre > < code class = "language-ada" > distance := EG.Position + (Clock - EG_Find_Time) * EG.Velocity - Vehicle_Position
< / code > < / pre >
< h5 id = "2-车从别的车获得的信息中有新的能量球" > < a class = "header-anchor" href = "#2-车从别的车获得的信息中有新的能量球" > ¶< / a > 2. < code > 车< / code > 从别的< code > 车< / code > 获得的信息中有新的< code > 能量球< / code > < / h5 >
< p > 这种情况实际上是非常复杂的,因为存在一种情况:两个< code > 车< / code > 说的时同一个< code > 能量球< / code > ,但是不是同时发现的,很难判断是否是同一个< code > 能量球< / code > 。< / p >
< p > 我们可以使用时间戳来判断获得更新的< code > 能量球< / code > 。但是这个更新不能以时间戳作为唯一判据,因为存在一种情况,< code > 车A< / code > 知道一个旧的< code > 能量球< / code > ,但是发现的时间已经过去很久了,< code > 车B< / code > 发现一个新的< code > 能量球< / code > ,从远处靠近< code > 车A< / code > ,时,两车交换信息,该如何选择呢?< / p >
< p > 所以,我又加入了一个失效时间,来解决上述问题。< / p >
< pre > < code class = "language-ada" > Clock - Vehicle_Message.EG_Update_Time > Vehicle_Message_Expire_Time
< / code > < / pre >
< p > 当上述条件为真时,< code > 车< / code > 才会选择更新的信息。< / p >
< h4 id = "使用旋转优化( Optimization-With-Rotation) " > < a class = "header-anchor" href = "#使用旋转优化( Optimization-With-Rotation) " > ¶< / a > 使用旋转优化( Optimization With Rotation) < / h4 >
2020-09-07 21:52:27 +08:00
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/%E6%97%8B%E8%BD%AC%E5%8D%8A%E5%BE%84-1599486504.png" alt = "旋转半径" > < / p >
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/%E6%97%8B%E8%BD%AC%E8%BD%B4-1599486505.png" alt = "旋转轴" > < / p >
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/2D%E6%97%8B%E8%BD%AC%E5%8D%8A%E5%BE%84-1599486506.png" alt = "2D旋转半径" > < / p >
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/3D%E6%97%8B%E8%BD%AC-1599486507.png" alt = "3D旋转" > < / p >
2020-01-27 20:30:21 +08:00
< p > 相对于静态的在球面等待,动态的在球面旋转在实验中取得了更稳定的表现。< / p >
< blockquote >
< p > < strong > 注意< / strong > < br >
这个优化措施可能无效,我的同学们对这个优化反应褒贬不一,但是我觉得确实让这个模型更好看啦😄< / p >
< / blockquote >
< p > 旋转半径向量与旋转轴垂直:< / p >
< p > $$< br >
X_rX_a+Y_rY_a+Z_rZ_a=0< br >
$$< / p >
< p > 易得无数个解,但是为了尽量让两个< code > 车< / code > 不会面对面相撞(随机赋值的话),这里手动赋值$X_a$和$Y_a$为$1$,求得唯一解。< / p >
< h4 id = "自动半径适应( Automatic-Radius-Adaptation) " > < a class = "header-anchor" href = "#自动半径适应( Automatic-Radius-Adaptation) " > ¶< / a > 自动半径适应( Automatic Radius Adaptation) < / h4 >
2020-09-07 21:52:27 +08:00
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/%E9%80%9A%E8%AE%AF%E7%8E%AF-1599486507.png" alt = "通讯环" > < / p >
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/%E9%80%9A%E8%AE%AF%E7%8E%AF%E5%86%85-1599486508.png" alt = "通讯环内" > < / p >
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/%E9%80%9A%E8%AE%AF%E7%8E%AF%E5%A4%96-1599486509.png" alt = "通讯环外" > < / p >
2020-01-27 20:30:21 +08:00
< p > 我们在 Stage A& B 中的半径是手动设置的,但是在 Stage C 中,每个球星模型的< code > 车< / code > 的数量是动态的,如果半径不跟随数量变化,那么就有可能丢失通讯。< / p >
< p > 在理想的球星模型中,我们可以发现一个通讯环,在通讯环中的所有< code > 车< / code > 都是互联的,并且中心的< code > 能量球< / code > 很难突破这层环。在< code > 车< / code > 进出通讯环时,我们可以通过当时的位置,动态修正半径大小。< / p >
< p > 我们分三种情况讨论该模型:< / p >
< ol >
< li > 半径过大,此时会有更多的< code > 车< / code > 进到通讯环以内,从而使得半径变小。< / li >
< li > 半径国小,此时会有更多的< code > 车< / code > 进到通讯环以外,从而使得半径变大。< / li >
< li > 半径正好,进到通讯环以内的< code > 车< / code > 和进到通讯环以外的< code > 车< / code > 大致是相同的,所以半径会稳定在某一个数值。< / li >
< / ol >
< p > 在自动修正半径时,我们需要一个学习率参数< code > Track_Correction_Rate< / code > ,来确保不会因为充能量的不确定性而使得半径不稳定。< / p >
< p > 要实现该模型,我们还需要存在一个弹出通讯环的效果,即< code > 车< / code > 在< code > 能量球< / code > 加完能量后,弹出到通讯环外。实现如下,< / p >
< pre > < code class = "language-ada" > Actual_Radius_Vector := 1.5 * Rotated_Radius_Vector;
< / code > < / pre >
< h3 id = "Stage-D" > < a class = "header-anchor" href = "#Stage-D" > ¶< / a > Stage D< / h3 >
< p > 最后一个阶段,要求< code > 车< / code > 之间随机协商出一定数量的< code > 车< / code > 存活,剩下的自主“死亡“,比如一开始是 64 个,最终要求剩下 42 个。< / p >
< p > 这个问题最简单的解决方案是直接从 1 开始分配编号,按照编号顺序“死亡”就好啦,但是我觉得这个方案无法体现< code > 随机< / code > 。< / p >
< p > 通过分析,这个类似于现在大火的< code > 区块链< / code > 中最重要的一个问题,即分布式节点如何达成共识,解决方案也是一样的:共识算法。< / p >
< p > 推荐观看< a href = "https://www.bilibili.com/video/av78588312?from=search&seid=1453987515383608625" target = "_blank" rel = "noopener" > 李永乐老师:拜占庭将军问题是什么?区块链如何防范恶意节点?< / a > < / p >
< h4 id = "共识算法-Consensus-Algorithm" > < a class = "header-anchor" href = "#共识算法-Consensus-Algorithm" > ¶< / a > 共识算法(Consensus Algorithm)< sup class = "footnote-ref" > < a href = "#fn1" id = "fnref1" > [1]< / a > < / sup > < / h4 >
< p > 在这里我们仅利用共识算法的思想(不解决恶意节点问题),利用时间戳达成共识。< / p >
< p > 在< code > 车< / code > 与< code > 车< / code > 的通讯过程中,我们约定以下原则:< / p >
< ol >
< li > 在消息中添加三个字段:< code > Vehicle_No< / code > 数组,< code > Target_No_of_Elements< / code > 数组长度和< code > Vehicle_List_Update_Time< / code > 上一次更新时间。< / li >
< li > 所有的< code > 车< / code > 一直都能接受和发送信息。< / li >
< li > 在最开始,所有的< code > 车< / code > 都把自己的编号放到数组的第一个位置。< / li >
< li > 如果< code > 车< / code > 接收到的信息与自身存储的信息不同(数组长度不同,或者上一次更新时间不同),那么按照下面的规则确定保留哪个< br >
保留数组更长的那个< br >
选择上一次更新时间更早的那个< / li >
< li > 检查自己的编号是否在< code > Vehicle_No< / code > 数组中,若不在并且仍有空间,那么就把自己的编号加进去。< / li >
< li > 在上一次更新时间又< code > Confirm_Time_Interval< / code > 秒后,如果数组已满并且自己的编号不在里面,那么该< code > 车< / code > 就不能再去加能量了。< / li >
< / ol >
< p > 经过实验,在 64 个< code > 车< / code > ,缩减到 42 个的情况下,< code > Confirm_Time_Interval< / code > 设置为 1 秒就可以满足要求。< / p >
< h2 id = "结果" > < a class = "header-anchor" href = "#结果" > ¶< / a > 结果< sup class = "footnote-ref" > < a href = "#fn2" id = "fnref2" > [2]< / a > < / sup > < / h2 >
< h3 id = "截图" > < a class = "header-anchor" href = "#截图" > ¶< / a > 截图< / h3 >
2020-09-07 21:52:27 +08:00
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/%E6%88%AA%E5%9B%BE-1599486510.png" alt = "截图" > < / p >
2020-01-27 20:30:21 +08:00
< h3 id = "Stage-A-B-Single-Globe-In-Orbit" > < a class = "header-anchor" href = "#Stage-A-B-Single-Globe-In-Orbit" > ¶< / a > Stage A& B(< code > Single_Globe_In_Orbit< / code > )< / h3 >
< table >
< thead >
< tr >
< th style = "text-align:center" > Initial Number< / th >
< th style = "text-align:center" > Target Number< / th >
< th style = "text-align:center" > Duration< / th >
< th style = "text-align:center" > Test times< / th >
< th style = "text-align:center" > Average Result< / th >
< th style = "text-align:center" > Survival Rate< / th >
< th style = "text-align:center" > Average Frame Rate< / th >
< / tr >
< / thead >
< tbody >
< tr >
< td style = "text-align:center" > 32< / td >
< td style = "text-align:center" > 32< / td >
< td style = "text-align:center" > 5 min< / td >
< td style = "text-align:center" > 5< / td >
< td style = "text-align:center" > 31.8< / td >
< td style = "text-align:center" > 0.99375< / td >
< td style = "text-align:center" > 30 Hz< / td >
< / tr >
< tr >
< td style = "text-align:center" > 64< / td >
< td style = "text-align:center" > 64< / td >
< td style = "text-align:center" > 5 min< / td >
< td style = "text-align:center" > 5< / td >
< td style = "text-align:center" > 63.4< / td >
< td style = "text-align:center" > 0.990625< / td >
< td style = "text-align:center" > 28 Hz< / td >
< / tr >
< tr >
< td style = "text-align:center" > 128< / td >
< td style = "text-align:center" > 128< / td >
< td style = "text-align:center" > 5 min< / td >
< td style = "text-align:center" > 5< / td >
< td style = "text-align:center" > 126.8< / td >
< td style = "text-align:center" > 0.990625< / td >
< td style = "text-align:center" > 20 Hz< / td >
< / tr >
< tr >
< td style = "text-align:center" > 256< / td >
< td style = "text-align:center" > 256< / td >
< td style = "text-align:center" > 5 min< / td >
< td style = "text-align:center" > 5< / td >
< td style = "text-align:center" > 233< / td >
< td style = "text-align:center" > 0.910156< / td >
< td style = "text-align:center" > 9 Hz< / td >
< / tr >
< / tbody >
< / table >
2020-09-07 21:52:27 +08:00
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/stageAB-1599486511.png" alt = "Stage A&B" > < / p >
2020-01-27 20:30:21 +08:00
< h3 id = "Stage-C-Random-Globes-In-Orbits" > < a class = "header-anchor" href = "#Stage-C-Random-Globes-In-Orbits" > ¶< / a > Stage C(< code > Random_Globes_In_Orbits< / code > )< / h3 >
< table >
< thead >
< tr >
< th style = "text-align:center" > Initial Number< / th >
< th style = "text-align:center" > Target Number< / th >
< th style = "text-align:center" > Duration< / th >
< th style = "text-align:center" > Test times< / th >
< th style = "text-align:center" > Average Result< / th >
< th style = "text-align:center" > Survival Rate< / th >
< th style = "text-align:center" > Average Frame Rate< / th >
< / tr >
< / thead >
< tbody >
< tr >
< td style = "text-align:center" > 32< / td >
< td style = "text-align:center" > 32< / td >
< td style = "text-align:center" > 5 min< / td >
< td style = "text-align:center" > 5< / td >
< td style = "text-align:center" > 26.8< / td >
< td style = "text-align:center" > 0.8375< / td >
< td style = "text-align:center" > 30 Hz< / td >
< / tr >
< tr >
< td style = "text-align:center" > 64< / td >
< td style = "text-align:center" > 64< / td >
< td style = "text-align:center" > 5 min< / td >
< td style = "text-align:center" > 5< / td >
< td style = "text-align:center" > 60.2< / td >
< td style = "text-align:center" > 0.940625< / td >
< td style = "text-align:center" > 28 Hz< / td >
< / tr >
< tr >
< td style = "text-align:center" > 128< / td >
< td style = "text-align:center" > 128< / td >
< td style = "text-align:center" > 5 min< / td >
< td style = "text-align:center" > 5< / td >
< td style = "text-align:center" > 109.2< / td >
< td style = "text-align:center" > 0.853125< / td >
< td style = "text-align:center" > 20 Hz< / td >
< / tr >
< tr >
< td style = "text-align:center" > 256< / td >
< td style = "text-align:center" > 256< / td >
< td style = "text-align:center" > 5 min< / td >
< td style = "text-align:center" > 5< / td >
< td style = "text-align:center" > 208.2< / td >
< td style = "text-align:center" > 0.813281< / td >
< td style = "text-align:center" > 9 Hz< / td >
< / tr >
< / tbody >
< / table >
2020-09-07 21:52:27 +08:00
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/stageC-1599486512.png" alt = "Stage C" > < / p >
2020-01-27 20:30:21 +08:00
< h3 id = "Stage-D-Random-Globes-In-Orbits" > < a class = "header-anchor" href = "#Stage-D-Random-Globes-In-Orbits" > ¶< / a > Stage D(< code > Random_Globes_In_Orbits< / code > )< / h3 >
< table >
< thead >
< tr >
< th style = "text-align:center" > Initial Number< / th >
< th style = "text-align:center" > Target Number< / th >
< th style = "text-align:center" > Duration< / th >
< th style = "text-align:center" > Test times< / th >
< th style = "text-align:center" > Average Result< / th >
< th style = "text-align:center" > Survival Rate< / th >
< th style = "text-align:center" > Average Frame Rate< / th >
< / tr >
< / thead >
< tbody >
< tr >
< td style = "text-align:center" > 32< / td >
< td style = "text-align:center" > 42< / td >
< td style = "text-align:center" > 5 min< / td >
< td style = "text-align:center" > 5< / td >
< td style = "text-align:center" > 24< / td >
< td style = "text-align:center" > 0.571429< / td >
< td style = "text-align:center" > 30 Hz< / td >
< / tr >
< tr >
< td style = "text-align:center" > 64< / td >
< td style = "text-align:center" > 42< / td >
< td style = "text-align:center" > 5 min< / td >
< td style = "text-align:center" > 5< / td >
< td style = "text-align:center" > 37.4< / td >
< td style = "text-align:center" > 0.890476< / td >
< td style = "text-align:center" > 28 Hz< / td >
< / tr >
< tr >
< td style = "text-align:center" > 128< / td >
< td style = "text-align:center" > 100< / td >
< td style = "text-align:center" > 5 min< / td >
< td style = "text-align:center" > 5< / td >
< td style = "text-align:center" > 83.4< / td >
< td style = "text-align:center" > 0.834< / td >
< td style = "text-align:center" > 20 Hz< / td >
< / tr >
< tr >
< td style = "text-align:center" > 256< / td >
< td style = "text-align:center" > 150< / td >
< td style = "text-align:center" > 5 min< / td >
< td style = "text-align:center" > 5< / td >
< td style = "text-align:center" > 133< / td >
< td style = "text-align:center" > 0.886667< / td >
< td style = "text-align:center" > 9 Hz< / td >
< / tr >
< / tbody >
< / table >
2020-09-07 21:52:27 +08:00
< p > < img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/stageD-1599486513.png" alt = "Stage D" > < / p >
2020-01-27 20:30:21 +08:00
< h2 id = "感谢" > < a class = "header-anchor" href = "#感谢" > ¶< / a > 感谢< / h2 >
< p > 感谢所有在作业中帮助过我的同学,辅导员和老师❤️。< / p >
< hr class = "footnotes-sep" >
< section class = "footnotes" >
< ol class = "footnotes-list" >
< li id = "fn1" class = "footnote-item" > < p > 共识算法:< a href = "https://en.wikipedia.org/wiki/Consensus_decision-making" target = "_blank" rel = "noopener" > https://en.wikipedia.org/wiki/Consensus_decision-making< / a > < a href = "#fnref1" class = "footnote-backref" > ↩︎< / a > < / p >
< / li >
< li id = "fn2" class = "footnote-item" > < p > 测试平台: 笔记本 Intel I7 处理器 @ 3.43GHz, 16GB 内存。因为我是用 Python 编写测试脚本,通过识别当前程序线程数量来判断< code > 车< / code > 的数量的,所以测试结果可能不准确。 < a href = "#fnref2" class = "footnote-backref" > ↩︎< / a > < / p >
< / li >
< / ol >
< / section >
<!-- [if lt IE 9]><script>document.createElement('audio');</script><![endif] -->
< audio id = "audio" loop = "1" preload = "auto" controls = "controls"
data-autoplay="false">
2020-09-07 21:52:27 +08:00
< source type = "audio/mpeg" src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/music/光良 - 童话.mp3" >
2020-01-27 20:30:21 +08:00
< / audio >
< div id = 'gitalk-container' class = "comment link"
data-ae='true'
data-ci='489076c5dd3f5ba13f67'
data-cs='d6e3b245787b0b74d0dbe2639ef87f452a401194'
data-r='blog.davidz.cn'
data-o='DavidZhang73'
data-a='DavidZhang73'
data-d=''
>留言< / div >
< / div >
< div class = "sidebar" >
< div class = "box animated fadeInRight" >
< div class = "subbox" >
2020-09-07 21:52:27 +08:00
< img src = "https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/2019-1599483796.jpg" height = 300 width = 300 > < / img >
2020-01-27 20:30:21 +08:00
< p > DavidZ< / p >
< span > 凡事都要留几分< / span >
< dl >
< dd > < a href = "https://github.com/DavidZhang73" target = "_blank" > < span
class=" iconfont icon-github">< / span > < / a > < / dd >
< dd > < a href = "https://twitter.com/david731998" target = "_blank" > < span
class=" iconfont icon-twitter">< / span > < / a > < / dd >
< dd > < a href = "https://stackoverflow.com/users/12693553/davidz" target = "_blank" > < span
class=" iconfont icon-stack-overflow">< / span > < / a > < / dd >
< / dl >
< / div >
< ul >
2020-10-09 14:46:16 +08:00
< li > < a href = "/" > 15 < p > 文章< / p > < / a > < / li >
2020-10-09 10:48:26 +08:00
< li > < a href = "/categories" > 8 < p > 分类< / p > < / a > < / li >
2020-10-09 14:46:16 +08:00
< li > < a href = "/tags" > 15 < p > 标签< / p > < / a > < / li >
2020-01-27 20:30:21 +08:00
< / ul >
< / div >
< div class = "box sticky animated fadeInRight faster" >
< div id = "toc" class = "subbox" >
< h4 > 目录< / h4 >
2020-02-14 14:54:30 +08:00
< ol class = "toc" > < li class = "toc-item toc-level-2" > < a class = "toc-link" href = "#前言" > < span class = "toc-number" > 1.< / span > < span class = "toc-text" > ¶前言< / span > < / a > < / li > < li class = "toc-item toc-level-2" > < a class = "toc-link" href = "#问题" > < span class = "toc-number" > 2.< / span > < span class = "toc-text" > ¶问题< / span > < / a > < / li > < li class = "toc-item toc-level-2" > < a class = "toc-link" href = "#分析" > < span class = "toc-number" > 3.< / span > < span class = "toc-text" > ¶分析< / span > < / a > < / li > < li class = "toc-item toc-level-2" > < a class = "toc-link" href = "#实现" > < span class = "toc-number" > 4.< / span > < span class = "toc-text" > ¶实现< / span > < / a > < ol class = "toc-child" > < li class = "toc-item toc-level-3" > < a class = "toc-link" href = "#Stage-A-B" > < span class = "toc-number" > 4.1.< / span > < span class = "toc-text" > ¶Stage A& B< / span > < / a > < ol class = "toc-child" > < li class = "toc-item toc-level-4" > < a class = "toc-link" href = "#基本程序结构( Basic-Program-Structure) " > < span class = "toc-number" > 4.1.1.< / span > < span class = "toc-text" > ¶基本程序结构( Basic Program Structure) < / span > < / a > < / li > < li class = "toc-item toc-level-4" > < a class = "toc-link" href = "#消息结构( Message-Structure) " > < span class = "toc-number" > 4.1.2.< / span > < span class = "toc-text" > ¶消息结构( Message Structure) < / span > < / a > < / li > < li class = "toc-item toc-level-4" > < a class = "toc-link" href = "#中央控制( Central-Control) " > < span class = "toc-number" > 4.1.3.< / span > < span class = "toc-text" > ¶中央控制( Central Control) < / span > < / a > < / li > < li class = "toc-item toc-level-4" > < a class = "toc-link" href = "#能量球位置估计( Energy-Globe-Position-Estimation) " > < span class = "toc-number" > 4.1.4.< / span > < span class = "toc-text" > ¶能量球位置估计( Energy Globe Position Estimation) < / span > < / a > < / li > < li class = "toc-item toc-level-4" > < a class = "toc-link" href = "#充电决策( Charge-Determination) " > < span class = "toc-number" > 4.1.5.< / span > < span class = "toc-text" > ¶充电决策( Charge Determination) < / span > < / a > < / li > < li class = "toc-item toc-level-4" > < a class = "toc-link" href = "#半径决策( Radius-Determination) " > < span class = "toc-number" > 4.1.6.< / span > < span class = "toc-text" > ¶半径决策( Radius Determination) < / span > < / a > < / li > < li class = "toc-item toc-level-4" > < a class = "toc-link" href = "#使用当前能量优化半径( Radius-Optimization-With-Current-Charge) " > < span class = "toc-number" > 4.1.7.< / span > < span class = "toc-text" > ¶使用当前能量优化半径( Radius Optimization With Current Charge) < / span > < / a > < / li > < li class = "toc-item toc-level-4" > < a class = "toc-link" href = "#一个解决碰撞的机制( A-Solution-To-Collision) " > < span class = "toc-number" > 4.1.8.< / span > < span class = "toc-text" > ¶一个解决碰撞的机制( A Solution To Collision) < / span > < / a > < / li > < / ol > < / li > < li class = "toc-item toc-level-3" > < a class = "toc-link" href = "#Stage-C" > < span class = "toc-number" > 4.2.< / span > < span class = "toc-text" > ¶Stage C< / span > < / a > < ol class = "toc-child" > < li class = "toc-item toc-level-4" > < a class = "toc-link" href = "#多个能量球决策( Multiple-Energy-Globes-Decision) " > < span class = "toc-number" > 4.2.1.< / span > < span class = "toc-text" > ¶多个能量球决策( Multiple Energy Globes Decision) < / span > < / a > < ol class = "toc-child" > < li class = "toc-item toc-level-5" > < a class = "toc-link" href = "#1-车发现了两个以上能量球" > < span class = "toc-number" > 4.2.1.1.< / span > < span class = "toc-text" > ¶1. 车发现了两个以上能量球< / span > < / a > < / li > < li class = "toc-item toc-level-5" > < a class = "toc-link" href = "#2-车从别的车获得的信息中有新的能量球" > < span class = "toc-number" > 4.2.1.2.< / span > < span class = "toc-text" > ¶2. 车从别的车获得的信息中有新的能量球< / span > < / a > < / li > < / ol > < / li > < li class = "toc-item toc-level-4" > < a class = "toc-link" href = "#使用旋转优化( Optimization-With-Rotation) " > < span class = "toc-number" > 4.2.2.< / span > < span class = "toc-text" > ¶使用旋转优化( Optimization With Rotation) < / span > < / a > < / li > < li class = "toc-item toc-level-4" > < a class = "toc-link" href = "#自动半径适应( Automatic-Radius-Adaptation) " > < span class = "toc-number" > 4.2.3.< / span > < span class = "toc-text" > ¶自动半径<EFBFBD> <EFBFBD>
2020-01-27 20:30:21 +08:00
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< div id = "back-to-top" class = "animated fadeIn faster" >
< div class = "flow" > < / div >
< span class = "percentage animated fadeIn faster" > 0%< / span >
< span class = "iconfont icon-top02 animated fadeIn faster" > < / span >
2020-02-06 14:52:17 +08:00
< / div > <!-- hexo - inject:begin --> <!-- hexo - inject:end -->
2020-01-27 20:30:21 +08:00
< / body >
< footer >
< p class = "copyright" id = "copyright" >
© 2020
< span class = "gradient-text" >
DavidZ
< / span > .
Powered by < a href = "http://hexo.io/" title = "Hexo" target = "_blank" rel = "noopener" > Hexo< / a >
Theme
< span class = "gradient-text" >
< a href = "https://github.com/TriDiamond/hexo-theme-obsidian" title = "Obsidian" target = "_blank" rel = "noopener" > Obsidian< / a >
< / span >
2020-07-17 11:27:08 +08:00
< small > < a href = "https://github.com/TriDiamond/hexo-theme-obsidian/blob/master/CHANGELOG.md" title = "v1.4.4" target = "_blank" rel = "noopener" > v1.4.4< / a > < / small >
2020-01-27 20:30:21 +08:00
< / p >
< / footer >
2020-06-05 12:12:10 +08:00
< script type = "text/javascript" src = "https://cdn.bootcss.com/mathjax/2.7.7/MathJax.js?config=TeX-AMS-MML_HTMLorMML" >
2020-01-27 20:30:21 +08:00
< / script >
< script >
MathJax.Hub.Config({
"HTML-CSS": {
preferredFont: "TeX",
availableFonts: ["STIX", "TeX"],
linebreaks: {
automatic: true
},
EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50)
},
tex2jax: {
inlineMath: [
["$", "$"],
["\\(", "\\)"]
],
processEscapes: true,
ignoreClass: "tex2jax_ignore|dno",
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
},
TeX: {
noUndefined: {
attributes: {
mathcolor: "red",
mathbackground: "#FFEEEE",
mathsize: "90%"
}
},
Macros: {
href: "{}"
}
},
messageStyle: "none"
});
< / script >
< script >
function initialMathJax() {
MathJax.Hub.Queue(function () {
var all = MathJax.Hub.getAllJax(),
i;
// console.log(all);
for (i = 0; i < all.length ; i + = 1 ) {
all[i].SourceElement().parentNode.className += ' has-jax';
}
});
}
function reprocessMathJax() {
if (typeof MathJax !== 'undefined') {
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
}
}
< / script >
2020-07-17 11:27:08 +08:00
2020-06-05 12:12:10 +08:00
< link rel = "stylesheet" href = "//cdn.bootcss.com/gitalk/1.6.2/gitalk.min.css" >
2020-07-17 11:27:08 +08:00
2020-06-05 12:12:10 +08:00
< script src = "//cdn.bootcss.com/gitalk/1.6.2/gitalk.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-02-13 21:45:16 +08:00
< script src = "//cdn.bootcss.com/jquery/3.4.1/jquery.min.js" > < / script >
2020-01-27 20:30:21 +08:00
< script src = "/js/plugin.js" > < / script >
< script src = "/js/obsidian.js" > < / script >
< script src = "/js/jquery.truncate.js" > < / script >
< script src = "/js/search.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-01-27 20:30:21 +08:00
< script src = "//cdn.bootcss.com/typed.js/2.0.10/typed.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-01-27 20:30:21 +08:00
< script src = "//cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-02-13 21:45:16 +08:00
< script src = "//cdn.bootcss.com/social-share.js/1.0.16/js/social-share.min.js" > < / script >
2020-01-27 20:30:21 +08:00
2020-06-05 12:12:10 +08:00
< script src = "https://cdn.bootcss.com/codemirror/5.54.0/codemirror.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-06-05 12:12:10 +08:00
< script src = "//cdn.bootcss.com/codemirror/5.54.0/mode/javascript/javascript.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-06-05 12:12:10 +08:00
< script src = "//cdn.bootcss.com/codemirror/5.54.0/mode/css/css.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-06-05 12:12:10 +08:00
< script src = "//cdn.bootcss.com/codemirror/5.54.0/mode/xml/xml.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-06-05 12:12:10 +08:00
< script src = "//cdn.bootcss.com/codemirror/5.54.0/mode/htmlmixed/htmlmixed.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-06-05 12:12:10 +08:00
< script src = "//cdn.bootcss.com/codemirror/5.54.0/mode/clike/clike.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-06-05 12:12:10 +08:00
< script src = "//cdn.bootcss.com/codemirror/5.54.0/mode/php/php.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-06-05 12:12:10 +08:00
< script src = "//cdn.bootcss.com/codemirror/5.54.0/mode/shell/shell.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-06-05 12:12:10 +08:00
< script src = "//cdn.bootcss.com/codemirror/5.54.0/mode/python/python.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-06-05 12:12:10 +08:00
< script src = "//cdn.bootcss.com/codemirror/5.54.0/mode/cmake/cmake.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-06-05 12:12:10 +08:00
< script src = "//cdn.bootcss.com/codemirror/5.54.0/mode/powershell/powershell.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-06-05 12:12:10 +08:00
< script src = "//cdn.bootcss.com/codemirror/5.54.0/mode/yaml/yaml.min.js" > < / script >
2020-07-17 11:27:08 +08:00
2020-01-27 20:30:21 +08:00
< script src = "/js/busuanzi.min.js" > < / script >
2020-07-17 11:27:08 +08:00
< script >
$(document).ready(function () {
if ($('span[id^="busuanzi_"]').length) {
initialBusuanzi();
}
});
< / script >
2020-01-27 20:30:21 +08:00
< link rel = "stylesheet" href = "//cdn.bootcss.com/photoswipe/4.1.3/photoswipe.min.css" >
< link rel = "stylesheet" href = "//cdn.bootcss.com/photoswipe/4.1.3/default-skin/default-skin.min.css" >
< script src = "//cdn.bootcss.com/photoswipe/4.1.3/photoswipe.min.js" > < / script >
< script src = "//cdn.bootcss.com/photoswipe/4.1.3/photoswipe-ui-default.min.js" > < / script >
<!-- Root element of PhotoSwipe. Must have class pswp. -->
< div class = "pswp" tabindex = "-1" role = "dialog" aria-hidden = "true" >
<!-- Background of PhotoSwipe.
It's a separate element as animating opacity is faster than rgba(). -->
< div class = "pswp__bg" > < / div >
<!-- Slides wrapper with overflow:hidden. -->
< div class = "pswp__scroll-wrap" >
<!-- Container that holds slides.
PhotoSwipe keeps only 3 of them in the DOM to save memory.
Don't modify these 3 pswp__item elements, data is added later on. -->
< div class = "pswp__container" >
< div class = "pswp__item" > < / div >
< div class = "pswp__item" > < / div >
< div class = "pswp__item" > < / div >
< / div >
<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
< div class = "pswp__ui pswp__ui--hidden" >
< div class = "pswp__top-bar" >
<!-- Controls are self - explanatory. Order can be changed. -->
< div class = "pswp__counter" > < / div >
< button class = "pswp__button pswp__button--close" title = "Close (Esc)" > < / button >
< button class = "pswp__button pswp__button--share" title = "Share" > < / button >
< button class = "pswp__button pswp__button--fs" title = "Toggle fullscreen" > < / button >
< button class = "pswp__button pswp__button--zoom" title = "Zoom in/out" > < / button >
<!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
<!-- element will get class pswp__preloader - - active when preloader is running -->
< div class = "pswp__preloader" >
< div class = "pswp__preloader__icn" >
< div class = "pswp__preloader__cut" >
< div class = "pswp__preloader__donut" > < / div >
< / div >
< / div >
< / div >
< / div >
< div class = "pswp__share-modal pswp__share-modal--hidden pswp__single-tap" >
< div class = "pswp__share-tooltip" > < / div >
< / div >
< button class = "pswp__button pswp__button--arrow--left" title = "Previous (arrow left)" >
< / button >
< button class = "pswp__button pswp__button--arrow--right" title = "Next (arrow right)" >
< / button >
< div class = "pswp__caption" >
< div class = "pswp__caption__center" > < / div >
< / div >
< / div >
< / div >
< / div >
2020-07-17 11:27:08 +08:00
<!-- Global site tag (gtag.js) - Google Analytics -->
< script async src = "//www.googletagmanager.com/gtag/js?id=UA-157733505-1" > < / script >
< script >
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
2020-01-27 20:30:21 +08:00
2020-07-17 11:27:08 +08:00
gtag('config', 'UA-157733505-1');
< / script >
2020-01-27 20:30:21 +08:00
< script >
2020-07-17 11:27:08 +08:00
function initialTyped() {
var typedTextEl = $('.typed-text');
if (typedTextEl & & typedTextEl.length > 0) {
var typed = new Typed('.typed-text', {
strings: ['凡事都要留几分', '颜值是第一生产力'],
typeSpeed: 90,
loop: true,
loopCount: Infinity,
backSpeed: 20,
});
2020-01-27 20:30:21 +08:00
}
2020-07-17 11:27:08 +08:00
}
2020-01-27 20:30:21 +08:00
2020-07-17 11:27:08 +08:00
if ($('.article-header') & & $('.article-header').length) {
$(document).ready(function () {
initialTyped();
});
}
2020-01-27 20:30:21 +08:00
< / script >
< / html >