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

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

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

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

Python

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

解決済

関数を並列化する方法が分からない

old.exe
old.exe

総合スコア23

Python 3.x

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

Python

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

2回答

0リアクション

0クリップ

330閲覧

投稿2022/10/04 02:49

遺伝的アルゴリズムで巡回セールスマン問題を解くプログラムを作りました。このプログラムの一部を並列化したいのですが、モジュールがthreading、multiprocessing、asyncioなどたくさんあり、どれをどう使用すべきか分かりません。以下、コードになります。この中でpfga()という関数を並列化したいです。

python

import random import math import csv import copy import time def read_tspfile(): """ tspファイルを読み込み、都市の座標(float型)を [[都市番号,X,Y],[...],...] の形で返す """ def str2float(cities): data = [[0]]*len(cities) for i in range(len(cities)): city = [0]*len(cities[i]) data[i] = city try: for j in range(len(cities[i])): data[i][j] = float(cities[i][j]) except: data[i]*=0 continue data2 = list(filter(None,data)) return data2 def remove_blank(cities): for i in range(len(cities)): for j in range(len(cities[i])): try: cities[i].remove('') except: continue with open("att48.tsp","r") as fin: data = [city.split(' ') for city in fin.read().splitlines()] remove_blank(data) cities_data = str2float(data) return cities_data cities_data = read_tspfile() population = [] # [[経路],[経路],[経路]...[経路]] cities = [] # Cityオブジェクトを入れるリスト CITIES_N = len(cities_data) # 都市数 class City: def __init__(self,num,X,Y): self.num = num self.X = X self.Y = Y class Route: def __init__(self): self.distance = 0 # 経路を作成(重複なしのランダム) self.citynums = random.sample(list(range(CITIES_N)),CITIES_N) def calc_distance(self): """ citynumsリストの各都市間の距離の総和を求める """ self.distance = 0 for i,num in enumerate(self.citynums): """ 1つ前の都市との距離を計算 i=0のとき、i-1は最後の都市(最後の都市からスタートへの距離) """ self.distance += math.dist((cities[num].X, cities[num].Y), (cities[self.citynums[i-1]].X, cities[self.citynums[i-1]].Y)) return self.distance def copy_route(route): return copy.deepcopy(route) def mutate(c1,c2): if random.random() > 0.5: select_num = [i for i in range(len(c1.citynums))] select_index = random.sample(select_num, 2) a = c1.citynums[select_index[0]] b = c1.citynums[select_index[1]] c1.citynums[select_index[1]] = a c1.citynums[select_index[0]] = b else: select_num = [i for i in range(len(c2.citynums))] select_index = random.sample(select_num, 2) a = c2.citynums[select_index[0]] b = c2.citynums[select_index[1]] c2.citynums[select_index[1]] = a c2.citynums[select_index[0]] = b return c1,c2 def crossover(p1, p2): # 子の遺伝子情報 c1 = copy_route(p1) c2 = copy_route(p2) # 切り離す位置をランダムに選択 index = random.randint(1,len(cities_data)-2) # indexの前までは自身の経路 #indexの後からは相方のリスト(index前の都市と重複しないように) fragment_c1 = c1.citynums[:index] fragment_c2 = c2.citynums[:index] notinslice_c1 = [X for X in fragment_c2 if X not in c1.citynums] notinslice_c2 = [X for X in fragment_c1 if X not in c2.citynums] #リストを合体 c1.citynums += notinslice_c1 c2.citynums += notinslice_c2 mutated_c1, mutated_c2 = mutate(c1,c2) return mutated_c1,mutated_c2 def pfga(): # 2未満なら追加。これだけだとランダムに2こ取り出す動作でエラー吐く。別途初期集団は作っておく if len(population) < 2: population.append(Route()) # ランダムに2個取り出す p1 = population.pop(random.randint(0, len(population)-1)) p2 = population.pop(random.randint(0, len(population)-1)) # 子を作成 c1, c2 = crossover(p1,p2) if p1.calc_distance() < p2.calc_distance(): p_good = p1 # 短い経路(優秀) p_bad = p2 # 長い経路(淘汰される) else: p_good = p2 p_bad = p1 if c1.calc_distance() < c2.calc_distance(): c_good = c1 c_bad = c2 else: c_good = c2 c_bad = c1 if c_bad.calc_distance() <= p_good.calc_distance(): # 子2個体がともに親の2個体より良かった場合 # 子2個体及び適応度の良かった方の親個体計3個体が局所集団に戻り、局所集団数は1増加する。 population.append(c1) population.append(c2) population.append(p_good) elif p_bad.calc_distance() <= c_good.calc_distance(): # 子2個体がともに親の2個体より悪かった場合 # 親2個体のうち良かった方のみが局所集団に戻り、局所集団数は1減少する。 population.append(p_good) elif p_good.calc_distance() <= c_good.calc_distance() and p_bad.calc_distance() >= c_good.calc_distance(): # 親2個体のうちどちらか一方のみが子2個体より良かった場合 # 親2個体のうち良かった方と子2個体のうち良かった方が局所集団に戻り、局所集団数は変化しない。 population.append(c_good) population.append(p_good) elif c_good.calc_distance() <= p_good.calc_distance() and c_bad.calc_distance() >= p_good.calc_distance(): # 子2個体のうちどちらか一方のみが親2個体より良かった場合 # 子2個体のうち良かった方のみが局所集団に戻り、全探索空間からランダムに1個体選んで局所集団に追加する。局所集団数は変化しない。 population.append(c_good) population.append(Route()) else: raise ValueError("not comming") # 時間計測開始 start = time.perf_counter() # citiesに読み込んだ座標を持つCityオブジェクトを入れる for i in range(CITIES_N): cities.append(City(cities_data[i][0], cities_data[i][1], cities_data[i][2])) # num,X,Yの順 # populationに個体を追加 for i in range(2): population.append(Route()) best = random.choice(population) # 個体(経路) record_distance = best.calc_distance() # 距離 gen = 0 # 世代カウント用 with open('PfGA_result.csv','w') as fout: csvout = csv.writer(fout) result = [] while True: print(record_distance) population.sort(key=Route.calc_distance) distance1 = population[0].calc_distance() # 最短経路 if distance1 < record_distance: record_distance = distance1 best = population[0] # 最短経路を更新 pfga() gen+=1 if gen == 1 or gen%100 == 0: data = [] data.extend([record_distance]) result.append(data) if gen == 50000: csvout.writerows(result) print(best.citynums) # 時間計測終了(秒) end = time.perf_counter() tim = end - start print(tim) break

以上になります。よろしければ回答お願いします。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

2022/10/04 03:26

こちらの質問が複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という指摘を受けました。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Python 3.x

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

Python

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