@@ -46,7 +46,9 @@ def get_data(
4646 :param dest: répertoire dans lequel télécharger les données
4747 :param timeout: timeout (seconds) when estabishing the connection
4848 :param verbose: affiche le progrès
49- :param keep: garde tout si la valeur est -1, sinon garde les 1000 premières rues
49+ :param keep: garde tout si la valeur est -1,
50+ sinon garde les 1000 premières rues, ces rues sont choisies
51+ de façon à construire un ensemble connexe
5052 :return: liste d'arcs
5153
5254 Un arc est défini par un 6-uple contenant les informations suivantes :
@@ -88,22 +90,38 @@ def get_data(
8890 pairs [p ] = True
8991
9092 if keep is not None :
91- short_edges = edges [:keep ]
9293 new_vertices = {}
93- edges = []
94- for edge in short_edges :
95- p1 , p2 = edge [- 3 :- 1 ]
96- if p1 not in new_vertices :
97- new_vertices [p1 ] = len (new_vertices )
98- if p2 not in new_vertices :
99- new_vertices [p2 ] = len (new_vertices )
100- i1 , i2 = new_vertices [p1 ], new_vertices [p2 ]
101- edges .append ((i1 , i2 , edge [2 ], p1 , p2 , edge [- 1 ]))
94+ already_added = set ()
95+ new_edges = []
96+ for _ in range (0 , int (keep ** 0.5 ) + 1 ):
97+ for edge in edges :
98+ if edge [:2 ] in already_added :
99+ continue
100+ p1 , p2 = edge [- 3 :- 1 ]
101+ if (
102+ len (new_vertices ) > 0
103+ and p1 not in new_vertices
104+ and p2 not in new_vertices
105+ ):
106+ # On considère des rues connectées à des rues déjà sélectionnées.
107+ continue
108+ if p1 not in new_vertices :
109+ new_vertices [p1 ] = len (new_vertices )
110+ if p2 not in new_vertices :
111+ new_vertices [p2 ] = len (new_vertices )
112+ i1 , i2 = new_vertices [p1 ], new_vertices [p2 ]
113+ new_edges .append ((i1 , i2 , edge [2 ], p1 , p2 , edge [- 1 ]))
114+ already_added .add (edge [:2 ])
115+ if len (new_edges ) >= keep :
116+ break
117+ if len (new_edges ) >= keep :
118+ break
102119 items = [(v , i ) for i , v in new_vertices .items ()]
103120 items .sort ()
104121 vertices = [_ [1 ] for _ in items ]
122+ edges = new_edges
105123
106- return edges
124+ return edges , vertices
107125
108126
109127def graph_degree (
@@ -321,7 +339,7 @@ def eulerien_extension(
321339 totali = 0
322340 while len (allow ) > 0 :
323341 if verbose :
324- print (f"------- nb odd vertices { len (allow )} iteration { totali } " )
342+ print (f"------- # odd vertices { len (allow )} iteration { totali } " )
325343 allowset = set (allow )
326344 init = bellman (
327345 edges ,
@@ -384,9 +402,9 @@ def euler_path(
384402 edges_from = {}
385403 somme = 0
386404 for e in edges :
387- k = e [:2 ]
388- v = e [- 1 ]
389- alledges [k ] = ["street" ] + list ( k + ( v ,))
405+ k = e [:2 ] # indices des noeuds
406+ v = e [- 1 ] # distance
407+ alledges [k ] = ["street" , * k , v ]
390408 a , b = k
391409 alledges [b , a ] = alledges [a , b ]
392410 if a not in edges_from :
@@ -398,10 +416,10 @@ def euler_path(
398416 somme += v
399417
400418 for e in added_edges : # il ne faut pas enlever les doublons
401- k = e [:2 ]
402- v = e [- 1 ]
419+ k = e [:2 ] # indices ds noeuds
420+ v = e [- 1 ] # distance
403421 a , b = k
404- alledges [k ] = ["jump" ] + list ( k + ( v ,))
422+ alledges [k ] = ["jump" , * k , v ]
405423 alledges [b , a ] = alledges [a , b ]
406424 if a not in edges_from :
407425 edges_from [a ] = []
@@ -411,39 +429,43 @@ def euler_path(
411429 edges_from [b ].append (alledges [a , b ])
412430 somme += v
413431
414- degre = {}
415- for a , v in edges_from .items ():
416- t = len (v )
417- degre [t ] = degre .get (t , 0 ) + 1
418-
419- two = [a for a , v in edges_from .items () if len (v ) == 2 ]
432+ # les noeuds de degré impair
420433 odd = [a for a , v in edges_from .items () if len (v ) % 2 == 1 ]
421434 if len (odd ) > 0 :
422- raise ValueError ("some vertices have an odd degree" )
435+ raise ValueError ("Some vertices have an odd degree." )
436+ # les noeuds de degré 2, on les traverse qu'une fois
437+ two = [a for a , v in edges_from .items () if len (v ) == 2 ]
423438 begin = two [0 ]
424439
425440 # checking
426441 for v , le in edges_from .items ():
442+ # v est une extrémité
427443 for e in le :
444+ # to est l'autre extrémité
428445 to = e [1 ] if v != e [1 ] else e [2 ]
429446 if to not in edges_from :
430- raise RuntimeError (
431- "unable to find vertex {0} for edge {0},{1}" .format (to , v )
432- )
447+ raise RuntimeError (f"Unable to find vertex { to } for edge { to } ,{ v } " )
433448 if to == v :
434- raise RuntimeError (f"circular edge { to } " )
449+ raise RuntimeError (f"Circular edge { to } " )
435450
436- # loop
451+ # On sait qu'il existe un chemin. La fonction explore les arcs
452+ # jusqu'à revenir à son point de départ. Elle supprime les arcs
453+ # utilisées de edges_from.
437454 path = _explore_path (edges_from , begin )
438- for p in path :
439- if len (p ) == 0 :
440- raise RuntimeError ("this exception should not happen" )
455+
456+ # Il faut s'assurer que le chemin ne contient pas de boucles non visitées.
441457 while len (edges_from ) > 0 :
458+ # Il reste des arcs non visités. On cherche le premier
459+ # arc connecté au chemin existant.
442460 start = None
443461 for i , p in enumerate (path ):
444462 if p [0 ] in edges_from :
445463 start = i , p
446464 break
465+ if start is None :
466+ raise RuntimeError (
467+ f"start should not be None\n path={ path } \n edges_from={ edges_from } "
468+ )
447469 sub = _explore_path (edges_from , start [1 ][0 ])
448470 i = start [0 ]
449471 path [i : i + 1 ] = path [i : i + 1 ] + sub
0 commit comments