1
0
DavidZhang73.github.io/anu-comp2310-assignment1/index.html

785 lines
45 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN" class="loading">
<head>
<!-- hexo-inject:begin --><!-- hexo-inject:end --><meta charset="UTF-8" />
<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">
<title>ANU COMP2310(2019) Assignment 1 - Blog</title>
<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&#39;s Blog,
原创发表于 DavidZ Blog遵循 CC 4.0 BY-NC-SA 版权协议,转载请附上原文出处链接及本声明。
敬告
本博客仅供参考,请不要抄袭。
¶前言
这是 ANU COMP231,">
<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">
<link rel="stylesheet" href="//cdn.bootcss.com/social-share.js/1.0.16/css/share.min.css">
<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">
<meta name="generator" content="Hexo 4.2.0"><!-- hexo-inject:begin --><!-- hexo-inject:end --></head>
<body class="loading">
<!-- hexo-inject:begin --><!-- hexo-inject:end --><div class="loader">
<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>
<h3 class="subtitle">ANU COMP2310(2019) Assignment 1</h3>
<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),
url(https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/截图-1599486510.png) ">
</div>
<div class="else">
<p class="animated fadeInDown">
<a href="/categories/Study"><b>
</b>STUDY<b></b></a>
一月 11, 2020
</p>
<h3 class="post-title animated fadeInDown"><a href="/anu-comp2310-assignment1/" title="ANU COMP2310(2019) Assignment 1" class="">ANU COMP2310(2019) Assignment 1</a>
</h3>
<p class="post-count animated fadeInDown">
<span>
<b class="iconfont icon-text2"></b> <i>文章字数</i>
18k
</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>
<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>
</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>
<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>
<p><strong>敬告</strong></p>
<div style="color: red">本博客仅供参考,请不要抄袭。</div>
</blockquote>
<h2 id="前言"><a class="header-anchor" href="#前言"></a>前言</h2>
<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>
<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>
<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>
<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>
<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&amp;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>
<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>
<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&lt;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>
<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>
<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>
<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>
<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>
<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>
<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 &gt; 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>
<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>
<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>
<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>
<p>我们在 Stage A&amp;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&amp;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>
<p><img src="https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/%E6%88%AA%E5%9B%BE-1599486510.png" alt="截图"></p>
<h3 id="Stage-A-B-Single-Globe-In-Orbit"><a class="header-anchor" href="#Stage-A-B-Single-Globe-In-Orbit"></a>Stage A&amp;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>
<p><img src="https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/stageAB-1599486511.png" alt="Stage A&amp;B"></p>
<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>
<p><img src="https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/stageC-1599486512.png" alt="Stage C"></p>
<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>
<p><img src="https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/stageD-1599486513.png" alt="Stage D"></p>
<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.43GHz16GB 内存。因为我是用 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">
<source type="audio/mpeg" src="https://davidz-blog.oss-cn-beijing.aliyuncs.com/music/光良 - 童话.mp3">
</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">
<img src="https://davidz-blog.oss-cn-beijing.aliyuncs.com/img/2019-1599483796.jpg" height=300 width=300></img>
<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>
<li><a href="/">15 <p>文章</p></a></li>
<li><a href="/categories">8 <p>分类</p></a></li>
<li><a href="/tags">15 <p>标签</p></a></li>
</ul>
</div>
<div class="box sticky animated fadeInRight faster">
<div id="toc" class="subbox">
<h4>目录</h4>
<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&amp;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">¶自动半径适应Automatic Radius Adaptation</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Stage-D"><span class="toc-number">4.3.</span> <span class="toc-text">¶Stage D</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#共识算法-Consensus-Algorithm"><span class="toc-number">4.3.1.</span> <span class="toc-text">¶共识算法(Consensus Algorithm)[1]</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#结果"><span class="toc-number">5.</span> <span class="toc-text">¶结果[2]</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#截图"><span class="toc-number">5.1.</span> <span class="toc-text">¶截图</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Stage-A-B-Single-Globe-In-Orbit"><span class="toc-number">5.2.</span> <span class="toc-text">¶Stage A&amp;B(Single_Globe_In_Orbit)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Stage-C-Random-Globes-In-Orbits"><span class="toc-number">5.3.</span> <span class="toc-text">¶Stage C(Random_Globes_In_Orbits)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Stage-D-Random-Globes-In-Orbits"><span class="toc-number">5.4.</span> <span class="toc-text">¶Stage D(Random_Globes_In_Orbits)</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#感谢"><span class="toc-number">6.</span> <span class="toc-text">¶感谢</span></a></li></ol>
</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>
</div><!-- hexo-inject:begin --><!-- hexo-inject:end -->
</body>
<footer>
<p class="copyright" id="copyright">
&copy; 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>
<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>
</p>
</footer>
<script type="text/javascript" src="https://cdn.bootcss.com/mathjax/2.7.7/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</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>
<link rel="stylesheet" href="//cdn.bootcss.com/gitalk/1.6.2/gitalk.min.css">
<script src="//cdn.bootcss.com/gitalk/1.6.2/gitalk.min.js"></script>
<script src="//cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<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>
<script src="//cdn.bootcss.com/typed.js/2.0.10/typed.min.js"></script>
<script src="//cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js"></script>
<script src="//cdn.bootcss.com/social-share.js/1.0.16/js/social-share.min.js"></script>
<script src="https://cdn.bootcss.com/codemirror/5.54.0/codemirror.min.js"></script>
<script src="//cdn.bootcss.com/codemirror/5.54.0/mode/javascript/javascript.min.js"></script>
<script src="//cdn.bootcss.com/codemirror/5.54.0/mode/css/css.min.js"></script>
<script src="//cdn.bootcss.com/codemirror/5.54.0/mode/xml/xml.min.js"></script>
<script src="//cdn.bootcss.com/codemirror/5.54.0/mode/htmlmixed/htmlmixed.min.js"></script>
<script src="//cdn.bootcss.com/codemirror/5.54.0/mode/clike/clike.min.js"></script>
<script src="//cdn.bootcss.com/codemirror/5.54.0/mode/php/php.min.js"></script>
<script src="//cdn.bootcss.com/codemirror/5.54.0/mode/shell/shell.min.js"></script>
<script src="//cdn.bootcss.com/codemirror/5.54.0/mode/python/python.min.js"></script>
<script src="//cdn.bootcss.com/codemirror/5.54.0/mode/cmake/cmake.min.js"></script>
<script src="//cdn.bootcss.com/codemirror/5.54.0/mode/powershell/powershell.min.js"></script>
<script src="//cdn.bootcss.com/codemirror/5.54.0/mode/yaml/yaml.min.js"></script>
<script src="/js/busuanzi.min.js"></script>
<script>
$(document).ready(function () {
if ($('span[id^="busuanzi_"]').length) {
initialBusuanzi();
}
});
</script>
<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>
<!-- 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());
gtag('config', 'UA-157733505-1');
</script>
<script>
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,
});
}
}
if ($('.article-header') && $('.article-header').length) {
$(document).ready(function () {
initialTyped();
});
}
</script>
</html>