def supprime_croisement(chemin, taille_zone, X, Y): """supprime les croisements d'arêtes, retourne le nombre de changement effectués, X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur d'un côté du carré d'une zone""" nb = len(chemin) # zone associé à chaque arête zone = dessin_arete_zone(chemin, taille_zone, X, Y) nbtout = 0 for i in xrange(0, nb): im = (i + 1) % nb a = chemin[i] b = chemin[im] # zone traversée par la ligne x1, x2 = int(a[0] // taille_zone), int(b[0] // taille_zone) y1, y2 = int(a[1] // taille_zone), int(b[1] // taille_zone) ens = brl.trace_ligne(x1, y1, x2, y2) ville = [] for k, l in ens: voisin = voisinage_zone_xy(k, l, X, Y) for u, v in voisin: ville.extend(zone[u][v]) # on supprime les doubles ville.sort() if len(ville) == 0: continue sup = [] mx = -1 for v in ville: if v == mx: sup.append(v) mx = v for s in sup: ville.remove(s) nb_change = 0 for v in ville: b = retournement_essai(chemin, i, v) if b: nb_change += 1 continue b = retournement_essai(chemin, im, v) if b: nb_change += 1 continue nbtout += nb_change print "nombre de croisements %d longueur : \t %10.0f détail \t" \ % (nbtout, longueur_chemin (chemin)) return nbtout
def supprime_croisement (chemin, taille_zone, X,Y) : """supprime les croisements d'arêtes, retourne le nombre de changement effectués, X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur d'un côté du carré d'une zone""" nb = len(chemin) # zone associé à chaque arête zone = dessin_arete_zone (chemin, taille_zone, X, Y) nbtout = 0 for i in xrange (0,nb) : im = (i+1) % nb a = chemin [i] b = chemin [im] # zone traversée par la ligne x1,x2 = int (a [0] // taille_zone), int (b [0] // taille_zone) y1,y2 = int (a [1] // taille_zone), int (b [1] // taille_zone) ens = brl.trace_ligne (x1,y1,x2,y2) ville = [] for k,l in ens: voisin = voisinage_zone_xy (k,l,X,Y) for u,v in voisin : ville.extend (zone [u][v]) # on supprime les doubles ville.sort () if len (ville) == 0 : continue sup = [] mx = -1 for v in ville: if v == mx : sup.append (v) mx = v for s in sup: ville.remove (s) nb_change = 0 for v in ville : b = retournement_essai (chemin, i,v) if b : nb_change += 1 continue b = retournement_essai (chemin, im,v) if b : nb_change += 1 continue nbtout += nb_change print "nombre de croisements %d longueur : \t %10.0f détail \t" \ % (nbtout, longueur_chemin (chemin)) return nbtout
def dessin_arete_zone(chemin, taille_zone, X, Y): """retourne une liste de listes de listes, res [i][j] est une liste des arêtes passant près de la zone (x,y) = [i][j], si k in res [i][j], alors l'arête k,k+1 est dans la zone (i,j), X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur du côté du carré d'une zone""" res = [[[] for j in xrange(0, Y + 1)] for i in xrange(0, X + 1)] nb = len(chemin) for i in xrange(0, nb): a = chemin[i] b = chemin[(i + 1) % nb] x1, x2 = int(a[0] // taille_zone), int(b[0] // taille_zone) y1, y2 = int(a[1] // taille_zone), int(b[1] // taille_zone) line = brl.trace_ligne(x1, y1, x2, y2) for x, y in line: res[x][y].append(i) return res
def dessin_arete_zone (chemin, taille_zone, X,Y): """retourne une liste de listes de listes, res [i][j] est une liste des arêtes passant près de la zone (x,y) = [i][j], si k in res [i][j], alors l'arête k,k+1 est dans la zone (i,j), X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur du côté du carré d'une zone""" res = [ [ [] for j in xrange (0,Y+1) ] for i in xrange (0,X+1) ] nb = len (chemin) for i in xrange (0,nb): a = chemin [i] b = chemin [(i+1) % nb] x1,x2 = int (a [0] // taille_zone), int (b [0] // taille_zone) y1,y2 = int (a [1] // taille_zone), int (b [1] // taille_zone) line = brl.trace_ligne (x1,y1,x2,y2) for x,y in line: res [x][y].append (i) return res
def echange_position(chemin, taille, taille_zone, X, Y, grande=0.5): """regarde si on ne peut pas déplacer un segment de longueur taille pour supprimer les arêtes les plus longues, au maximum <grande> longues arêtes, retourne le nombre de changement effectués, X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur d'un côté du carré d'une zone""" nb = len(chemin) def tri_arete(x, y): """pour trier la liste l par ordre décroissant""" if x[2] < y[2]: return 1 elif x[2] > y[2]: return -1 else: return 0 # list des arêtes triés par ordre décroissant la = [] for i in xrange(0, nb): im = (i + 1) % nb la.append((i, im, distance(chemin[i], chemin[im]))) la.sort(tri_arete) # zone associé à chaque arête zone = dessin_arete_zone(chemin, taille_zone, X, Y) dseuil = la[int(nb * grande)][2] nbtout = 0 nb_change = 0 iarete = 0 retour = {} for t in xrange(1, taille + 1): retour[t] = 0 while iarete < nb: nb_change = 0 arete = la[iarete] iarete += 1 x = arete[0] xm = arete[1] a = chemin[x] b = chemin[xm] d = distance(a, b) if d < dseuil: break # arête trop petite # zone traversée par la ligne x1, x2 = int(a[0] // taille_zone), int(b[0] // taille_zone) y1, y2 = int(a[1] // taille_zone), int(b[1] // taille_zone) ens = brl.trace_ligne(x1, y1, x2, y2) ville = [] for k, l in ens: voisin = voisinage_zone_xy(k, l, X, Y) for u, v in voisin: ville.extend(zone[u][v]) # on supprime les doubles ville.sort() if len(ville) == 0: continue sup = [] mx = -1 for v in ville: if v == mx: sup.append(v) mx = v for s in sup: ville.remove(s) # on étudie les possibilités de casser l'arête (x,xm) aux alentours des villes # comprise dans l'ensemble ville for t in xrange(1, taille + 1): for i in ville: # on essaye d'insérer le sous-chemin (x- t + 1 + nb) --> x # au milieu de l'arête i,i+1 b = echange_position_essai(chemin, (x - t + 1 + nb) % nb, x, i, False) if b: nb_change += 1 retour[t] += 1 continue # on essaye d'insérer le sous-chemin (xm+ t - 1) --> xm # au milieu de l'arête i,i+1 b = echange_position_essai(chemin, (xm + t - 1) % nb, xm, i, False) if b: nb_change += 1 retour[t] += 1 continue # on essaye de casser l'arête x,xm en insérant # le sous-chemin i --> (i+t) % nb b = echange_position_essai(chemin, i, (i + t) % nb, x, False) if b: nb_change += 1 retour[t] += 1 continue # idem b = echange_position_essai(chemin, i, (i + t) % nb, x, True) if b: retour[t] += 1 nb_change += 1 continue # idem b = echange_position_essai(chemin, (i - t + nb) % nb, i, x, False) if b: nb_change += 1 retour[t] += 1 continue # idem b = echange_position_essai(chemin, (i - t + nb) % nb, i, x, True) if b: retour[t] += 1 nb_change += 1 continue nbtout += nb_change print "nombre de déplacements %d longueur : \t %10.0f détail \t" \ % (nbtout, longueur_chemin (chemin)), " détail : ", retour return nbtout
def echange_position (chemin, taille, taille_zone, X,Y, grande = 0.5) : """regarde si on ne peut pas déplacer un segment de longueur taille pour supprimer les arêtes les plus longues, au maximum <grande> longues arêtes, retourne le nombre de changement effectués, X est le nombre de zones horizontalement, Y est le nombre de zones verticalement, taille_zone est la longueur d'un côté du carré d'une zone""" nb = len(chemin) def tri_arete (x,y): """pour trier la liste l par ordre décroissant""" if x [2] < y [2] : return 1 elif x [2] > y [2] : return -1 else : return 0 # list des arêtes triés par ordre décroissant la = [] for i in xrange (0,nb) : im = (i+1) % nb la.append ( (i, im, distance (chemin [i], chemin [im]) ) ) la.sort (tri_arete) # zone associé à chaque arête zone = dessin_arete_zone (chemin, taille_zone, X, Y) dseuil = la [ int (nb * grande) ] [ 2 ] nbtout = 0 nb_change = 0 iarete = 0 retour = { } for t in xrange (1, taille+1): retour [t] = 0 while iarete < nb : nb_change = 0 arete = la [iarete] iarete += 1 x = arete [0] xm = arete [1] a = chemin [x] b = chemin [xm] d = distance ( a,b ) if d < dseuil : break # arête trop petite # zone traversée par la ligne x1,x2 = int (a [0] // taille_zone), int (b [0] // taille_zone) y1,y2 = int (a [1] // taille_zone), int (b [1] // taille_zone) ens = brl.trace_ligne (x1,y1,x2,y2) ville = [] for k,l in ens: voisin = voisinage_zone_xy (k,l,X,Y) for u,v in voisin : ville.extend (zone [u][v]) # on supprime les doubles ville.sort () if len (ville) == 0 : continue sup = [] mx = -1 for v in ville: if v == mx : sup.append (v) mx = v for s in sup: ville.remove (s) # on étudie les possibilités de casser l'arête (x,xm) aux alentours des villes # comprise dans l'ensemble ville for t in xrange (1, taille+1): for i in ville: # on essaye d'insérer le sous-chemin (x- t + 1 + nb) --> x # au milieu de l'arête i,i+1 b = echange_position_essai (chemin, (x- t + 1 + nb) % nb,x, i, False) if b : nb_change += 1 retour [t] += 1 continue # on essaye d'insérer le sous-chemin (xm+ t - 1) --> xm # au milieu de l'arête i,i+1 b = echange_position_essai (chemin, (xm + t - 1) % nb, xm, i, False) if b : nb_change += 1 retour [t] += 1 continue # on essaye de casser l'arête x,xm en insérant # le sous-chemin i --> (i+t) % nb b = echange_position_essai (chemin, i, (i+t) % nb, x, False) if b : nb_change += 1 retour [t] += 1 continue # idem b = echange_position_essai (chemin, i, (i+t) % nb, x, True) if b : retour [t] += 1 nb_change += 1 continue # idem b = echange_position_essai (chemin, (i-t+nb) % nb, i, x, False) if b : nb_change += 1 retour [t] += 1 continue # idem b = echange_position_essai (chemin, (i-t + nb) % nb, i, x, True) if b : retour [t] += 1 nb_change += 1 continue nbtout += nb_change print "nombre de déplacements %d longueur : \t %10.0f détail \t" \ % (nbtout, longueur_chemin (chemin)), " détail : ", retour return nbtout