• [技术干货] 【转载】Python, C++和Java代码互翻,Facebook开发首个自监督神经编译器
    译者 | 刘畅来源 | AI科技大本营(ID:rgznai100) 将早期的编程语言(例如COBOL)的代码库迁移到现在的编程语言(例如Java或C++)是一项艰巨的任务,它需要源语言和目标语言方面的专业知识。COBOL如今仍在全球大型的系统中广泛使用,因此公司,政府和其他组织通常必须选择是手动翻译其代码库还是尽力维护使用这个可追溯到1950年代的程序代码。 FaceBook公司开发了一个工具TransCoder,这是一个完全自我监督的神经编译器系统,它可以使代码迁移变得更加轻松和高效。本文的方法是第一个能够将代码从一种编程语言转换为另一种编程语言而无需并行数据进行训练的AI系统。本文已经证明TransCoder可以成功地在C++,Java和Python 3之间进行翻译功能。TransCoder的性能优于开源的代码和基于商业规则的翻译程序。在本文的评估中,该模型正确地将90%以上的Java函数转换为C++,将74.8%的C++函数转换为Java,并将68.7%的函数从Java转换为Python。相比之下,市售工具只能正确地将61.0%的功能从C++转换为Java,而开源的翻译器仅能准确地将38.3%的Java函数转换为C++。 自我监督训练对于在编程语言之间进行翻译特别重要。传统的有监督学习方法依赖于大规模的并行数据集进行训练,但是对于COBOL到C++或C++到Python来说,这些数据根本不存在。TransCoder只依赖于仅用一种编程语言编写的源代码,而不需要源代码和目标语言中的相同代码示例。它不需要编程语言方面的专业知识,并且可以很容易地将TransCoder的方法推广到其他编程语言中。本文还创建了专门为此领域设计的新的评估指标。 TransCoder对于将遗留代码库更新为现代编程语言可能很有用,现代编程语言通常更高效且易于维护。它还展示了一个神经机器翻译技术应用的新领域。与Facebook AI以前使用神经网络解决高级数学方程式的工作一样,本文认为NMT可以帮助完成通常与翻译或模式识别任务无关的其他任务。特意为编程语言建立序列到序列模型 在自然语言中,即使在越来越依赖自动化机器翻译系统的专业翻译人员群体中,神经机器翻译的最新结果也被广泛认可。但是,由于代码翻译领域中缺少并行数据,因此它们在该方面的应用受到了限制。程序员仍然依赖于基于规则的代码转换工具,这需要专家复查和调试输出,或者手动翻译代码。TransCoder通过利用无监督机器翻译到编程语言翻译取得的成功来克服这些挑战。 本文构建了一个带有注意力机制的序列到序列(seq2seq)模型,该模型由具有转换结构的编码器和解码器组成。TransCoder使用单个共享模型,部分基于Facebook AI以前在XLM上针对所有编程语言所做的工作。本文按照Facebook AI先前的研究中详细介绍的无监督机器翻译的三个原则进行了训练:初始化,语言建模和反向翻译。本文首先利用开源GitHub项目中的源代码使用蒙版语言模型(MLM)对本文的模型进行了预训练。就像自然语言处理中的上下文一样,这种预训练会创建跨语言的嵌入:在相似上下文中使用来自不同编程语言的关键字在嵌入空间(例如catch和except)中非常接近。这些嵌入的跨语言性质来自存在于多种语言中的大量通用的标记(锚点)。锚点的示例包括C++,Java和Python通用的关键字(例如,for,while,if,try),以及源代码中出现的数学运算符,数字和英语字符串。 使用MLM进行预训练使TransCoder可以生成输入序列的高质量表示。然而,由于从未训练过解码器基于源表示对序列进行解码,因此解码器缺乏翻译能力。为了解决此问题,本文训练了该模型使用降噪自动编码(DAE)对序列进行编码和解码。DAE的工作方式类似于有监督的机器翻译算法,在该算法中,模型被训练为在给定序列存在损坏的情况下预测该序列。作为输入给解码器的第一个符号是指示输出编程语言的特殊标记。在测试时,该模型可以对Python序列进行编码,并使用C++起始符号对其进行解码以生成C++翻译器。C++翻译的质量将取决于模型的“跨语言”:如果编码器将Python函数和有效的C++翻译映射到相同的潜在表示,则解码器将成功翻译成C++。 仅预训练的跨语言模型和自动降噪就足以进行翻译。但是,这些翻译的质量往往很低,因为从未训练过该模型在测试时应该完成什么样的工作,即从一种语言翻译为另一种语言的功能。为了解决此问题,本文使用反向翻译,这是在弱监督的情况下利用单语数据的最有效方法之一。对于每种目标语言,本文使用一个模型和一个不同的开始标记。它经过训练可以从源到目标以及从目标到源并行转换。目标到源版本用于将目标序列翻译成源语言,从而产生与标记目标(GT)序列相对应的嘈杂源序列。然后以弱监督的方式训练模型,让模型可以从嘈杂的源序列中重建目标序列,并学习从源到目标的转换。直到收敛为止。 为了评估该模型,以前对源代码翻译的大多数研究都依赖于自然语言中使用的度量标准,例如BLEU分数或其他基于标记之间相对重叠的方法。但是,这些类型的指标不太适合编程语言。语法差异小的两个程序在执行代码时可能会获得很高的BLEU分数,但会产生非常不同的结果。相反,具有不同实现方式的语义等效程序将具有较低的BLEU分数。另一种度量标准是参考匹配,或与GT完全匹配的翻译百分比,但这通常会低估翻译的质量,因为它无法识别语义上等效的代码。 为了更好地衡量TransCoder和其他代码翻译技术的性能,本文创建了一个称为计算精度的新指标,该指标可评估假设函数在给定相同输入时是否生成与参考相同的输出。我们还将发布测试集以及用于计算该指标的脚本和单元测试。下面的示例显示了TransCoder如何将示例代码从Python转换为C++。我们使用以上的代码作为模型输入:TransCoder成功将Python输入函数SumOfKsubArray转换为C++。它还可以推断参数的类型,返回类型和函数的参数。该模型将Python dequeue()容器附加到C++实现dequeue <>。下面是该模型在C++中的输出:最新研究并在实际应用中提供的帮助 自动代码翻译有可能使在公司或开源项目中工作的程序员更加高效,因为他们可以更轻松地集成公司内其他团队或其他开源项目的各种代码,还可以大大减少更新用早期语言编写的代码库的工作量和成本。 反编译的进步可能会促使公司和其他机构更新到最新的语言并促进未来的创新,这可能让使用服务的人们以及机构本身受益。编程语言机器翻译的进步也可以帮助那些没有时间学习多种语言编程的人。 更广泛地说,人工智能有潜力帮助其他编程任务。例如,Facebook AI以前共享了神经代码搜索,这是一种在查询代码中使用自然语言的方法。以及Getafix,该工具可学习自动为编码错误提供建议修复。虽然TransCoder并非旨在帮助调试或提高代码质量,但它可以帮助工程师迁移旧代码库或使用以其他语言编写的外部代码。 为了促进使用深度学习进行代码翻译的研究,本文还发布了一个测试集,该测试集使其他研究人员可以使用计算精度而不是语义盲模型来评估代码翻译模型。我们期待看到其他人如何在我们与TransCoder的合作基础上继续前进,并为新的翻译任务推进自我监督学习。转载自:CSDN论坛
  • [问题求助] C++如何判断一个浮点数为0?
    c++如何判断一个浮点数为0?
  • [开发环境] 安装 ModelArts SDK 错误 error: Microsoft Visual C++ 14.0 is required
    windows 平台, 使用PIP 安装, pip install modelarts-1.1.3-py2.py3-none-any.whl出错信息: running build_ext    building 'psutil._psutil_windows' extension    error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft VisualC++ Build Tools": https://visualstudio.microsoft.com/downloads/系统是安装了VC++的, 而且数据包和依赖包都下载了. 网上说是whl 文件要放到/script目录下, 看书找了半天, 也没有在pycharm下面找到这个目录.安装详细信息:  Downloading https://files.pythonhosted.org/packages/93/b8/95b1c38f5b00ed2c0d16cf65f2b07a5ae73eeacf66d2010c0e934737d1d9/MarkupSafe-1.1.1-cp38-cp38-win32.whlInstalling collected packages: configparser, six, python-dateutil, Pillow, prometheus-client, esdk-obs-python, gunicorn, psutil, MarkupSafe, Jinja2, Werkzeug, itsdangerous, click, Flask, Flask-Cors, urllib3, modelarts  Running setup.py install for prometheus-client ... done  Running setup.py install for esdk-obs-python ... done  Running setup.py install for psutil ... error    ERROR: Command errored out with exit status 1:     command: 'c:\users\administrator\appdata\local\programs\python\python38-32\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\Administrator\\AppData\\Local\\Temp\\pip-install-3zriipmx\\psutil\\setup.py'"'"'; __file__='"'"'C:\\Users\\Administrator\\AppData\\Local\\Temp\\pip-install-3zriipmx\\psutil\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\Administrator\AppData\Local\Temp\pip-record-n3j_7xlb\install-record.txt' --single-version-externally-managed --compile         cwd: C:\Users\Administrator\AppData\Local\Temp\pip-install-3zriipmx\psutil\    Complete output (37 lines):    running install    running build    running build_py    creating build    creating build\lib.win32-3.8    creating build\lib.win32-3.8\psutil    copying psutil\_common.py -> build\lib.win32-3.8\psutil    copying psutil\_compat.py -> build\lib.win32-3.8\psutil    copying psutil\_exceptions.py -> build\lib.win32-3.8\psutil    copying psutil\_psaix.py -> build\lib.win32-3.8\psutil    copying psutil\_psbsd.py -> build\lib.win32-3.8\psutil    copying psutil\_pslinux.py -> build\lib.win32-3.8\psutil    copying psutil\_psosx.py -> build\lib.win32-3.8\psutil    copying psutil\_psposix.py -> build\lib.win32-3.8\psutil    copying psutil\_pssunos.py -> build\lib.win32-3.8\psutil    copying psutil\_pswindows.py -> build\lib.win32-3.8\psutil    copying psutil\__init__.py -> build\lib.win32-3.8\psutil    creating build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_aix.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_bsd.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_connections.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_contracts.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_linux.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_memory_leaks.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_misc.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_osx.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_posix.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_process.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_sunos.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_system.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_unicode.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\test_windows.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\__init__.py -> build\lib.win32-3.8\psutil\tests    copying psutil\tests\__main__.py -> build\lib.win32-3.8\psutil\tests    running build_ext    building 'psutil._psutil_windows' extension    error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft VisualC++ Build Tools": https://visualstudio.microsoft.com/downloads/    ----------------------------------------ERROR: Command errored out with exit status 1: 'c:\users\administrator\appdata\local\programs\python\python38-32\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\Administrator\\AppData\\Local\\Temp\\pip-install-3zriipmx\\psutil\\setup.py'"'"'; __file__='"'"'C:\\Users\\Administrator\\AppData\\Local\\Temp\\pip-install-3zriipmx\\psutil\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\Administrator\AppData\Local\Temp\pip-record-n3j_7xlb\install-record.txt' --single-version-externally-managed --compile Check the logs for full command output.
  • [问题求助] sample-objectdetection(c++)batch推理问题
    我在做batch推理的时候遇到了如下问题,batch我存了4张图片。输出日志显示:[ERROR] FMK(5166,workspace_mind_studio_sample-objectdetection):2020-07-24-16:21:21.108.525 CheckDataLen:framework/domi/ome/model_manager/model_manager.cpp:953:"data len(12) does not match the model data len(48), input index:1 Error Code:0x3000001(Parameter's invalid!)"
  • [问题求助] 【物联网知识竞赛】+LiteOS Studio为什么要加入C++?Arduino为什么要使用C++?
    LiteOS Studio为什么要加入C++?Arduino为什么要使用C++?
  • [技术干货] 【转载】从C、C++、Java到Python,编程入门到底学什么语言好?
    【转载华为云社区】最近,TIOBE更新了7月的编程语言榜单,常年霸榜的C、Java和Python依然蝉联前三位。万万没想到的是,R语言居然冲到了第八位,创下了史上最佳记录。而且后续随着业内对数据统计和挖掘需求的上涨,R语言热度颇有些势不可挡的架势然而作为程序员吃饭的工具,编程语言之间也形成了某种鄙视链,各大论坛里弥漫着剑拔弩张的气氛,众口难调。也难怪有很多初学者会有疑惑,为什么会有这么多编程语言,我到底应该学什么语言?回顾编程语言几十年来的兴衰起伏,似乎也折射了整个信息产业的变迁消亡,想要在技术的洪流里激流勇进,找准并学精一两门编程语言更加显得至关重要。编程语言的黄金时代“有人不喜欢花括号,开发了Python;有人在一个周末设计了出了JavaScript;有人因为上班太无聊,于是发明了C语言”。关于编程语言的八卦轶事很多,但归根结底,一个编程语言的诞生一定是需求的推动。从面向机器的语言、面向过程的语言到面向对象的语言,编程语言的历史也经历了由繁到简。而互联网崛起的90年代,无疑也是编程语言的黄金时代。套用维基百科的总结,“1990年代未见到有什么重大的创新,大多都是以前构想的重组或变化。”但就是这样的一个时代,却是各种编程语言大放异彩的开始。彼时最主流的编程语言是贝尔实验室两位大佬发明的C/C++语言,互联网的载体计算机的基础设施,都是用这套语言来编写的,包括Linux操作系统、数据库、编译器等等。这也奠定了C语言在IT领域的地位,只要有计算机的存在,C/C++肯定会有它们的一席之地。但后来者居上的故事也随时在发生,这里的主角是已经落幕的昔日巨头网景和Sun。1994年,网景发布了一款真正的网络浏览器Navigator,但受限于当时的技术限制,Navigator更像是一个本地展示页面,不具备任何交互功能。巧的是,Sun公司在1995年正式向市场推出他们开发的Java(即Oak语言),特点是“一次编写,到处运行”,网景看中了这个潜力股,选择与Sun结盟。当时的Java可以作为脚本嵌入到网页中实现交互功能,即我们所熟知的Java Applet。然而,网景认为Java作为网页脚本还是过于复杂,程序员Brendan Eich就在10天内,集百家之长,开发了Javascript,如今所有浏览器前端库都需要基于JavaScript实现。计算机的普及、互联网的崛起,Web应用的出现,Ruby、PHP等语言也悉数登场。如知乎作者“强哥学堂”述,“这段时间,虽然没有创造编程语言,但是由于大量企业的参与,编程语言得到了空前的发展,形成了今天的编程语言的基本形态。也使得软件开发越来越标准化,规模化。”与此同时,还有一些“小众”的编程语言,正蓄势待发中,等待着“爆红”的机会。苹果的搅局,生态很关键2010年iPhone 4问世,乔布斯用智能手机改写了之后的互联网发展轨迹。iOS和Android支撑起的智能手机市场,让移动互联网成为绝对的舞台主角。苹果开创了一个全新的生态,作为iOS的应用开发语言,始于1984年的Objective-C从籍籍无名走向声名大噪,依托各种iPhone、iPad应用程序的开发,Objective-C曾一度挺进TIOBE排行榜的Top 3。不过,苹果在2014年的WWDC上推出了新的编程语言Swift,支持编写macOS/OS X、iOS、iPadOS、watchOS和tvOS的软件应用,并在第二年宣布开源、支持Linux。自此之后,Objective-C的市场份额逐年递减,从2014年的12%下降到2016年的1%。从下图也可以看出,新语言Swift从0开始,这几年一直处于稳定增长中,今年1月也冲进了TIOBE榜单的第九位。虽然一门计算机语言从编译器、语法、基础库到在程序员的圈子中普及,并不是短时间可以一蹴而成,但苹果仍然以一己之力将Objective-C和Swift带入了编程语言的主流市场,由此可见,编程语言和一个产品的生态规模息息相关。微软和Visual Basic的关系也是如此,移动互联网时代之前,VB曾经依靠可视化的开发环境,成为最炙手可热的桌面开发工具,并一度拥有300万开发者。而且借助Windows操作系统市场优势,VB如今也一直保持着居高不下的热度(遗憾的是,微软表示不打算继续演化 Visual Basic了)。回到移动互联网时代,另一边的Android选择的是Java,随着Android阵营的越来越庞大,Java一直是TIOBE榜单上的第一,成绩最差也能拿个第二。一个编程语言的长盛不衰,除了它本身的优势之外,其生态的建设也至关重要,毕竟用的人多了,也就能自成一派,这一点在Python的流行中体现的淋漓尽致。大数据+AI时代,Python一骑绝尘当学Python要从娃娃抓起的口号开始流行时,编程语言从IT圈子进入到大众圈。大数据、AI的时代,Python可以说是一骑绝尘,从数据分析、机器学习、Web开发到爬虫开发都可以在Python的帮助下非常轻松的解决。统计分析人员可以用Python解决数据爬取和分析的问题,大学生可以用Python解决租房的问题……最关键的是,Python的学习门槛比C++,Java都要低,简洁的语法、成熟的第三方库,即使是非程序员群体,也能在短时间内速成。用于统计分析、绘图、数据挖掘的R语言也是如此,赶上了数据应用分析的潮流,自然能从众多编程语言中脱颖而出。针对今年7月榜单R语言创纪录的成绩,TIOBE的 CEO Paul Jansen 明确表示有两大趋势起着关键作用:一是商业统计语言和软件包(如 SAS、Stata 和 SPSS)的时代已经结束,大学和研究机构采用Python和R进行统计分析;二是与COVID-19相关的研究需要进行大量统计和数据挖掘,所以易于学习和使用的统计编程语言热度上升。再比如诞生于2010年,由Mozilla主导开发的Rust语言,其更加强调安全性、存储器配置、以及并发处理等特性。去年Facebook推出的区块链项目Libra,就选择了Rust语言来构建,因为它足够安全。Rust的排名也从2012年的200名开外,在最新一期TIOBE榜单上冲进了Top20。我们以互联网的崛起为分界线,可以看到各个编程语言的此消彼长,必然伴随着新的产品和技术。顺应新技术发展的编程语言,即便时隔几十年,也可以重新焕发光彩。而且随着开源社区的壮大,一门优秀的编程语言可以博采众家之长,成长为后起之秀。结语如果你想以编程语言立生,建议你先学习Java,然后是Python和C++,因为这三种编程语言,基本上可以解决我们工作中遇到的大部分问题。所以,不妨先试试华为云推出的Java开发全栈成长计划,让你0基础入门,构建Java技能体系,向全栈工程师迈进!最后,如C#之父Anders Hejlsberg曾总结:如果要我概括在未来十年编程语言会变成什么样,首先,我认为编程语言应该变得更加“声明式”,我们需要设法为语言引入一些如元编程,函数式编程的能力,同时可能也要寻找让用户有办法扩展语法,使他们可以构造领域特定语言等等。不过总体来说我想强调的是,对于编程语言,新的范式则是“多范式”编程语言。本文部分内容有参考以下文章:1、《IT行业激荡30年->编程语言变迁史》https://zhuanlan.zhihu.com/p/1068080452、《计算机和编程语言的发展历史》https://blog.csdn.net/abc6368765/article/details/83990756
  • [问题求助] atlas200dkC++程序开发
    想问一下有没有关于C++程序开发的指导手册,还想问一下开发版和pc机之间如何完成通讯的
  • [C/C++] c语言和C++的区别
    他们的应用场合是不一样的C语言:C语言是结构化和模块化的语言,是面向过程的。当程序的规模较小时,C语言运用起来得心应手。但是当问题比较复杂、程序的规模比较大的时候,C语言就会展现出它的局限性。C++:正是因为有大规模的程序需要去处理,C++就应运而生了。C++是由C发展而来的,与C语言兼容。C++既可用于面向过程的结构化程序设计,也可用于面向对象的程序设计,是一种功强大的混合型的程序设计语言。语法的不同1、输入/输出函数 C语言:用一个例子说明一下:int a=1;double d=3.1415926;printf("%d\n",a);printf("a=%d\n",a);printf("b=%6.3f, b=%6.2f, b=%.3f\n",b,b,b);scanf("%d",&a);//取地址,输入a的值%d和%f称为格式说明符,表示以此格式输出对应表达式的值,\n表示换行。%6.3f 中的6表示占六列,.3 表示输出对应浮点表达式值时只输出三位小数。C++:也是用一个例子说明:int a=5;float b;cout << "a="<cin >>b;cout必须要和”<<“一起使用,cin必须要和”>>“一起使用。我觉得C++中的输入输出流是很强大的,它不像C里面还要指定格式。endl表示换行。2、字符串另外一个我觉得C++里面另外一个特别好用的用来存放字符串的就是string,它是在C++标准库中声明的一个字符串类。C语言:char a[20]="hangzhou";char *p="hangzhou";C++: string s1="abcd";string s2="hello world";string s3=s1+s2;s1=s2;c++比c更方便许多。3、头文件C语言中所有的头文件都带后缀 .h(比如stdio.h)C++中有系统提供的头文件不带后缀 .h,用户自己编制的头文件可以有后缀 .h。4、结构体和类C语言:结构体struct Student //声明了一个名为Student的结构体类型{ int num;char name[20];char sex;} ;Student stud1,stud2; //定义了两个结构体变量 ,默认情况下为public类型。C++:类class Student{ private:int num;char name[20];char sex;public:void display(){ cout<<"num="<cout<<"name="<cout<<"sex="<};Student stud1,stud2;//定义了两个Student类的对象转自知乎@cdfarsight
  • [问题求助] 编写C++API来GET手机上传的图片,把电脑当成server,然后把结果RETURN给client
    您好,我正在做个项目,就是使用atlas来分析鳄梨的成熟度。步骤大概就是:买鳄梨的人,在手机打开网站,拍个照片网站会把照片发给我的电脑(电脑当成是服务器)电脑通过USB把照片发给AtlasAtlas处理后,把结果发回给电脑电脑再把结果发给手机Atlas这种用法行吗?老师建议我在电脑上写一个C++的API,get手机上传的图片,再return结果,不知这么做可能吗?我附上了架构图(是英文的,不好意思)
  • [大赛专区] 口罩大作战(赛道一)陪跑经历和算法思路代码(C++)分享
      因为一直在电脑旁上网课并且一直拿柜子当椅子坐导致腰肌劳损,所以直到现在才来发分享帖,下面开始正题。  本来早就在学校官方网站上就看到了该比赛,因为课程大作业的原因所以一直推到4月28日才正式开始报名编写代码~  一开始看到题目我首先想到的是TSP(旅行商)问题,就是多次全局搜索取次优解,想到之前编写过用蚁群算法编写过TSP代码(想着这下可以直接搬过来用了),但看到测试用例说要1000幅地图在5分钟内跑完,我开始犹豫了,想起之前跑蚁群的时候一幅地图就要搜索几千次才能得出一个次优解,想着这1000幅地图有点够呛,但自始至终都没注意一幅地图的大小限定(12*12),我脑内一直想的是有在任意大小的地图内N个口罩需求区,1个随机仓库,N个随机口罩捐赠区的配送问题(这也是我一直的毛病看到一个问题就想实现一个通用性比较强的解法,结果最后是试用在用例上效果并不好~~~~)于是我放弃了蚁群搜索算法和Dijkstra这些耗时的搜索算法,使用构造函数的方法(然后陷入了大坑无法自拔~~)第一天(4月28日)——完成了算法思路构建和数据结构编写(代码第一版)1、首先是既然是构造函数法肯定是要有权重值,题目中说基于距离最短,所以将距离因素权重设为0.8,而口罩数量的因素权重设为0.2,然后是每个建筑的位置和口罩数,而且在配送的过程中要时刻删除相关的坐标,所以使用链表数据结构来存储位置信息和口罩数信息,然后是建筑物信息,题目的建筑物可以分为两类,一类是仓库类(捐献小区也可看作是仓库)这类结构体链表中的口罩数是正数;一类是待配送类,这类结构体链表中的口罩数是负数,定义最大口罩数为10000;#define MAX 10000 struct coordinate { int x;         //坐标位置       int y; int cost; struct coordinate *next = NULL; }; class building { public: int sum;                    //目前建筑数量 struct coordinate *last; struct coordinate *first; building() { sum = 0; first =  NULL; last =  NULL; } };2、接着是开始main函数编写while循环监控是否有命令输入,若命令是S则是仓库命令,调用add函数向warehouse建筑类内添加仓库;若命令是R则是小区命令,若num>0则是捐赠小区,向warehouse建筑类内添加,若num<0则是需求小区,向resident建筑类内添加,并且记录总共的需求数need_sum;如果命令为G,则是移动命令,开始执行action函数,若需求小区数sum为0,结束;int main() { char op; int x, y; int num; //int count1 = 0; int Delivery_x, Delivery_y, Delivery = 100; int need_sum = 0; //int total = 0; struct coordinate *pre =  NULL; building warehouse = building(); building resident = building(); while (cin >> op) { if (op == 'S') { cin >> x >> y; add(&warehouse, x, y); if (warehouse.first->next == warehouse.last) { Delivery_x = warehouse.last->x; Delivery_y = warehouse.last->y; } } else if (op == 'R') { cin >> x >> y >> num; if (num > 0) { pre = add(&warehouse, x, y, num); if (x == Delivery_x && y == Delivery_y) { change(&warehouse, &resident, &Delivery_x, &Delivery_y, &Delivery, &need_sum, 2, warehouse.last, pre); } } else { need_sum += abs(num); add(&resident, x, y, num); } } if (op == 'G') { action(&warehouse, &resident, &Delivery_x, &Delivery_y, &Delivery, &need_sum); if (resident.sum == 0) { break; } } } }3、main函数涉及相关函数(1)添加建筑函数add这个就没什么多说的了,建立新的位置信息类结构体,在连到链表上面;(不要在意其中的cout,这是运行测试模块能不能正常运行用的)struct coordinate * establish(int x, int y, int cost = MAX) { struct coordinate *p = new struct coordinate; p->x = x; p->y = y; p->cost = cost; return p; } void action(class building *wa, class building *re, int *d_x, int *d_y, int *sum, int *need, int flat, struct coordinate *n, struct coordinate *n_pre); struct coordinate* add(class building *build, int x, int y, int num = MAX) { struct coordinate* pre =  NULL; if (build->first ==  NULL) { build->first = new struct coordinate; build->last = establish(x, y, num); (*build).first->next = build->last; //cout<<(*build).first->next->x<<(*build).first->next->y<<(*build).first->next->cost<<endl; //cout<<(*build).last->x<<(*build).last->y<<(*build).last->cost<<endl; } else { pre = build->last; (*build).last->next = establish(x, y, num); build->last = (*build).last->next; //cout<<(*build).first->next->x<<(*build).first->next->y<<(*build).first->next->cost<<endl; //cout<<(*build).last->x<<(*build).last->y<<(*build).last->cost<<endl; } build->sum++; return pre; }(2)移动函数action1、如果当前配送员口罩数大于等于需要口罩数的平均数的一半(为什么是大于等于需要口罩数的平均数的一半,因为假设极端情况所有的需求小区都是200,那么派送员最大是100,要满足配送需求就是大于等于此时需要口罩数的平均数的一半即100),为什么还有(*sum)!=0,这是后期发现的bug之后再说,我们现在按时间顺序来说,满足条件后说明可以配送      当此时发现配送员发现持有口罩数大于等于需求区口罩数时(*sum >= abs(p->cost)),计算该需求区的权重意愿值权重函数构造思路------前半部分:float(abs(*d_x - p->x) + abs(*d_y - p->y))*beta距离越短越好后半部分:float(abs(*d_x - p->x) + abs(*d_y - p->y)) / abs(p->cost)*alpha  单位距离配送越多越好     当此时发现配送员发现持有口罩数小于需求区口罩数时(*sum < abs(p->cost))时,使用另一个构造函数计算该需求区的权重意愿值权重函数构造思路------前半部分:同上  后半部分:a = float(abs(*d_x - p->x) + abs(*d_y - p->y))*beta + float(abs(*d_x - p->x) + abs(*d_y - p->y)) /b*alpha  因为此时所持口罩数大于均值,优先配送需求大的小区,减小需求大的小区从仓库到该区域的来回步数;2、如果当前配送员口罩数大于所有的需求,若有则判断权重意愿值3、否则如果有当前配送员口罩数大于需求小区的,则使用权重函数判断此时权重float(abs(*d_x - p->x) + abs(*d_y - p->y)) / abs(p->cost);  单位距离配送越多越好4、若有配送目标则a!=-1,则移动到该点,移动玩之后判断是否移动到了其他需求小区的位置或捐献小区的位置,若有进入change函数改变对应的口罩数;5、否则跳出前往获取口罩Supplementary(wa, re, d_x, d_y, sum, need);void action(class building *wa, class building *re, int *d_x, int *d_y, int *sum, int *need) { float alpha = 0.2, beta = 0.8, a = -1; int best_dis = MAX; int b; struct coordinate *p = re->first->next; struct coordinate *p1 = re->first->next; struct coordinate *pre = re->first; struct coordinate *best= NULL; struct coordinate *best_pre = NULL; while (p !=  NULL) { if (*sum >= (*need) / (re->sum * 2)&&(*sum)!=0) {                 if (*sum >= abs(p->cost)) { a = float(abs(*d_x - p->x) + abs(*d_y - p->y))*beta + float(abs(*d_x - p->x) + abs(*d_y - p->y)) / abs(p->cost)*alpha; //cout<<"a="<<a<<"SUM="<<*sum<<"AVG"<<*need<<"RE"<<(re->sum*2)<<endl; if (a < best_dis) { best_dis = a; best_pre = pre; best = p; } } else { b=abs(p->cost) - (*sum);                 b=(b==0)?1:b; a = float(abs(*d_x - p->x) + abs(*d_y - p->y))*beta + float(abs(*d_x - p->x) + abs(*d_y - p->y)) /b*alpha; //cout<<"a="<<a<<"SUM="<<*sum<<"AVG"<<*need<<"RE"<<(re->sum*2)<<endl; if (a < best_dis) { best_dis = a; best_pre = pre; best = p; } } } else if(*sum >= (*need)){ a = float(abs(*d_x - p->x) + abs(*d_y - p->y))*beta + float(abs(*d_x - p->x) + abs(*d_y - p->y)) / abs(p->cost)*alpha; //cout<<"a="<<a<<"SUM="<<*sum<<"AVG"<<*need<<"RE"<<(re->sum*2)<<endl; if (a < best_dis) { best_dis = a; best_pre = pre; best = p; } } else if (*sum >= abs(p->cost)) { a = float(abs(*d_x - p->x) + abs(*d_y - p->y)) / abs(p->cost); //cout<<"a="<<a<<"SUM="<<*sum<<"AVG"<<*need<<"RE"<<(re->sum*2)<<endl; if (a < best_dis) { best_dis = a; best_pre = pre; best = p; } } else{             break; } pre = p; p = p->next; } //cout<<"目前位置"<<*d_x<<','<<*d_y<<"要去的位置:"<<best->x<<','<<best->y<<endl; if (a != -1) { if (*d_x > best->x) { cout << 'N' << endl; (*d_x)--; } else if (*d_x < best->x) { cout << 'S' << endl; (*d_x)++; } else if (*d_y < best->y) { cout << 'E' << endl; (*d_y)++; } else if (*d_y > best->y) { cout << 'W' << endl; (*d_y)--; } if (*d_x == best->x&&*d_y == best->y) change(wa, re, d_x, d_y, sum, need, 1, best, best_pre); else { int flat = 0; struct coordinate *w = (*wa).first->next; struct coordinate *w_pre = (*wa).first; while (w !=  NULL) { if (abs(*d_x - w->x) == 0 && abs(*d_y - w->y) == 0) { flat = 2; break; } w_pre = w; w = w->next; } struct coordinate *r = (*re).first->next; struct coordinate *r_pre = (*re).first; while (r !=  NULL) { if (abs(*d_x - r->x) == 0 && abs(*d_y - r->y) == 0) { flat = 1; break; } r_pre = r; r = r->next; } if (flat == 2) change(wa, re, d_x, d_y, sum, need, flat, w, w_pre); else change(wa, re, d_x, d_y, sum, need, flat, r, r_pre); } } else { Supplementary(wa, re, d_x, d_y, sum, need); } }(3)获取口罩Supplementary函数1、判断若此时口罩数+捐献小区数大于均值则判断该小区权重意愿值构造函数思路:float(abs(*d_x - p->x) + abs(*d_y - p->y))*beta + float(abs(*d_x - p->x) + abs(*d_y - p->y)) /b*alpha     距离至上,后半部分表示获取口罩的损失率越小越好2、得到位置之后移动,同移动函数action后半部分,先移动后判断是否移动到其他区域;void Supplementary(class building *wa, class building *re, int *d_x, int *d_y, int *sum, int *need) { float a = -1; int best_dis = MAX; int b; struct coordinate *p = (*wa).first->next; struct coordinate *pre = wa->first; struct coordinate *best= (*wa).first->next; struct coordinate *best_pre =wa->first; while (p !=  NULL) { if ((*sum + p->cost) > (*need) / (re->sum * 2)) { b = ((100 - (*sum)) > p->cost) ? (p->cost-(*sum)) : (100-(*sum)); b =(b==0)?1:b; a = float(abs(*d_x - p->x) + abs(*d_y - p->y))*beta + float(abs(*d_x - p->x) + abs(*d_y - p->y)) /b*alpha; //cout<<"获取口罩a="<<a<<"SUM="<<*sum<<"AVG"<<*need<<"RE"<<(wa->sum*2)<<endl; if (a < best_dis) { best_dis = a; best = p; best_pre = pre; } } pre = p; p = p->next; } }(4)口罩数变动函数change这个没什么多说的,flat是区分送口罩还是取口罩,送口罩:足够就送完删除该小区,不够就持有清0  取口罩:足够就取满,不够就取完删除该捐献小区;void change(class building *re, int *d_x, int *d_y, int *sum, int *need, int flat, struct coordinate *best, struct coordinate *best_pre) { if (flat == 1) { if (*d_x == best->x&&*d_y == best->y) { if ((-best->cost) > *sum) { best->cost = best->cost + *sum; (*need) -= *sum; *sum = 0; } else { (*sum) = best->cost + (*sum); (*need) += best->cost; best->cost = 0; //cout<<best->cost<<"剩余"<<(*sum)<<endl; best_pre->next = best->next; re->sum--; if (re->last == best) re->last = best_pre; delete best; if (re->sum == 0) return; } } } if (flat == 2) { if (*d_x == best->x&&*d_y == best->y) { if ((best->cost + (*sum) > 100)) { best->cost = best->cost - (100 - *sum); *sum = 100; } else { (*sum) = best->cost + (*sum); best->cost = 0; best_pre->next = best->next; //cout<<"这里"<<best->next->x<<best->next->y<<best->next->cost<<endl; warehouse.sum--; if (warehouse.last == best) warehouse.last = best_pre; delete best; } } } }然后后面几天就是debug的时间了第二天(4月29日)——debug半天才知道测试不支持C++11 用null替换nullptr,删除了万能开头头文件;第三天(4月30日)1、通过测试一堆数据发现有的时候G命令没有及时移动命令,发现action函数中*sum >= (*need) / (re->sum * 2)这个判断条件若need==1,re->sum==1,sum==0时会卡住,所以加上sum!=0的条件2、添加了捐献小区落脸上的条件判断,第一次提交成功也是最成功的一次,之后不管如何修改都平均步数会更低;第四天(5月1日)——通过分析几天的每日PK例子发现代码在一个区域配送时,有时会跑到其他区域配送增加重复的步数,猜想分区域配送可能会好一点,分为右上配送,左上配送,左下配送,右下配送,但捐赠小区不分区照常获取最优口罩,让最远的待配送区域留到最后配送,进行逆时针配送,防止出现重复步数;例如:分区后的main函数,代码中涉及到的移动判断位置都要加入分区域判断(篇幅情况不过多赘述原代码)building resident_onright = building(); building resident_belowright=building(); building resident_onleft=building(); building resident_belowleft=building(); building warehouse = building(); int need_sum_onright = 0,need_sum_onleft=0,need_sum_belowleft=0,need_sum_belowright=0;if (op == 'R') { cin >> x >> y >> num; if (num > 0) { pre = add(&warehouse, x, y, num); if (x == Delivery_x && y == Delivery_y) {                     if(x<=wa_x&&y>wa_y) change(&resident_onright, &Delivery_x, &Delivery_y, &Delivery, &need_sum_onright, 2, warehouse.last, pre);                 else if(x<wa_x&&y<=wa_y)                     change(&resident_onleft, &Delivery_x, &Delivery_y, &Delivery, &need_sum_onleft, 2, warehouse.last, pre);                 else if(x>=wa_x&&y<wa_y)                     change(&resident_belowleft, &Delivery_x, &Delivery_y, &Delivery, &need_sum_belowleft, 2, warehouse.last, pre);                 else if(x>wa_x&&y>=wa_y)                     change(&resident_belowright, &Delivery_x, &Delivery_y, &Delivery, &need_sum_belowright, 2, warehouse.last, pre); } } else { if(x<=wa_x&&y>wa_y){                 need_sum_onright += abs(num);                 if(abs(x-wa_x)+abs(y-wa_y)>further_dis){                 further_dis=abs(x-wa_x)+abs(y-wa_y);                 position=1;                 } add(&resident_onright, x, y, num); }else if(x<wa_x&&y<=wa_y){     need_sum_onleft += abs(num);     if(abs(x-wa_x)+abs(y-wa_y)>further_dis){                 further_dis=abs(x-wa_x)+abs(y-wa_y);                 position=2;                 } add(&resident_onleft, x, y, num); }else if(x>=wa_x&&y<wa_y){     need_sum_belowleft += abs(num);     if(abs(x-wa_x)+abs(y-wa_y)>further_dis){                 further_dis=abs(x-wa_x)+abs(y-wa_y);                 position=3;                 } add(&resident_belowleft, x, y, num); }else if(x>wa_x&&y>=wa_y){     need_sum_belowright += abs(num);     if(abs(x-wa_x)+abs(y-wa_y)>further_dis){                 further_dis=abs(x-wa_x)+abs(y-wa_y);                 position=4;                 } add(&resident_belowright, x, y, num); } } }最后debug提交发现并没有什么用~~~直接崩溃第五天(5月2日)没办法生病了,划水度过~~~~~~~~~眼睁睁的看着排名一直下跌从20到37~~~~~~~~~~~~~~~最后附上垃圾代码,以上!
  • [云桌面百科] 【鲲鹏开发】各位好汉请留步!小编带你走花路~~
    软件名称 软件介绍链接apr-Apache可移植运行库       apr(apache portable run-time libraries,Apache可移植运行库)的目的如其名称一样,主要为上层的应用程序提供一个可以跨越多操作系统平台使用的底层支持接口库https://www.huaweicloud.com/kunpeng/software/apr.htmlbusybox -Linux常用命令工具busybox 是一个集成了三百多个最常用Linux命令和工具的软件。busybox 包含了一些简单的工具,例如ls、cat和echo等等,还包含了一些更大、更复杂的工具,例grep、find、mount以及telnet等等https://www.huaweicloud.com/kunpeng/software/busybox.htmlGoogle Test - C++单元测试库Google Test,也称为gtest,是基于xUnit架构的用于C ++编程语言单元测试的库。它可以在各种POSIX和Windows平台上进行编译,在修改少量源代码的情况下,对C和C++程序进行单元测试。https://www.huaweicloud.com/kunpeng/software/googletest.htmlFFmpeg - 免费的多媒体框架FFmpeg是一个免费的多媒体框架,可以用来记录、转换数字音频、视频,并能将其转化为流https://www.huaweicloud.com/kunpeng/software/ffmpeg.htmlEmacs - 文本编辑器Emacs是一个文本编辑器。Emacs被公认为是最受专业程序员喜爱的代码编辑器之一https://www.huaweicloud.com/kunpeng/software/emacs.htmlGDB - UNIX下的程序调试工具GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具https://www.huaweicloud.com/kunpeng/software/gdb.htmlOpenSSL - 安全通信软件库OpenSSL是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连接者的身份https://www.huaweicloud.com/kunpeng/software/openssl.htmlSwagger UI - RestFul API文档和测试工具Swagger UI是目前最流行的RestFul接口API文档和测试工具https://www.huaweicloud.com/kunpeng/software/swaggerui.htmlLibxml2 - XML文档解析函数库Libxml2是一个C语言的XML程序库,可以简单方便地提供对XML文档的各种操作,并且支持XPATH查询,以及部分的支持XSLT转换等功能https://www.huaweicloud.com/kunpeng/software/libxml2.htmlReact - JavaScript渲染库React(有时叫“React”“.js”或ReactJS)是一个为数据提供渲染为HTML视图的开源JavaScript库https://www.huaweicloud.com/kunpeng/software/react.htmlTinyXML - 开源的XML解析库TinyXML是一个简单,小巧的C++XML解析器,可以轻松集成到其他程序中。它读取XML并创建表示XML文档的C++对象。可以将对象作为XML进行操作,更改和再次保存开源地址:https://github.com/leethomason/tinyxml2https://www.huaweicloud.com/kunpeng/software/tinyxml.htmlconflict - 查找可执行文件冲突的开发包conflict是一个C++的用来查找可执行文件名冲突的开发包。conflict在执行路径中显示冲突的文件名。与csh命令不同,它显示路径中的所有(非别名)可执行文件。conflict通过列出环境变量PATH中列出的目录列表,然后扫描这些目录以查找可执行文件来报告路径名冲突。如果为conflict提供参数以指定名称范围,则可执行文件的测试仅限于给定的名称(在剥离目录前缀之后)https://www.huaweicloud.com/kunpeng/software/conflict.htmldoxygen - 程序注释转为说明文件的工具                doxygen是一种开源跨平台的、类似JavaDoc风格描述的文档系统,完全支持C、C++、Java、Objective-C和IDL语言,部分支持PHP、C#语言。Doxygen是一个程序的文件生成工具,可将程序中的特定注释转换成说明文件https://www.huaweicloud.com/kunpeng/software/doxygen.htmlfiglet - 终端文本转换为大字母工具figlet是一种用C语言编写的可以将普通终端文本转换为大字母的命令https://www.huaweicloud.com/kunpeng/software/figlet.htmlgit - 开源的分布式版本控制系统Git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理https://www.huaweicloud.com/kunpeng/software/git.htmljsoncpp - 用于与JSON交互的C++库                JsonCpp是一个允许操作JSON值的C++库,包括对字符串进行序列化和反序列化。 它也可以保存反序列化/序列化步骤中的现有注释,使其方便用于存储用户输入文件的格式https://www.huaweicloud.com/kunpeng/software/jsoncpp.htmllibgcrypt - 基于GnuPG代码的通用加密库libgcrypt是一个非常成熟的加密算法库,也是著名的开源加密软件GnuPG的底层库,支持多种对称、非对称加密算法,以及多种Hash算法https://www.huaweicloud.com/kunpeng/software/libgcrypt.htmllibmpc - 具有任意高精度的复数运算库                libmpc是一个C库,用于复数的算术,具有任意高的精度和正确的舍入结果。 它将固定精度实数浮点数的IEEE-754标准的原则扩展为复数,为每个操作提供明确的语义。 同时,高精度的操作速度是主要的设计目标https://www.huaweicloud.com/kunpeng/software/libmpc.htmlMPFR - 多精度浮点库MPFR库是一个C库,用于具有正确舍入的多精度浮点计算https://www.huaweicloud.com/kunpeng/software/mpfr.htmlRE2 - 开源的正则表达式库RE2是Google开源的正则表达式库,提供对C/C++、Python、Ruby等多种语言的支持https://www.huaweicloud.com/kunpeng/software/re2.htmlzlib - 通用数据压缩库zlib是通用的压缩库,提供了一套in-memory压缩和解压函数,并能检测解压出来的数据的完整性(integrity)。zlib也支持读写gzip (.gz)格式的文件https://www.huaweicloud.com/kunpeng/software/zlib.htmlThrift - 远程过程调用(RPC)框架Thrift是一个跨语言的服务部署框架,最初由Facebook于2007年开发,2008年进入Apache开源项目。Thrift通过一个中间语言(IDL,接口定义语言)来定义RPC的接口和数据类型,然后通过一个编译器生成不同语言的代码(支持C++、Java、Python、PHP、Ruby、Erlang等语言)并由生成的代码负责RPC协议层和传输层的实现https://www.huaweicloud.com/kunpeng/software/thrift.htmlPF_RING - 高效数据包处理框架PF_RING™是一个Linux内核模块和用户空间框架,它使您可以高速处理数据包,同时为数据包处理应用程序提供一致的API。已在鲲鹏云服务器上验证过下述版本,请根据实际需要选择版本https://www.huaweicloud.com/kunpeng/software/pfring.htmlpcre - 正则表达式pcre(perl compatible regular expressions中文含义:perl语言兼容正则表达式)是由菲利普.海泽(Philip Hazel)编写的正则表达式函数库,它是比Boost之中的正则表达式库小得多,但PCRE十分易用,同时功能也很强大,性能超过了POSIX正则表达式库和一些经典的正则表达式库https://www.huaweicloud.com/kunpeng/software/pcre.htmlapr-util - Apache可移植运行库完整的APR(Apache portable Run-time libraries,Apache可移植运行库)实际上包含了三个开发包:apr、apr-util以及apr-iconv,每一个开发包分别独立开发,并拥有自己的版本。apr-util该目录中也是包含了一些常用的开发组件。这些组件与apr目录下的相比,它们与apache的关系更加密切一些。比如存储段和存储段组,加密等等https://www.huaweicloud.com/kunpeng/software/apr_util.htmlHiredis - Redis的C接口库Hiredis是Redis数据库的C接口库https://www.huaweicloud.com/kunpeng/software/hiredis.htmlFlatBuffers - 跨平台的序列化工具库FlatBuffers是一个开源的、跨平台的、高效的、提供了C++、Java、Ruby等接口的序列化工具库https://www.huaweicloud.com/kunpeng/software/flatbuffers.htmlCmockery - C单元测试的轻量级框架Cmockery是Google发布的用于C单元测试的一个轻量级的框架。它很小巧,对其他开源包没有依赖,对被测试代码侵入性小https://www.huaweicloud.com/kunpeng/software/cmockery.htmlJunit - 开源的Java测试框架JUnit是一个开源的Java测试框架,用于编写和运行可重复的测试。它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具https://www.huaweicloud.com/kunpeng/software/junit.htmlOpus - 高性能音频编解码器Opus是一个完全开放的、免费的、多功能的音频编解码器。 它在交互式的语音和音乐在互联网中的传输方面有着无与伦比的优势,但是同样致力于存储和流媒体应用程序。它是由互联网工程任务组(IETF)制定的标准,标准格式为RFC 6716,由Skype的SILK编解码器和Xiph.Org的CELT编解码器合并发展而来,号称音频编解码器中的瑞士**https://www.huaweicloud.com/kunpeng/software/opus.htmlVue - 构建用户界面的渐进式框架Vue是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。此外,当与现代化的工具链以及各种支持类库结合使用时,Vue完全能够为复杂的单页应用提供驱动https://www.huaweicloud.com/kunpeng/software/vue.htmlShc - shell脚本加密工具Shc用来对shell脚本进行加密,它将shell脚本转换为一个可执行的二进制文件,从而避免shell脚本中的用户名、密码等重要信息暴露https://www.huaweicloud.com/kunpeng/software/shc.htmlbuddy - 二元决策图开发库buddy是一个二进制决策图开发库,它包括许多功能,比如:许多高效的矢量化BDD操作,动态变量重新排序,自动垃圾收集,具有自动引用计数的C++接口等等https://www.huaweicloud.com/kunpeng/software/buddy.htmldos2unix - Windows文件转换为Unix格式工具dos2unix是将Windows格式文件转换为Unix、Linux格式的实用命令。Windows格式文件的换行符为“\r\n”,而Unix&Linux文件的换行符为“\n”。dos2unix命令其实就是将文件中的“\r\n”转换为“\n”。而unix2dos与dos2unix相反,它是将Linux和Unix格式文件转换为Windows格式文件的命令https://www.huaweicloud.com/kunpeng/software/dos2unix.htmlenca - 编码转换工具enca是一个实用的编码转换工具https://www.huaweicloud.com/kunpeng/software/enca.htmlfmt- C++的开源格式库fmt是一个用于C++的开源格式库。 它可以作为printf和iostreams的安全和快速替代品https://www.huaweicloud.com/kunpeng/software/fmt.htmlGMP - 大整数运算库GMP(The GNU Multiple Precision Arithmetic Library)又叫GNU多精度算术库,是一个提供了很多操作高精度的大整数,浮点数的运算的算术库,几乎没有什么精度方面的限制,功能丰富https://www.huaweicloud.com/kunpeng/software/gmp.htmllibconfig - 结构化的配置文件库libconfig是一个结构化的配置文件库,用于结构化文件的读取、操作和写入,提供对C、C++两种语言的支持https://www.huaweicloud.com/kunpeng/software/libconfig.htmllibgpg-error - libgcrypt支持库libgpg-error是一个小型库,最初为所有GnuPG组件定义了常见错误值。 其中包括GPG,GPGSM,GPGME,GPG-Agent,libgcrypt,Libksba,DirMngr,Pinentry,SCdaemon。 由于Libgpg-error是所有GnuPG组件的常见依赖项,因此库中添加了更多功能,比如扩展流库(estream),printf实现,锁(互斥)的实现等等https://www.huaweicloud.com/kunpeng/software/libgpgerror.htmlOpenCV - 跨平台计算机视觉库OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列C函数和少量C++类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法https://www.huaweicloud.com/kunpeng/software/opencv.htmlRinetd - TCP端口转发技术Rinetd是一种简单的TCP端口转发技术。Rinetd软件可将发往本机某个网口上的某个端口的访问,传递到别的服务器的某个网口的某个端口https://www.huaweicloud.com/kunpeng/software/rinetd.htmlWebSVN - svn的web浏览软件WebSVN是一个基于Web的Subversion Repository浏览器。它将Subverion的各种功能操作通过Web界面提供出来。通过它,可以看到任何给定版本的任何文件或者目录的日志,并且可看到所有文件改动、添加、删除的列表。同样可以查看两个版本间的差异来知道特定版本改动了什么https://www.huaweicloud.com/kunpeng/software/websvn.html 
  • [技术干货] 【转载】鲲鹏编译时间优化(C/C++)
    1 问题背景项目中遇到鲲鹏芯片架构下编译C/C++代码编译时间过长,增加了业务版本CI时间,需要优化。本案例分享一下基于cmake和GCC编译优化的思路和措施。2 原因分析获取环境以后,利用开源软件A编译测试,逐步对可能影响编译时间的因素排查调优分析。1.  充分发挥多CPU并行处理功能Make阶段利用多线程处理,将进程个数设置成cpu的核数,提高编译速度。效果:相对于单线程编译来说,有几倍提升。2.  降低iowait同过iostat观察,编译过程中有部分时间出现iowait,特别是编译写文件的时候。方法:修改缓存VM参数,增加缓冲:以下参数和X86配置不一致,修改一致为:(1)/proc/sys/vm/dirty_ratio 修改前10,修改后20效果: 整体编译时间减少2s左右,说明有一定的效果,还不是关键因素。3.  去掉nohz=off/proc/cmdline如果存在nohz=off配置,会对系统性能有影响,尝试去掉测试性能方法:找到系统中/boot/efi/EFI/XXX/grub.cfg的nohz=off去掉,并重启服务器效果:去掉nohz=off参数后测试性能和修改前差不多4.  Gcc参数加入ARM相关编译参数新版本gcc里面加入了对ARM架构的编译优化参数,如-mtune=tsv110,-march=armv8-a,尝试是否对编译性能有提升。方法:升级编译gcc到9.2.0版本,在编译脚本gcc后面加上-mtune=tsv110,-march=armv8-a参数,重新对程序进行编译测试性能。效果:添加参数后gcc编译性能无提升,平均执行时间和修改前差不多。此选项加入是优化编译软件运行性能的,不会降低编译时间。5.  内存页大小通过perf分析,编译代码有很多跳转指令,汇编代码中加载内存指令的执行时间段很高,分析可能是内存主要瓶颈。Perf热点函数分析内存换页函数调用频繁,浪费时间。可以通过扩大内存页来加大每页命中率,减少页切换的资源浪费。方法:获取内核源码,修改.config文件参数CONFIG_ARM64_64K_PAGES=y(注意,执行make menuconfig通过界面修改更为全面),重新编译内核,然后系统用新内核启动。检查是否修改成功: getconf PAGESIZE  显示为65536 即表示修改成功。效果:编译时间缩短20%左右,优化效果较大。3 解决方案综上分析,通过并发编译、修改vm缓存参数和调整内存页大小为64K对编译时间优化有显著效果。修改方法也在上文有描述。4 总结优化编译时间在版本构建的时候很关键,能节约不少构建时间,提高生产效率。目前大多是对编译出程序性能的优化,这样必然会增加编译时间,比如说如果用高版本的GCC编译器,编译出来的程序性能会更好,但是编译时间可能变长了,相比低版本的GCC来说。也就是说,如果想优化编译时间,尽量避免去用新GCC版本,或者利用新的GCC编译优化参数。 提供程序运行性能,让他跑得更快,还是老一套,去分析程序运行时的系统瓶颈,解除瓶颈后会对性能有提升,如本案例中内存就是一个瓶颈。转自:https://bbs.huaweicloud.com/forum/thread-42510-1-1.html
  • [大赛专区] 关于口罩大作战赛道一(C++)的记录和总结——White-Loub
        2020.5.6    20:38    四月末看到学校的通知,加上女朋友的大力“怂恿”,作为一个刚刚入门的小白,我毅然决然的和女朋友一起报名参加了比赛,后面的过程真是一把鼻涕一把泪。我想把我的思路和参赛经历记录下来,也就当做纪念啦。当然啦,由于学识疏浅,我的代码里并没有什么特别厉害的算法,如果能给各位提供一点点一点点参考,那真是。。。很很很很有幸了(注:本人排名30+,和我排名相近的同学和排名在前的大佬们怕是没有什么可以参考的了),献丑啦!        我使用的是C++语言,代码整体思路非常简单。    首先我思考了一下配送口罩的整个过程,其实就是1.快递员取口罩;2.快递员思考目的地;3.快递员送口罩。在代码实现的过程中,思路可以稍微修改一些,比如快递员取口罩和送口罩其实都包含了快递员的移动和口罩数量的变化,为了更好实现,在代码中我们就可以将这两部分分开,所以上面的几点其实可以转换为下面几个模块:1.快递员朝目标地移动;2.快递员携带的口罩数量和建筑物口罩数量变化;3.判断快递员的目标地。其实我认为这道题最难的地方就在于快递员目标地的判断,这部分的算法就导致了快递员的送货效率(完成一幅地图的步数),很显然,作为小白,我不知道该如何更好的处理这一部分,算法真是又难又厉害呀。    明确了刚才的思路,我们就可以开始写具体的代码啦,以下记录的代码主要是样例,具体代码由于比赛还未结束,会在结束后更新!    当然,我们首先先完成地图的录入工作,也就是记录仓库和需求小区的位置(题目开始的6个输入)!/*例如,这是仓库的录入代码*/ char S;//定义仓库名称  int S_x,S_y;//定义仓库变量;我没有使用数组来记录各个建筑物的值,而是使用了整数变量,便于理解 cin>>S; if(S =='S') { cin>>S_x>>S_y; //输入仓库坐标信息 }    然后,就开始代码的主体,就是按照刚才的思路来,在这里,为了获取一个G的输入我们就进行一次移动或者判断,我使用了While循环!第一步的移动可以靠预设的值进行,以后的移动靠上一轮循环判断的目标进行移动,同时,用一个变量(我用的是send_or)判断移动是配送移动还是取货移动可能更容易梳理逻辑,另外不要忘记捐赠小区的输入!char G;//获取系统输入指令 int send_or=1;//设定送货还是取货状态,0为取货,1为送货  int P_x,P_y,P_send;//设定快递员位置和快递员口罩数量  int O_send=0;//设定快递员到的补给点,初始补给点设为仓库(假设仓库编号为0) .............;//部分变量设置未展示 cin>>G; //首先是先获取第一个G的输入,然后开始循环 while(G) {     /*如果新输入为R开头的捐赠小区,则记录离目标点近的补给小区*/       if(G=='R')     {         int i;         cin>>R_donation_x[donation_j]>>R_donation_y[donation_j]>>R_donation_num[donation_j];//我使用数组记录捐赠的小区,比较复杂,不要忘记捐赠小区的录入就好         for(i=1;i<donation_j;i++)         {             if(R_donation_x[donation_j]==R_donation_x&&R_donation_y[donation_j]==R_donation_y)             {                 R_donation_num=R_donation_num+R_donation_num[donation_j];                 R_donation_x[donation_j]=0;                 R_donation_y[donation_j]=0;                 R_donation_num[donation_j]=0;                 donation_j=donation_j-1;                 break;              }         }         donation_j++;     }      /*进入移动阶段*/     /*例如判断是否向仓库移动*/     if(G=='G' && send_or==0 && O_send==0)     { if((S_x-P_x)<0)//判断是否需要向北走  { cout<<'N'<<endl; P_x--; } else if((S_x-P_x)>0)//判断是否需要向南走  { cout<<'S'<<endl; P_x++; } else if((S_y-P_y)>0)//判断是否需要向东走  { cout<<'E'<<endl; P_y++; } else if((S_y-P_y)<0)//判断是否需要向西走  { cout<<'W'<<endl; P_y--;      }     }          /*判断是否向捐赠小区移动*/      .........................//部分代码未展示          /*判断是否向目标小区移动*/     .........................//部分代码未展示 }    然后,是对快递员到达各个位置数量变化的判断,依旧在While循环内,这里要注意两个问题:1.捐赠小区生成在快递员的当前位置;2.移动途中经过了需求小区!while(G) {     ....................//刚才的代码          /*以下进入判断阶段*/     /*如果经过或者踩到仓库的处理方法,只判定数量改变*/     if(P_x==S_x&&P_y==S_y)     {         P_send=100;     }          /*如果经过或者到达捐赠小区,包括捐赠小区生成在快递员位置,只判定数量改变*/     i_pro=1;     for(i_pro=1;i_pro<donation_j;i_pro++)     {          if(P_x==R_donation_x[i_pro]&&P_y==R_donation_y[i_pro])         {             if(P_send+R_donation_num[i_pro]<=100)              {                 P_send=P_send+R_donation_num[i_pro];                 R_donation_num[i_pro]=0;             }             else             {                 R_donation_num[i_pro]=R_donation_num[i_pro]+P_send-100;                 P_send=100;             }                  break;//如果已经确认踩到,就跳出循环          }     }          /*如果经过或者到达需求小区的处理方法,只判定数量改变*/     .....................................//部分代码未展示 }    最后,就是对目标地的判断,主要是判断快递员的目标,再次循环时,快递员再根据目标进行移动、判断数量、判断目标,不断循环!最后部分因为我代码的变量太复杂,展示后不太容易看懂,我就详细的记录和总结一下我的思路,和刚才的例子形成一个整体。刚才我们已经说了,对于目标地点的判断是核心,再此之前,我们要完成需求小区、捐赠小区信息录入,要有数组或者专门的变量进行记录,这样我们可以确定每个建筑;然后是移动,第一步的移动可以靠预设的值进行,以后的移动靠上一轮循环判断的目标进行移动。    最后的判断部分,我的想法很简单,就是每一步结束以后进行判定:1.如果处在取货状态,快递员到达目标点(仓库或者捐赠小区)后,就改成送货状态;或者未到达目标点,但是身上的货物满足当前需求(当前配送的目标需求小区的需求)也改为送货状态;2.如果处于送货状态,快递员身上的货物由于经过了非目标需求小区导致货物数量不达标,则改为取货状态;3.正处于取货状态,先判断除仓库外口罩数量满足当前需求(当前配送的目标需求小区的需求)的捐赠小区,再选择这些小区中距离最近的一个作为取货的目标,如果一个都没有,就设定仓库为取货的目标。    依次循环,便可跑完地图。    注意,这道题中需要注意的几个点,我记录下来:1.捐赠小区可能生成在快递员位置上,此时快递员会取走该捐赠小区的货物(快递员的携带的货物不会超过100,只会补齐缺少的数量);2.捐赠小区的口罩如果没被取完会一直保留;3.经过需求小区和捐赠小区,快递员的数量一定要进行判定是否发生变化。    总结。最后做个总结!我写这一篇记录真是在各位大佬面前献丑啦,感谢华为和各位参赛同学,真是让我见识到算法的神奇!我更加可以理解好的算法在一段代码中起到的核心作用,而且编程真是逻辑性非常强的事情,有时候逻辑上错一点,代码便会运行出错,而为了让自己的思路通畅,就需要我有良好的编程习惯(比如规范的格式、便于理解的变量命名等),就像那句话说的一样:“I'm not a great programmer; I'm just a good programmer with great habits.”OK!感谢各位!我会继续努力,争取早日搞懂诸如启发式搜索之类的算法,然后在最后的几个小时,我希望再改进一下代码,优化一下快递员取货目标的计算!哈哈哈~    冲鸭!--------------------------------------------------------------------我是分割线!---------------------------------------------------------------------    2020.5.7    21:18    更新一波,分享我和女朋友的代码!班门弄斧,献丑啦!    今天晚上看了各位大佬的解题思路,受益匪浅!我们会继续努力的!    继续冲鸭!
  • [大赛专区] 赛道一小结(C++)_本次竞赛算法思路与代码分享以及学习c++的资源链接和计算机速成课视频链接
             从学校官网得知比赛消息,到现在转眼已经快两周了,比赛也接近了尾声,写一个小结也算记录下这次的比赛经历,毫不夸张的再说,这次比赛我投入了几乎自己全部的精力和热情去做这件事,中断了坚持了一个月的健身,刚刚恢复的作息再一次变得乱七八糟,但是看到提交成功也有一种小小的成就感,第一眼看到竞赛标题,“口罩配送”,就觉得新奇和接地气,自己参加比赛之余也觉得自己是在为改善社会生活做了一丁点贡献。       这是我最终成绩的截图,以及有幸登入一次每日PK榜,和前面的大神有好远的距离,看了大神们的分享,发现还是思路有了很大的局限性。       下面说说我的编程之旅吧,看完题目和要求,我就先衡量自己的选择和需要准备的东西,编程语言我选了c++,并没有什么高大上原因的考虑,因为我只会它,然后就是编程软件和开发环境,我用的是VS2019而没选择devc++,是因为用过前者,但是这个选择也让我后来遇到了一个问题。       搭建好编译环境,我就着手于整个程序框架的搭建,我喜欢整体确定后,慢慢完善的感觉,写完了输入输出函数,就开始着眼于方法的实现,一开始太过于贪心,总想着用些高大上的有技巧的方法,结果一整天也没什么进度,主要还是知识储备量匮乏,高深的算法也理解不了就更谈不上灵活使用。后来我就完全自己去想解决方法,首先是数据的整理以及特征化。我建立了下图中这些结构体数组,其中包含地图每一点的信息如同一幅图像数组,配送员的状态,捐赠小区的状态以及配送小区的状态。       结合之前和导师做过图像滤波方面的东西,我就选择了类似于均值滤波,中值滤波这样的小窗口来收集配送员周边的捐赠和配送小区的信息,从而选择移动的方向,后来由于窗口选择太小对突然出现的捐赠小区不敏感,从而路径优化的程度太低放弃了,窗口再大就不如处理整个12*12矩阵了。不过得益于此,从这之后,我从局部最优联想到当前路径最优。即将在最短步数下完成一个配送次数,配送次数就是指满足一个小区所需要到该小区的次数,需求量大于100的为2,小于100的为1。        具体操作就是:        1,当配送员在仓库时,将配送小区信息按照距离仓库的由近到远排序,选择最近的配送点作为配送目标。        2,当配送员到达配送小区后,根据配送员身上的剩余口罩数目判断接下来的目标点,按照配送小区距离配送员的近到远查询配送小区的需求数进行查询,当目前地图未出现捐赠点时,如果配送员自身剩余口罩不满足一个配送次数,则将目标点为仓库。        3,当目前地图出现捐赠点时,配送员自身剩余口罩加上全部捐赠数目满足一个配送次数,则启动最短路径查询函数,以目前所在点到仓库加上距离仓库最近点的配送小区所需要的步数为衡量标准,计算满足一个配送次数所走的最短路径,并将该路径沿途的捐赠点坐标信息以及目标点坐标信息进行保存,每经过一个捐赠点就会将下一步的坐标作为行进目标。       4,当所有配送小区需求数目为0,退出程序。        其中,最短路径查询函数的原理是分别以剩余四个配送点作为路径终点,采用递归方式,进行将捐赠点任意组合形成路径,比如1,2,3三个捐赠点,就会有1,2,3,12,13,123等六条路径,同时对需要经过多捐献点的路径将捐赠点按照走完所需要最短步数的原则进行排序,结合配送员和捐赠点的口罩数将不符合配送次数的路径剔除。       具体代码我分享到附件当中,有兴趣的可以看看。       下图是代码函数中的子函数以及相关注释:       在这个最终版想法之前,我是用路径最优法,选择比原路径降低步数最多的路径进行存储,再将去往每个配送点的路径进行同样比较,选择降低步数最多的路径作为当前的路径。后来经过测试发现当前路径最优法会造成多余步数,就是比如配送员还差一步到达目标,此时出现一个捐赠点,程序判定配送员经过该捐赠点到达另一个目标比当前的路径优化的步数多,它就会毅然去往捐赠点,导致未完成目标,之前走的路就有点多余。为解决这个问题,我就将追求当前路径最优改成了当前路径最短,与路径最优选择方法一致,只不过是选择一条步数总和最少的路,完成程序编写之后就开始了我漫长又难熬的调试过程,用一句话简单却又痛苦的话就是,我走了一些弯路。       线下测试和程序debug的成功和一上传就说我编译错误,让我一度抓狂,后来被群里的一个小伙伴建议用devc++试试,我就用它编译了一下,出了很多警告和一个错误,我才知道vs2019可能会默认一些新编译规则,我改正了警告,修复了错误。然而故事并没有结束,我遇到了群里很多小朋友遇到的问题“配送已结束,仍有小区未获得口罩”,我本着一定是数据或我程序判定部分出问题的观念,不停地debug,验证数据的传递和每一个判断,却什么也没发现,我想是我设想的地图情况太少的原因,就边百度边修改了线下测试程序,改成随机生成地图,测试100幅,报了错误,我将报错的地图一幅幅的分析,都没找到程序哪儿的命令出错了,我仔细看了看测试代码,发现错误原因是两者的信息不一致,后来又是群里一个小伙伴点醒了我,测试程序只能接受方向指令,无法进行多余的操作,即我程序原本设定的是到了配送小区有选择的留下口罩数目,但是测试程序直接扣除了配送员身上的全部,导致两者信息的不一致。Bug找到进行了修复,害怕再失败我就在线下测试了1000幅随机地图,都成功了,我就提交了作品,事实证明我还是太年轻了,网页信息提醒我配送员超出了地图范围,这个原因有两种,一种是接受你的移动指令后,位置超出了地图数组边界,另一种就是配送员原地打转。。。。由于没有地图信息无法调试,我就又跑了随机测试程序,事实证明同志们,测试次数再多也不为过!我跑了3000幅地图!!才有一幅爆出了我超出范围的错误!有了地图后面的单步修改程序就简单了很多,在提交成功后,评分第一次出现的时候,真是超级激动有木有!接下来没有程序细节上的问题,我又对程序算法做了一些调整,将路径最优算法和路径最短算法进行结合使用,路径最优算法用于当配送员位于配送点时触发,能保证当前路径最优,在新捐献点出现时触发路径最短算法,就解决了路径最优算法造成的步数浪费。写了这么多,絮絮叨叨,应该也没人会看完,本来打算5.4时候写一下发一下,庆祝下节日,可惜程序的bug没让我如愿。      以上就是我这次竞赛的全部经历和想法历程了,也算是一种自我梳理。最后这几天状态的总结可以用一个成语来形容,废寝忘食,有时候亲身体会了才明白古人诚不欺我,也许对编程是一种热爱吧,只有热爱才会让我专心致志和想要去完成一件事,一直觉得虚拟行业很酷,你编的每一条代码,每一行指令都是在让那个世界越来越美,希望有一天自己参与完成的一些东西在这个世界的角落,稳定而又高效的运行着,它的每一秒都是在让这个世界更美好。,希望大家多多批评指正!多多留言给我!                                                                                                                                                                                             2020/05/05           注:下面的链接是我在学习c+和数据结构时看的一些视频链接,网上反响比较好的,希望大家一起学习!大家一起进步!          【C语言】《带你学C带你飞》(小甲鱼):https://www.bilibili.com/video/BV17s411N78s?p=1          计算机速成课(很有意思,对于梳理计算机体系很有用):https://www.bilibili.com/video/BV1EW411u7th?p=1          C++从0到1入门编程(附C++编程环境搭建教程):https://www.bilibili.com/video/BV1et411b73Z?p=1          数据结构(郝斌):https://www.bilibili.com/video/BV11s41167h6?p=1
  • [问题求助] 请问ATLAS 200DK中如何使用纯C(不是C++)的代码?
    直接源码编译报ELF重定位.Information:/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: CMakeFiles/picasso.dir/core/encrypt/aes.c.o:普通ELF重定位(M: 62)Information:/usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: CMakeFiles/picasso.dir/core/encrypt/aes.c.o:普通ELF重定位(M: 62)Information:CMakeFiles/picasso.dir/core/encrypt/aes.c.o: 无法添加符号: 文件格式错误Error:collect2: error: ld returned 1 exit status编成.a,如下图所示: