热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

2020华为软挑总结

文章目录一、热身赛编程闯关:评价标准:问题分析二、初赛问题描述评价标准:问题分析思路一:思路二:思路三


文章目录

    • 一、热身赛
        • 编程闯关:
        • 评价标准:
        • 问题分析
    • 二、初赛
        • 问题描述
        • 评价标准:
        • 问题分析
            • 思路一:
            • 思路二:
            • 思路三:
            • 针对思路三的提速:
        • 最终结果:
    • 三、code记录
    • 初赛两篇不错的总结
    • 三、复活赛
        • 线上结果:
        • 算法思路:
    • 四、复活赛其他组共享代码
    • 五、民间数据集


一、热身赛


编程闯关:

用户贷款风险预测。要求参赛者建立准确的风控模型,预测用户是否会逾期还款。


评价标准:

速度为王,只要速度够快,准确率可以忽略不计。
在这里插入图片描述


问题分析

二分类问题:采用logistic回归算法对用户类型进行分类。
在此分类算法上依次采用L2正则化、影子滑动平均、学习衰减率、随机梯度下降、自适应梯度下降等优化策略。以提高收敛速度,保证泛化能力。
最终结果:不堪入目。
在这里插入图片描述


二、初赛


问题描述

通过金融风控的资金流水分析,可有效识别循环转账,辅助公安挖掘洗钱组织,帮助银行预防信用卡诈骗。基于给定的资金流水,检测并输出指定约束条件的所有循环转账。


评价标准:

在保证准确率的基础之上,速度为王!
结果一定要100%正确,否则无法参与评分。


问题分析

在有向图结构中找出所有长度在[3,7]的简单环,并按规则输出。详细规则 gitee链接-coding记录 中有记录。


思路一:

采用vector储存所有顶点信息,list存储所有边结构信息。采用 深度优先搜索+破环边结构 的方法搜索所有简单环。在官方给的56环数据中,该思路能正确运行;但在线上运行失败。故此路不通。


思路二:

先采用tarjan算法找出图中所有强连通子图;其后在各强连通子图采用johnson算法中寻找所有简单环。
此算法适用于强连通子图比较多的图结构。大赛线上表现一般。
推荐一位小哥的视频,该视频很好地讲诉了该算法的思路。
johnson找环算法视频


思路三:

暴力找环法。依次针对每个节点递归7层结构,只找以此节点为开头的环。该法能确保结果正确,但存在大量重复查找的过程。


针对思路三的提速:

提速一:改变图的存储结构,使用二维数组储存邻接表结构的图,提高访问速度。针对文件的输入,有两种方式。
一种是有序的图结构(按id大小排序):采用set记录所有顶点,并按顶点id大小排序。采用unordered_multimap储存所有边结构。采用unordered_map绑定顶点id与索引号。最终使得图结构按 ID升序排列。顶点ID+边顶点索引号
一种是无序结构:采用unordered_map绑定顶点与其索引号,将边结构顶点的索引号(按查找的方式,从unordered_map对象中获得。 顶点ID顺序与其添加顺序有关。顶点ID+边顶点索引号
提速二:每个起始结点只找比自己id号大的环结构,这样可保证输出的排序规则。
提速三:采用四线程,将数据分成4部分分别查找,最终将所有结果综合排序。

//定义一个计时器类
class Timer
{
public:Timer() : beg_(clock_::now()) {}void reset() { beg_ = clock_::now(); }double elapsed() const {return std::chrono::duration_cast<second_>(clock_::now() - beg_).count();}void out(std::string message = "") {double t = elapsed();std::cout << message << " elasped time:" << t << "s" << std::endl;reset();}
private:typedef std::chrono::high_resolution_clock clock_;typedef std::chrono::duration<double, std::ratio<1> > second_;std::chrono::time_point<clock_> beg_;
};Timer t;
t.out("Tatal");//开启线程的两种方式
#include
#include
//#include
#include//多线程找环//std::future m1 = std::async(FFCC1, std::ref(g)); //线程一//std::thread t1(FFCC1, std::ref(g)); //线程一//std::thread t2(FFCC2, std::ref(g)); //线程二//std::thread t3(FFCC3, std::ref(g)); //线程三std::future <void> m1 = std::async(FFCC1, std::ref(g)); //线程一std::future <void> m2 = std::async(FFCC2, std::ref(g)); //线程一std::future <void> m3 = std::async(FFCC3, std::ref(g)); //线程一g.FC(); //主线程m1.wait();//线程一m2.wait();//线程一m3.wait();//线程一//t1.join(); //线程一//t2.join(); //线程二//t3.join(); //线程三

提速四:一个剪枝的方法。递归消除所有出度为0的结点。


最终结果:

效果一般、牛人太多
团队最优成绩:4.9s
个人最好成绩:5.1s
在这里插入图片描述


三、code记录

gitee链接-coding记录

//编译命令
g++ -O3 baseline.cpp -o test -lpthread
//执行命令、并分析用时
perf stat ./test

推荐操纵服务器的两款不错的工具:
往服务器传送文件:WinSCP、Xftp6
命令行操纵服务器:Xshell6、putty
分享一个能找出所有环的baseline.cpp代码(待优化)。比赛结束了我才发现。。。。。
baseline.cpp


初赛两篇不错的总结

知乎大佬:图中所有简单环查找算法研究总结
知乎大佬删除了好多内容,可惜了。
CSDN大佬:深度遍历暴力求解所有简单环


三、复活赛

与初赛的差异:


转账记录 28W -> 200W
环个数 2914186 -> 2000W
转账金额比例约束 :如[A,B,X],[B,C,Y],要满足0.2 <= Y/X <= 3


算法策略:负三步标记剪枝, 正七步找环,其中后三步只在有标记的结点中寻找。
优化策略:mmap读入,写出; 双vector存图改为动态二维数组存图; 四线程交替分配数据。递归改七层迭代循环。


线上结果:

在这里插入图片描述


算法思路:

建图部分:(1936万环,1s)
1、mmap映射读入,将数据暂存在一个xxxx*3的二维数组中,同时vector记录所有第一个顶点。
2、使用sort为vector排序;使用unique去除重复元素。
3、unordered_map绑定顶点id值与其序号,按顺序依次加入各顶点信息。
4、借组unordered_map和xxxx*3二维数组绑定各边与顶点。建立子图与父图(正向图与反向图)。
5、正向图需对各边顶点序号排序。




找环部分:(1936万环,14s)(直接用动态二维数组可达8s,但对菊花图易造成空间不够。)
a、针对所有顶点均运行一遍找环程序。顶点分配原则为四线程交替分配。有更好的分配方法,(不要预先给各个线程分配任务,这样可能导致任务分配不均匀。使用动态分配策略:维护一个队列,如果一个线程完成了一个任务,那么就去队列里去取下一个任务。),碍于时间有限,未能实现。
b、每次找环,均只找以该顶点为起点的环。

1、反向迭代三层,标记该顶点的负三邻域。迭代时只遍历结点号比自己大的结点。
2、正向迭代前四层正常逻辑,后三层只遍历有标记的结点。
3、找到环时将环变成字符串类型。且3、4、5、6、7各环存在不同的容器中,以保证环有序。





文件写入部分:(1936万环,0.8s)
1、建立mmap映射。
2、各环容器,各线程交替输出。可保证输出有序。





代码可维护性差,仅供参考。
方案一code

方案二code

其中方案一和二,算法思路一样。但实现方式略有不同。


四、复活赛其他组共享代码

1、ddd2020大佬
2、京津东北赛区 A 榜 rank1
3、粤港澳复赛A榜第2
4、2020华为软挑初赛上合赛区第一,复赛A榜总榜第一,B榜GG
5、2020华为软挑初赛武长赛区第一,复赛武长赛区A榜第二解决方案
6、最终成绩杭厦赛区第6


五、民间数据集

民间数据集
知乎评价


推荐阅读
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
author-avatar
挽木城祠_
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有