實例: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(A):
                                        path.append(A)
                                elif x3 > s:
                                    try:
                                        nodes4 = graph[x3]
                                    except KeyError as e:
                                        pass
                                    else:
                                        for x4 in nodes4:
                                            if s == x4:
                                                A = [s,x1,x2,x3]
                                                if len(set(A)) == len(A):
                                                    path.append(A)
                                            elif x4 > s:
                                                try:
                                                    nodes5 = graph[x4]
                                                except KeyError as e:
                                                    pass
                                                else:
                                                    for x5 in nodes5:
                                                        if s == x5:
                                                            A = [s,x1,x2,x3,x4]
                                                            if len(set(A)) == len(A):
                                                                path.append(A)
                                                        elif x5 > s:
                                                            try:
                                                                nodes6 = graph[x5]
                                                            except KeyError as e:
                                                                pass
                                                            else:
                                                                for x6 in nodes6:
                                                                    if s == x6:
                                                                        A = [s,x1,x2,x3,x4,x5]
                                                                        if len(set(A)) == len(A):
                                                                            path.append(A)
                                                                    elif x6 > s:
                                                                        try:
                                                                            nodes7 = graph[x6]
                                                                        except KeyError as e:
                                                                            pass
                                                                        else:
                                                                            for x7 in nodes7:
                                                                                if s == x7:
                                                                                    A = [s,x1,x2,x3,x4,x5,x6]
                                                                                    if len(set(A)) == len(A):
                                                                                        path.append(A)
                                                                                    else:
                                                                                        break
    return path

def savePredict(AA2):
    t2 = time.time()
    with open(result_name, 'w') as f:
        f.write(str(len(dd))+'\n')
        for aa in AA2:
            ww = str(aa)
            q1 = ww.strip(']')
            qq = q1.strip('[')
            bb = qq.replace(" ", "")
            f.write(str(bb)+"\n")
    print('write_time', time.time() - t2)
if __name__ == '__main__':
    t1 = time.time()
    file_name = "./data/test_data.txt"
    result_name = "result.txt"
    with open(file_name) as f:
        a = []
        c = []
        for line in f.readlines():
            line = line.strip('\n')  # 去掉換行符\n
            b = line.split(',')  # 將每一行以空格爲分隔符轉換成列表
            a.append(int(b[0]))
            c.append(int(b[1]))
    print('read_time', time.time() - t1)
    graph = {}
    data_list = [a,c]
    for x in range(len(a)):
        if a[x] in graph:
            graph[a[x]] += [c[x]]
        else:
            graph[a[x]] = [c[x]]
    s = sorted(graph.keys())
    t4 = time.time()
    dd = []
    for i in s:
        d = func(graph, i)
        if d != []:
            for ii in d:
                dd.append(ii)
    dd.sort()
    print('func_time', time.time() - t4)
    AA2 = sorted(dd, key=lambda i: len(i), reverse=False)
    print(len(dd))
    savePredict(AA2)
    print('總時:', time.time() - t1)

運行結果:
在這裏插入圖片描述
代碼和數據已經上傳到GitHub,感興趣的可以下載下來。
https://github.com/xueli-lxl/python

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章