实例:python 实现有向图找环(反洗钱、资金流)

  1. 题目来源:2020华为软件精英挑战赛–初赛
  2. 题目说明:
    2.1 输入信息:输入为包含资金流水的文本文件,每一行代表一次资金交易记录,包含本端账号ID, 对端账号ID, 转账金额,用逗号隔开。
    本端账号ID和对端账号ID为一个32位的无符号整数
    转账金额为一个32位的无符号整数
    转账记录最多为28万条
    每个账号平均转账记录数< 10
    账号A给账号B最多转账一次
    举例如下,其中第一行[1,2,100]表示ID为1的账户给ID为2的账户转账100元:
    1,2,100
    1,3,100
    2,4,90
    3,4,50
    4,1,95
    2,5,95
    5,4,90
    4,6,30
    6,7,29
    7,4,28
    2.2 输出信息:输出信息为一个文件,包含如下信息:
    第一行输出:满足限制条件下的循环转账个数。
    说明:数据集经过处理,会保证满足条件的循环转账个数小于300万。
    第二行开始:输出所有满足限制条件的循环转账路径详情。
    输出循环转账路径要按照指定排序策略进行排序:每条循环转账中,ID(ID转为无符号整数后)最小的第一个输出;总体按照循环转账路径长度升序排序;同一级别的路径长度下循环转账账号ID序列,按照字典序(ID转为无符号整数后)升序排序。
    举例如下:
    4
    1,2,4
    1,3,4
    4,6,7
    1,2,5,4
    2.3 限制条件:循环转账的路径长度最小为3(包含3)最大为7(包含7),例如账户A给账户B转账,账户B给账户A转账,循环转账的路径长度为2,不满足循环转账条件。
  3. 题目理解:
    在这里插入图片描述
    说明:2,4,1,2 是长度为 3 的环,按照升序的要求是:1,2,4
    本案例是以邻接表的形式找环,利用 sort 对 graph.keys() 得到的 key 值进行从小到大的排序,为了在找环过程中出现重复找环的情况,进行了剪枝优化,即:比自己小的 key 不再去查找,本案例用的最基本的 for 循环,对于十万以内的环查找速度较快,但是不建议用python 程序参加比赛,主要是太慢了。当然自己也想过用多进程多线程进行优化,然而效果并没有多大的提升,本文可以很好的帮助小白理解操作,大佬不喜勿喷啊,毕竟作为一个妹子码代码不容易,自己一个人走了太多的弯路了,不过个人很欢迎大佬前来指导一二。
    废话不多说,下面上代码。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/4/23 13:04
# @Author  : xueli
# @Software: win10 Tensorflow1.13.1 python3.6.3
import time

def func(graph,s):#graph图  s指的是开始结点
    path =[]
    for x1 in graph[s]:
        if x1 > s:
            try:
                nodes2 = graph[x1]
            except KeyError as e:
                pass
            else:
                for x2 in nodes2:
                    if x2 > s:
                        try:
                            nodes3 = graph[x2]
                        except KeyError as e:
                            pass
                        else:
                            for x3 in nodes3:
                                if s == x3:
                                    A = [s,x1,x2]
                                    if len(set(A)) == len(
  • 5
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值