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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 3.x

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

GitHub

GitHubは、Gitバージョン管理システムを利用したソフトウェア開発向けの共有ウェブサービスです。GitHub商用プランおよびオープンソースプロジェクト向けの無料アカウントを提供しています。

Q&A

解決済

2回答

1816閲覧

座標値をprintすると,0x0000....のようなオブジェクト?の結果が出力されてしまう.

退会済みユーザー

退会済みユーザー

総合スコア0

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 3.x

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

GitHub

GitHubは、Gitバージョン管理システムを利用したソフトウェア開発向けの共有ウェブサービスです。GitHub商用プランおよびオープンソースプロジェクト向けの無料アカウントを提供しています。

0グッド

0クリップ

投稿2018/12/04 07:28

実現したいこと

github上にある2-opt法のプログラム結果を数値で表示したい.
理由は,結果をmatplotlibで可視化したいため

コード

python

1""" 2Alissa Hall 3CS 345 4May 11, 2016 5TSP 2-opt algorithm for Python given a pre-existing tour. 6Input files must have '.tsp' extension. 7""" 8 9from sys import argv 10from math import hypot 11from timeit import default_timer 12from random import randrange 13 14class Node: 15 """ 16 represents a node in a TSP tour 17 """ 18 def __init__(self, coords): 19 self.num = coords[0] # start position in a route's order 20 self.x = coords[1] # x coordinate 21 self.y = coords[2] # y coordinate 22 23 def __str__(self): 24 """ 25 returns the string representation of a Node 26 """ 27 return str(self.num) 28 29 def __eq__(self, other): 30 return self.__dict__ == other.__dict__ 31 32 def euclidean_dist(self, other): 33 """ 34 returns the Euclidean distance between this Node and other Node 35 other - other node 36 """ 37 dx = self.x - other.x 38 dy = self.y - other.y 39 return hypot(dx, dy) 40 41def parse_input_route(filename): 42 """ 43 returns initial route as read from input file, None if parsing errors occur 44 filename - name of the input file with '.tsp' extension 45 """ 46 f = open(filename, 'r') 47 route = [] 48 dimension = -1 49 dimension_found = False 50 node_section_found = False 51 52 # Parse header 53 for line in f: 54 if "DIMENSION" in line: 55 tokens = line.split() 56 dimension = int(tokens[-1]) 57 dimension_found = True 58 if "NODE_COORD_SECTION" in line: 59 node_section_found = True 60 break 61 62 # Check for parsing errors in header 63 if not dimension_found: 64 print("99 TSP - Parsing error: DIMENSION not found") 65 f.close() 66 return None 67 elif not node_section_found: 68 print("99 TSP - Parsing error: NODE_COORD_SECTION header not found") 69 f.close() 70 return None 71 72 # Parse nodes 73 for line in f: 74 if "EOF" in line: 75 break 76 coords = get_coords(line) 77 if not coords: 78 print("99 TSP - Parsing error: Invalid node data found") 79 f.close() 80 return None 81 route.append(Node(coords)) 82 f.close() 83 84 # Check for parsing error with nodes 85 if len(route) != dimension: 86 print("99 TSP - Parsing error: number of nodes found does not match dimension") 87 return None 88 89 return route 90 91def get_coords(line): 92 """ 93 returns the line data as numerals, None if line contains more than 94 3 items or non-numerics in the line 95 line - string containing the data 96 """ 97 data = line.split() 98 if len(data) == 3: 99 try: 100 coords = (int(data[0]), float(data[1]), float(data[2])) 101 return coords 102 except ValueError: 103 pass 104 return None 105 106def route_distance(route): 107 """ 108 returns the distance traveled for a given tour 109 route - sequence of nodes traveled, does not include 110 start node at the end of the route 111 """ 112 dist = 0 113 prev = route[-1] 114 for node in route: 115 dist += node.euclidean_dist(prev) 116 prev = node 117 return dist 118 119def swap_2opt(route, i, k): 120 """ 121 swaps the endpoints of two edges by reversing a section of nodes, 122 ideally to eliminate crossovers 123 returns the new route created with a the 2-opt swap 124 route - route to apply 2-opt 125 i - start index of the portion of the route to be reversed 126 k - index of last node in portion of route to be reversed 127 pre: 0 <= i < (len(route) - 1) and i < k < len(route) 128 post: length of the new route must match length of the given route 129 """ 130 assert i >= 0 and i < (len(route) - 1) 131 assert k > i and k < len(route) 132 new_route = route[0:i] 133 new_route.extend(reversed(route[i:k + 1])) 134 new_route.extend(route[k+1:]) 135 assert len(new_route) == len(route) 136 return new_route 137 138def run_2opt(route): 139 """ 140 improves an existing route using the 2-opt swap until no improved route is found 141 best path found will differ depending of the start node of the list of nodes 142 representing the input tour 143 returns the best path found 144 route - route to improve 145 """ 146 improvement = True 147 best_route = route 148 best_distance = route_distance(route) 149 while improvement: 150 improvement = False 151 for i in range(len(best_route) - 1): 152 for k in range(i+1, len(best_route)): 153 new_route = swap_2opt(best_route, i, k) 154 new_distance = route_distance(new_route) 155 if new_distance < best_distance: 156 best_distance = new_distance 157 best_route = new_route 158 improvement = True 159 break #improvement found, return to the top of the while loop 160 if improvement: 161 break 162 assert len(best_route) == len(route) 163 return best_route 164 165def print_results(route, filename, time, startnode): 166 """ 167 prints the nodes in the final route and route information 168 route - route to print 169 filename - name of the original input filename 170 time - time to run 2opt 171 startnode - start node of original tour if randomized 172 """ 173 for node in route: 174 print(node) 175 print(-1) 176 print("Original input file : " + filename) 177 print("Dimension : " + str(len(route))) 178 if startnode: 179 print("Randomized start node : " + str(startnode)) 180 print("Total Distance : " + str(route_distance(route))) 181 print("Time to run 2opt : %.2f seconds" % time) 182 183 184def main(): 185 # Check to make sure input file is given 186 if len(argv) == 1: 187 print("99 TSP - No input file") 188 return 189 # Check to make sure input file is correct type 190 elif ".tsp" != argv[1][-4:]: 191 print("99 TSP - Input file must contain \'.tsp\' extension") 192 return 193 194 # Terminate early if parsing errors are found 195 route = parse_input_route(argv[1]) 196 if not route: 197 return 198 199 # Option to randomize 'start' of route 200 r = None 201 if len(argv) == 3 and argv[2] == "-r": 202 r = randrange(0, len(route)) 203 new_route = route[r:] + route[0:r] 204 assert len(new_route) == len(route) 205 route = new_route 206 r = route[0] 207 208 # Run 2opt 209 start = default_timer() #start time of running 2opt 210 route = run_2opt(route) 211 end = default_timer() #end time of running 2opt 212 print_results(route, argv[1], (end - start), r) 213 214if __name__ == "__main__": 215 main()

問題

main関数内にあるrouteには,(0,10,5)のように,(インデックス番号,x値,y値)と入っているようです.これをfor文で回さずに,printすると
<tsp.twoopt.TSP2opt.Node object at 0x000002059967DF98>,
のように表示されるが,(0,10.5)のように表示することは可能でしょうか.

リンク内容

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

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

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

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

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

guest

回答2

0

ソース眺めただけで動作未検証ですが、routeNode型だとすると__str__が定義されているので
print(str(route))で何らかの数値(start position in a route's order)が出力されると思われます。
またはprint(route.num,route.x,route.y)にて簡易的にx,yも出力できるはずです。

投稿2018/12/04 07:37

can110

総合スコア38233

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

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

0

ベストアンサー

Nodeに__repr__メソッドを用意すれば良いです。
例えばこんな感じで。

Python

1class Node: 2 ... 3 4 def __repr__(self): 5 return f'({self.num}, {self.x}, {self.y})'

ただ、__str__メソッドが適切に実装されている以上、
for文で巡回して一つずつ出力していった方が行儀が良いようにも思います。

実験

Python

1class Spam: 2 def __str__(self): 3 return 'str' 4 5 def __repr__(self): 6 return 'repr' 7 8 9spams = [Spam(), Spam(), Spam()] 10print(spams) 11 12for spam in spams: 13 print(spam) 14 15 16# こういうのもアリ 17print(f'[{", ".join(map(str, spams))}]')

実行結果 Wandbox

[repr, repr, repr] str str str [str, str, str]

投稿2018/12/04 07:36

編集2018/12/04 07:44
LouiS0616

総合スコア35658

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

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

退会済みユーザー

退会済みユーザー

2018/12/04 09:40

早急に対応いただきありがとうございます! printでの表示はできました! もう1点不明点があるのですが,以下のようなコードを使用しmatplotlibで表示をすることは可能でしょうか.これは,TypeError: 'Node' object does not support indexingとエラーで出てしまいます x = [] y = [] for i in range(len(route)): x.append(route[0][i][0]) y.append(route[0][i][1]) # Figure内にAxesを追加() fig = plt.figure(figsize=(12, 8)) # ...1 # Figure内にAxesを追加() ax = fig.add_subplot(111) # ...2 ax.plot(data_x, data_y, 'o', label="test") # ...3 ax.plot(x, y, color='red', linestyle='solid') plt.show()
LouiS0616

2018/12/04 09:46

route[0][i][0]が何を示しているのか分からないので何とも言えません。
退会済みユーザー

退会済みユーザー

2018/12/04 10:10

申し訳ありません routeは(1,10,5)のような(インデックス番号,x値,y値)であり,printにより出力したかった<tsp.twoopt.TSP2opt.Node object at 0x000002059967DF98>の部分です. このrouteは[(1,10,5),(2,50,3),.....]のようになっており,x値をxのリストに,y値をyのリストにそれぞれ代入し,matplotlibで表示したいです.(表示させる部分はax.plot(x, y, color='red', linestyle='solid')です)
LouiS0616

2018/12/04 12:03

単に route[i].x じゃダメなのでしょうか。
退会済みユーザー

退会済みユーザー

2018/12/04 12:16

できました! ご丁寧にありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問