85 lines
37 KiB
XML
85 lines
37 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<search>
|
||
|
||
|
||
|
||
<entry>
|
||
<title>浪潮实习</title>
|
||
<link href="/inspur-internship/"/>
|
||
<url>/inspur-internship/</url>
|
||
|
||
<content type="html"><![CDATA[<p>到了期末都说要找个实习的工作,“雷声大雨点小”,最后没几个真正去实习的😂。</p><p>我是主要是在<a href="https://www.shixiseng.com/" target="_blank" rel="noopener">实习僧</a>上找的(就当免费做个广告吧),我住在美丽的泉城济南,<s>这个地方好就好在</s>,咳咳咳,我大概填了填简历,可能是没啥亮点,投了三四家都不要我😢。</p><p>我分析原因大概有以下几条:</p><ol><li>我最喜欢最熟练的语言是 Python,但是现在国内的环境,Python 很少作为 Web 的后端,主要是用在机器学习(大数据分析,量化交易之类的)方面。济南大多数都是 Java 和 Cpp 岗。</li><li>我个人没有参加过 acm 之类的比赛,除了几个项目没法有效证明我的能力。</li><li>我这个寒假只能干 2 个月,<s>其实最终只干了一个半月</s>。</li><li>我是个大三的学生。可能培养了对于公司来说也没啥意义吧。</li></ol><p>最后还是十分感谢秦老师❤️,不但收了我到浪潮实习,还在实习过程中给了我很多帮助和指导。</p><p>下面列一列我学习了解的项目工具之类的。</p><h2 id="CppMicroServices"><a class="header-anchor" href="#CppMicroServices">¶</a><a href="https://github.com/CppMicroServices/CppMicroServices" target="_blank" rel="noopener">CppMicroServices</a></h2><p>我们主要做了一个插件管理器,是基于 CppMicroServices 的二次开发。这是一个 Cpp 的微服务框架,主要实现了 Bundle 的全生命周期管理,注册,启动,停止,状态管理等。</p><h2 id="CLion"><a class="header-anchor" href="#CLion">¶</a><a href="https://www.jetbrains.com/clion" target="_blank" rel="noopener">CLion</a></h2><p>大爱 Jetbrains 全家桶,我实习的第一件事大概就是给组里所有人安利了 CLion 吧。与宇宙第一 IDE Visual Studio 相比最突出的优点有</p><ol><li>精美的全功能编辑器。不是我吐槽,VS 的编辑器为了向下兼容现在甚至已经落后 VSCode 了,这还是曾经的宇宙第一 IDE 嘛。举一个简单的例子,连字功能连个开关都找不到,重启 VS 没成功,重启电脑就成功了?再加上没有拼写检查?没有自动注释补全?没有缺陷提示?你可能觉得没什么,但是这些都是 CLion 的自带功能啊。</li><li>丰富完善的插件生态。虽然感觉比不上 VSCode,但是相对于 VS,😄。</li><li>CMake 项目的原生支持。VS 虽然也有,但是感觉应该还处在开发状态。</li><li>SVN & Git 的原生支持。</li><li>远程开发功能。因为我们要求项目有跨平台能力,所以需要在多个平台切换。VS 虽然也有这个功能,但是也是感觉在开发状态,相比 CLion 少了很多配置的灵活性。</li><li>丰富的主题。VS 硬伤。</li></ol><p>综上所述,对于 Cpp 的 CMake 跨平台项目,还是推荐使用 CLion 作为 IDE。</p><p>我猜测 Visual Studio 是宇宙第一 IDE 应该说的是对于 C# 项目吧。</p><h2 id="CMake"><a class="header-anchor" href="#CMake">¶</a><a href="www.cmake.org">CMake</a></h2><p>以前的 C/Cpp 项目对我来说就是个谜,解决方案、项目傻傻分不清楚,Visual Studio 写单文件程序,解算法题还是很溜的,但是两个文件以上就很晕。</p><p>傻瓜式的配置的优点和确定都是非常显著的,好用是好用,用好是真的难。</p><p>CMake 作为这几年流行的跨平台构建工具,实现了配置式构建,终于让我理解了大学里 Linux 老师讲的程序编译链接都是些啥。</p><p>下面我简单写一写 CMake 的入门知识。</p><h3 id="常见编译器"><a class="header-anchor" href="#常见编译器">¶</a>常见编译器</h3><table><thead><tr><th style="text-align:center">Platform</th><th style="text-align:center">Windows</th><th style="text-align:center">Linux</th></tr></thead><tbody><tr><td style="text-align:center">GNU(open source)</td><td style="text-align:center">MinGW, MinGW-w64</td><td style="text-align:center">GCC(GNU Compiler Collection)</td></tr><tr><td style="text-align:center">Other</td><td style="text-align:center">Clang(Apple), MSVC(Microsoft), ICC(Intel) etc.</td><td style="text-align:center">Clang(Apple), ICC(Intel) etc.</td></tr></tbody></table><p>上面这些编译器都可以作为 CMake 的编译器。</p><p>这里主要还是推荐 GCC,毕竟老牌,经过这么多年的洗礼了。</p><p>其次的话推荐 CLang,这些年对于新特性,特别是 C++20,支持的不错。</p><p>再次就是如果真的需要 Windows 原生底层支持,那就只能使用 MSVC 啦。</p><h3 id="常见构建工具"><a class="header-anchor" href="#常见构建工具">¶</a>常见构建工具</h3><table><thead><tr><th style="text-align:center">Platform</th><th style="text-align:center">Windows</th><th style="text-align:center">Linux</th></tr></thead><tbody><tr><td style="text-align:center">GNU(open source)</td><td style="text-align:center">MinGW-make(Makefile)</td><td style="text-align:center">make(Makefile)</td></tr><tr><td style="text-align:center">Other</td><td style="text-align:center">nmake(Makefile), MSBuild(.vcxproj), ninja(.ninja), qmake etc.</td><td style="text-align:center">ninja(.ninja), qmake etc.</td></tr><tr><td style="text-align:center">Solution</td><td style="text-align:center">Visual Studio(.sln), QT(.project)</td><td style="text-align:center">XCode, QT(.project)</td></tr></tbody></table><p>以上所有都可以作为 CMake 的 Generator。</p><p>IDE 可以识别 CMake 根据 CMakeLists.txt 生成的 CMakeCache.txt,从中获得项目构成,编译连接选项等,从而替代解决方案。</p><p>我们在项目中使用的情况是,在 Linux 下使用 make,在 Windows 下使用 nmake。</p><h3 id="CMake-常用指令"><a class="header-anchor" href="#CMake-常用指令">¶</a>CMake 常用指令</h3><pre><code class="language-shell">Generate a Project Buildsystem cmake [<options>] <path-to-source> cmake [<options>] <path-to-existing-build> cmake [<options>] -S <path-to-source> -B <path-to-build>Build a Project cmake --build <dir> [<options>] [-- <build-tool-options>]Install a Project cmake --install <dir> [<options>]Open a Project cmake --open <dir>Run a Script cmake [{-D <var>=<value>}...] -P <cmake-script-file>Run a Command-Line Tool cmake -E <command> [<options>]Run the Find-Package Tool cmake --find-package [<options>]View Help cmake --help[-<topic>]</code></pre><p>这些其实用不太到,构建别人的项目只使用简单的<code>cmake ..</code>就好啦。</p><p>其他常用的 CLion 都有相应的图形化设置。</p><h3 id="Makefile"><a class="header-anchor" href="#Makefile">¶</a>Makefile</h3><pre><code class="language-makefile"><TargetName>: gcc <arg1> <arg2> ... <file> g++ <arg1> <arg2> ... <file> gcc <arg1> <arg2> ... <file></code></pre><p>这个是传统的 makefile,事实上,对于大型项目,已经很少有人这么写了,详细参考<a href="https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html" target="_blank" rel="noopener">Autotools</a>。</p><h3 id="CMakeLists-txt"><a class="header-anchor" href="#CMakeLists-txt">¶</a>CMakeLists.txt</h3><pre><code class="language-cmake">cmake_minimum_required(VERSION 3.16)project(Demo)set(CMAKE_CXX_STANDARD 14)find_package(Poco REQUIRED COMPONENTS Foundation)include_directories(include)add_executable(Demo src/main.cpp)set(BUILD_SHARED_LIBS true)add_library(Cal src/cal.cpp include/cal.h)message(STATUS ${Poco_LIBRARIES})target_link_libraries(Demo ${Poco_LIBRARIES} Cal)set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin/)set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib/)</code></pre><p>这个是一个简单的 Demo,链接外部的 Poco 库,还编译生成了一个动态库和一个可执行文件,然后指定了输出目录。</p><p>整体难度中等,主要原因是<a href="https://cmake.org/" target="_blank" rel="noopener">官网文档</a>有一点看不懂😢。</p><h2 id="Vcpkg"><a class="header-anchor" href="#Vcpkg">¶</a><a href="https://github.com/microsoft/vcpkg" target="_blank" rel="noopener">Vcpkg</a></h2><p>这个是微软开发的,类似于 Python 的 pip,Nodejs 的 npm,总而言之就是个依赖包管理器。主要适用于解决开发依赖问题。</p><p>比如安装一个 poco,原来你需要下载源码->编译源码->把文件放进项目->修改编译链接选项,然后才能用,现在你只需要</p><pre><code class="language-shell">vcpkg install poco</code></pre><p>然后在 CMakeLists.txt 里面添加</p><pre><code class="language-cmake">find_package(Poco REQUIRED COMPONENTS Foundation)</code></pre><p>然后再连接上 Target 就好啦。</p><p>Vcpkg 甚至还允许你使用</p><pre><code class="language-shell">vcpkg install poco:x64-windows</code></pre><p>直接安装 64 位的 Poco 库。</p><p>至于搜索和卸载都大同小异。</p><p><strong>但是</strong>,它有一个致命问题是,不支持版本管理,每个库都是由一个文件指定的,而不是像 pip,npm 之类的,有个在线仓库,所以,你 vcpkg 的版本直接决定了依赖的版本。</p><p>vcpkg 安装依赖都是下载后现编译安装的,不过这个应该是 C/Cpp 项目不可避免的,我也没找到 Windows 下更好的依赖包管理器。</p><h2 id="Poco"><a class="header-anchor" href="#Poco">¶</a><a href="https://github.com/pocoproject/poco" target="_blank" rel="noopener">Poco</a></h2><p>这个类似于野生 C++标准类库<a href="https://www.boost.org" target="_blank" rel="noopener">Boost</a>,但是官网说很轻量,使用感觉也确实是这样。但是用起来总感觉有一些问题,我也提了 issue,作者也没回我,可能太忙了吧。</p><p>基本上能够让 Cpp 在使用上达到 Java 的水平吧,但是肯定还是有一定的差距的,跟我熟悉的 Python 更是相差甚远,毕竟不是标准库,也情有可原吧。</p><p>用了一段时间之后,感觉这个库的实现还是很标准的,看了一些源代码,也很规范,以后再有 Cpp 的项目可以着重考虑一下了。</p><h2 id="Linux"><a class="header-anchor" href="#Linux">¶</a>Linux</h2><p>因为跨平台,在项目开发过程中大量使用了 Linux 上 shell,systemctl,docker 这些工具以及 CFEngine, Zabbix 这些运维的东西,感觉又喜欢上了 Linux 和命令行,熟悉了之后真是很方便。</p><p>同时因为是 C/Cpp 项目,我们编译了很多开源项目,算是终于知道了 Linux 根目录下面每个目录都是干啥的。</p><p>Linux 下的包管理器比如 apt,yum 用起来也很爽。所以我也看了看 Windows 下面的包管理器,发现了 Scoop 这个神器,我准备把它,终端和 WSL 放在一起再写一篇博客。</p><h2 id="MSYS2"><a class="header-anchor" href="#MSYS2">¶</a><a href="https://github.com/msys2/msys2" target="_blank" rel="noopener">MSYS2</a></h2><p>因为快离职的时候,新的需求要交叉编译 CFEngine(虽然到离职也没搞成功),但是让我发现了 MSYS2 这个交叉编译神器。</p><blockquote><p>MinGW 是在 Windows 平台的<a href="https://www.gnu.org/software/gcc" target="_blank" rel="noopener">GCC</a>,而 CygWin 和 MSYS2 均是在 MinGW 基础上的<a href="https://www.gnu.org/software/libc/manual/html_node/POSIX.html" target="_blank" rel="noopener">POSIX</a>子操作系统(概念类似于微软 WSL)。<br><a href="https://www.cnblogs.com/Netsharp/p/11073142.html" target="_blank" rel="noopener">CygWin、Msys、MinGW、Msys2 的区别与联系</a></p></blockquote><p>选择 MSYS2 而不是 MinGW 也不是 CygWin 的主要原因也是因为 MSYS2 的包管理器 pacman。</p><p>交叉编译也是个大坑,巨坑无比,反正我也没研究明白,七八个可执行文件就编译出来一个。</p><h2 id="感谢"><a class="header-anchor" href="#感谢">¶</a>感谢</h2><p>感谢所有在实习中帮助过我的老师,同事们❤️。</p>]]></content>
|
||
|
||
|
||
<categories>
|
||
|
||
<category> Internship </category>
|
||
|
||
</categories>
|
||
|
||
|
||
<tags>
|
||
|
||
<tag> Inspur </tag>
|
||
|
||
</tags>
|
||
|
||
</entry>
|
||
|
||
|
||
|
||
<entry>
|
||
<title>ANU COMP2310(2019) Assignment1</title>
|
||
<link href="/anu-comp2310-assignment1/"/>
|
||
<url>/anu-comp2310-assignment1/</url>
|
||
|
||
<content type="html"><![CDATA[<blockquote><p><strong>敬告</strong></p><div style="color: red">本博客请供参考,请不要抄袭。</div></blockquote><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="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/assignment-1.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="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/figure1.svg" alt="3D球形模型"></p><p><img src="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/figure2.svg" 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&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="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/figure3.svg" 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<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="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/figure4.svg" 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="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/figure5.svg" 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="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/figure6.svg" 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 > 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="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/figure7.svg" alt="旋转半径"></p><p><img src="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/figure8.svg" alt="旋转轴"></p><p><img src="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/figure9.svg" alt="2D旋转半径"></p><p><img src="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/figure10.svg" 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="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/figure11.svg" alt="通讯环"></p><p><img src="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/figure12.svg" alt="通讯环内"></p><p><img src="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/figure13.svg" alt="通讯环外"></p><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><p><img src="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/cover.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&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="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/table1.svg" alt="Stage A&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="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/table2.svg" 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="http://davidz.cn/static/blog/2020-01-11-anu-comp2310-assignment1/table3.svg" 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.43GHz,16GB 内存。因为我是用 Python 编写测试脚本,通过识别当前程序线程数量来判断<code>车</code>的数量的,所以测试结果可能不准确。 <a href="#fnref2" class="footnote-backref">↩︎</a></p></li></ol></section>]]></content>
|
||
|
||
|
||
<categories>
|
||
|
||
<category> Study </category>
|
||
|
||
</categories>
|
||
|
||
|
||
<tags>
|
||
|
||
<tag> ANU </tag>
|
||
|
||
<tag> COMP2310 </tag>
|
||
|
||
</tags>
|
||
|
||
</entry>
|
||
|
||
|
||
|
||
<entry>
|
||
<title>Hello World</title>
|
||
<link href="/hello-world/"/>
|
||
<url>/hello-world/</url>
|
||
|
||
<content type="html"><![CDATA[<p>哈哈哈,这是一个经典的测试页面。</p><p>一直以来都想拥有一个自己的博客,从<a href="https://wordpress.org/" target="_blank" rel="noopener">WordPress</a>开始,到<a href="http://typecho.org/" target="_blank" rel="noopener">Typecho</a>,再到<a href="https://halo.run/" target="_blank" rel="noopener">Halo</a>,甚至中途尝试用 Django 自己实现了一个(不过样子也太丑了),虽然说一直在捣鼓博客,但是从来都是安装=>部署=>安装插件=>选择主题=>发布第一篇文章,然后就没有然后了。</p><p>今天我突然看到<a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a>的<a href="https://github.com/TriDiamond/hexo-theme-obsidian" target="_blank" rel="noopener">Obsidian</a>主题,我觉得时机到了,毕竟颜值是第一生产力。</p><p>给自己列一个简单的 TODO LIST 吧。</p><ul><li>[x] 完善 BLOG</li><li>[x] COMP2310 作业整理</li><li>[x] 浪潮实习</li><li>[ ] 终端与 WSL</li></ul><p>希望这个寒假能做完这些吧。</p><p>就这样。</p>]]></content>
|
||
|
||
|
||
<categories>
|
||
|
||
<category> Personal </category>
|
||
|
||
</categories>
|
||
|
||
|
||
<tags>
|
||
|
||
<tag> Others </tag>
|
||
|
||
</tags>
|
||
|
||
</entry>
|
||
|
||
|
||
|
||
|
||
</search>
|