質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

PyPy

PyPy(パイパイ)は、RPythonで記述されたPythonの実装のひとつです。CPythonとの互換性に重点を置いて開発されており、コードを必要に応じて機械語にコンパイルする「JITコンパイル機能」を備えています。

Q&A

解決済

1回答

465閲覧

(Python,競技プログラミング) setを用いたコードのTLEの理由をご教示ください。

taryo

総合スコア2

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

PyPy

PyPy(パイパイ)は、RPythonで記述されたPythonの実装のひとつです。CPythonとの互換性に重点を置いて開発されており、コードを必要に応じて機械語にコンパイルする「JITコンパイル機能」を備えています。

0グッド

0クリップ

投稿2023/07/08 17:31

前提

競技プログラミング(AtCoder)にて、なぜTLEが発生するのか分からないため質問させていただきます。
AtCoder Beginner Contest 299E問題(リンク)を解いていました。
提出コードがTLEするためコードテストをしていると、どうやら以下の配列distanceを作成する過程で時間がかかっているようでした。
配列distanceは、全ての頂点を始点として幅優先探索を行うことでdistance[i][j] = 地点iからの最短距離がjとなる地点の集合となる配列です。
distance[i][j]の中身をlistにし、追加前に存在確認をすることで重複を無くすようにするとパフォーマンスが改善することからsetの影響で時間が掛かっているのかなとは思うのですが、具体的な原因がはっきりしません。
もしよろしければ、どのような原因で時間が掛かっているのかご教示いただければ幸いです。

該当のソースコード

Python

1import collections 2 3# 入力 4N,M = map(int,input().split()) 5 6# グラフ生成 7graph = {i:[] for i in range(1,(N+1))} 8for _ in range(M): 9 u,v, = map(int,input().split()) 10 graph[u].append(v) 11 graph[v].append(u) 12 13# distance[i][j] = 地点iからの最短距離がjとなる地点のset 14distance = [ collections.defaultdict() for _ in range(N+1) ] 15 16# 全ての頂点を始点としてBFS 17for i in range(1,N+1): 18 queue = collections.deque() 19 ans = [-1]*(N+1) 20 distance[i][0] = {i} 21 queue.append(i) 22 ans[i] = 0 23 while queue: 24 q = queue.popleft() 25 26 if not graph[q]: 27 continue 28 for x in graph[q]: 29 if ans[x] == -1: 30 queue.append(x) 31 ans[x] = ans[q]+1 32 if ans[x] in distance[i]: 33 distance[i][ans[x]].add(x) 34 else: 35 distance[i][ans[x]] = {x}

試したこと

テストケース(リンク)をコードテストした結果が以下になります。
PyPy3:実行時間 2065 ms, メモリ 893200 KB
Python: 実行時間 8713 ms, メモリ 870412 KB

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

distanceで保持しなければならないsetの数が多すぎるのが原因だと思われます。

リンクされたテストケースは、2000個の頂点を一直線上に並べた構造になっています。
そうなると、distanceの要素数は2000、distanceの各要素の要素数は1000-1999(平均1500程度)なので、distance内に含まれるsetの総数は、300万程度になります。

ここまで数が多いと、それぞれの要素がsetlistかという些細な差でも、パフォーマンスへの影響は大きくなります。

投稿2023/07/08 23:03

actorbug

総合スコア2381

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taryo

2023/07/09 02:32 編集

ご回答いただきありがとうございます。 下記のようなコードを用意して、'distance[i]=set()'の部分を'= []', '=[i]', '=set()', '= {i}'の4種試してみたところ、順に約1000ms,1300ms,1000ms,2000msといった実行時間でした。 要素入りのsetを多く持つとlistに比べてやや重たくなってしまうのですね… 大変勉強になりました。ありがとうございました。 ''' distance = dict() for i in range(1,2000*2000):    distance[i] = set() '''
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問