IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

A propos d'algorithmes glouton et d'un voyageur de commerce. A l'aide svp


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2023
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 18
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2023
    Messages : 1
    Par défaut A propos d'algorithmes glouton et d'un voyageur de commerce. A l'aide svp
    Bonjour à tous,

    Je tente d'écrire un programme permettant de résoudre le fameux problème du voyageur de commerce par la méthode gloutonne.
    La solution gloutonne donne une distance de 810 km mais en sollicitant mon programme, j'obtiens 503 km...
    Une erreur doit se nicher au niveau d'une boucle j'imagine mais impossible de mettre le doigt dessus ...

    Pourriez-vous jeter un coup d'oeil à mon bout de code s'il vous plait ?
    Je vous remercie pour votre aide,
    Excellente journée !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
     
    villes = [1,2,3,4,5]
     
    dist = [[0  , 55  , 303 , 188 , 183],
            [55 , 0   , 306 , 176 , 203],
            [303, 306 , 0   , 142 , 155],
            [188, 176 , 142 , 0   , 123],
            [183, 203 , 153 , 123 , 0    ]]
     
    n=len(villes)
     
    def circuit_glouton(villes, dist, depart):
     
        visitees=[False]*n
        distance_total = 0
        courante=depart
     
        for i in range (n-1):
            visitees[courante] = True
            suivante=plus_proche(courante,dist, visitees)
            distance_total += cumul_etapes(courante, suivante,  dist)
            courante = suivante
        distance_total += cumul_etapes(courante, suivante,  dist)
        print (' la distance totale est de :', distance_total)
     
    def plus_proche(villes, dist, visitees):
        pp= None
        for i in range(len(visitees)):
            if not visitees[i]:
                if pp == None or dist[villes][i] < dist[villes][pp]:
                    pp = i
        return pp
     
    def cumul_etapes (courante,suivante,dist):
        distance =dist[courante][suivante]
        print (" il faut aller de", villes[courante], "à", villes[suivante],'en',distance, "km")
        return distance
     
    print(circuit_glouton(1,dist,villes[0]))

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 752
    Par défaut
    Salut,

    Citation Envoyé par William06 Voir le message
    Une erreur doit se nicher au niveau d'une boucle j'imagine mais impossible de mettre le doigt dessus ...
    Il y a assez peu de villes pour que la vérification du résultat "à la main" soit rapide et facile.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 837
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 837
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par William06 Voir le message
    La solution gloutonne donne une distance de 810 km mais en sollicitant mon programme, j'obtiens 503 km...
    Vu que ton programme donne une solution cohérente, qui passe effectivement par toutes les villes, et dont le total des distances fait effectivement 503km, je ne vois pas comment tu peux dire que "la" solution est de 810km.
    Citation Envoyé par William06 Voir le message
    if pp == None
    On ne compare pas "None" via l'égalité mais via "is" => if pp is None => https://peps.python.org/pep-0008/#pr...ecommendations

    [edit]j'ai compris d'où sort le 810. Il sort de l'algorithme "simpliste" => prendre le minimum de ce qui est proposé
    • A la ville 1, le minimum c'est 55 pour la ville 2 (total 55)
    • A la ville 2, le minimum c'est 176 pour la ville 4 (total 231)
    • A la ville 4, le minimum c'est 123 pour la ville 5 (total 354)
    • A la ville 5, le minimum c'est 153 pour la ville 3 (total 507)
    • Et à la ville 3, le retour à la ville 1 fait 303 (total 810)

    Toutefois la différence entre cet algo et le tien c'est que cet algo part de la ville 1 (le tien part de la ville 2) et qu'il retourne à la ville d'origine (le tien se termine à la dernière ville sans boucler). Donc tu as ta réponse sur le pourquoi de la différence.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 236
    Par défaut
    Hello,
    il y a un truc de louche dans ton code :
    c'est que l'appel de la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    circuit_glouton(1,dist,villes[0])
    ne correspond pas à la définition de la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    def circuit_glouton(villes, dist, depart)
    villes n'est pas utilisée dans ta fonction.

    Ami calmant, J.P

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 837
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 837
    Billets dans le blog
    1
    Par défaut
    Je crois qu'il y a un autre souci: la numérotation des villes va de 1 à 5. Mais dans un tableau, la numérotation commence à 0.
    Fatalement ville[1] présumé taper dans la première ville (et qu'on voit dans dist[villes][i] < dist[villes][pp]) tape en réalité dans la seconde. C'est pour ça que son résultat part de la ville 2.
    Si on renumérote les villes correctement (de 0 à 4) on obtient le parcours que j'ai cité en 507 km qui, si on le fait reboucler sur la ville de départ, fait alors 810km.
    Et (accessoirement) si on commence réellement par la ville 2, alors le voyage n'en fait plus que 809.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 752
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Je crois qu'il y a un autre souci: la numérotation des villes va de 1 à 5. Mais dans un tableau, la numérotation commence à 0.
    Certes mais ce numéro va dans villes qui n'est pas utilisé.

    Si la question est pourquoi on ne trouve pas 810 kms, le soucis est que la ligne 24 est un copie/coller de la ligne 22:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
           distance_total += cumul_etapes(courante, suivante,  dist)
    A la sortie de la boucle, courante == suivante et ça ajoute 0.

    On devrait (à la place) ajouter la distance entre courante/suivante et départ.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 236
    Par défaut
    Hello,
    finalement, en prenant en compte les remarques à Sve@r et Wiztricks , on obtient bien 810 avec ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    villes = ['ville1','ville2','ville3','ville4','ville5']
     
    dist = [[0  , 55  , 303 , 188 , 183],
            [55 , 0   , 306 , 176 , 203],
            [303, 306 , 0   , 142 , 155],
            [188, 176 , 142 , 0   , 123],
            [183, 203 , 153 , 123 , 0    ]]
     
    n=len(villes)
     
    def circuit_glouton(depart):
     
        visitees=[False]*n
        distance_total = 0
        courante=depart
     
        for i in range (n-1):
            visitees[courante] = True
            suivante=plus_proche(courante,dist, visitees)
            distance_total += cumul_etapes(courante, suivante,  dist)
            courante = suivante
        distance_total += cumul_etapes(courante, depart,  dist)
        print (' la distance totale est de :', distance_total)
     
    def plus_proche(villes, dist, visitees):
        pp= None
        for i in range(len(visitees)):
            if not visitees[i]:
                if pp is None or dist[villes][i] < dist[villes][pp]:
                    pp = i
        return pp
     
    def cumul_etapes (courante,suivante,dist):
        distance =dist[courante][suivante]
        print (" il faut aller de", villes[courante], "à", villes[suivante],'en',distance, "km")
        return distance
     
    circuit_glouton(0)
    Remarques :
    1 - circuit_glouton n'a plus qu'un paramètre qui est l'indice de la ville de départ ( indice qui commence à 0). je me suis aperçu que les autres paramètres ne servaient pas car les fonctions prenaient en compte les variables définies au début du programme. D'ailleurs qui peut m'expliquer le pourquoi car je croyais qu'il fallait définir les variables en global pour avoir ce type de comportement (à noter que ces variables ne sont pas modifiées dans les fonctions). Le test a été effectué en python 3.10.
    2 - j'ai remplacé les villes par des noms.
    3 - Le print de la dernière ligne ne servait à rien et retournait None. Les print sont faits dans les fonctions
    Voici le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     il faut aller de ville1 à ville2 en 55 km
     il faut aller de ville2 à ville4 en 176 km
     il faut aller de ville4 à ville5 en 123 km
     il faut aller de ville5 à ville3 en 153 km
     il faut aller de ville3 à ville1 en 303 km
     la distance totale est de : 810
    Ami calmant, J.P

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 837
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 837
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Certes mais ce numéro va dans villes qui n'est pas utilisé.
    Ca reste quand-même un bug (suffit de remplacer par villes = [5, 1, 2, 3, 4] et on voit l'IndexError sortir)

    Citation Envoyé par jurassic pork Voir le message
    D'ailleurs qui peut m'expliquer le pourquoi car je croyais qu'il fallait définir les variables en global pour avoir ce type de comportement
    Toute variable définie dans le scope global (hors de toute fonction) est implicitement connue des fonctions appelées après (mêmes si définies avant), mais en lecture seule.
    L'instruction global var dans la fonction sert juste à rendre la variable "var" modifiable par la fonction (et c'est souvent pas une bonne idée)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 752
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ca reste quand-même un bug (suffit de remplacer par villes = [5, 1, 2, 3, 4] et on voit l'IndexError sortir)
    Certes mais je me limite à la question posée... et à (essayer de) donner des pistes au PO pour trouver tout seul.
    Ecrire plus proprement un code assez classique dont on trouve déjà plusieurs variantes sur Internet a (pour moi) un intérêt limité.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Algorithme génétique et probleme de voyageur de commerce avec graphe non complet
    Par marmarnassouf dans le forum Intelligence artificielle
    Réponses: 2
    Dernier message: 30/04/2009, 16h51
  2. Réponses: 2
    Dernier message: 03/02/2009, 20h21
  3. [Tutoriel] Application d'un algorithme génétique au problème du voyageur de commerce
    Par Malick dans le forum Algorithmes et structures de données
    Réponses: 0
    Dernier message: 25/06/2008, 12h00
  4. A propos des algorithmes de tri..
    Par Kerwando dans le forum C++
    Réponses: 4
    Dernier message: 19/08/2006, 11h43
  5. [Lisp] Algorithme glouton
    Par TomCat1664 dans le forum Lisp
    Réponses: 2
    Dernier message: 04/01/2005, 12h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo