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

C# Discussion :

modification du code


Sujet :

C#

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
    Janvier 2013
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Janvier 2013
    Messages : 1
    Par défaut modification du code
    Bonjour la communauté,
    je ne sais pas si je suis sur le bon forum! mais si c'est le cas bien vouloir me réorienter svp!!

    Je suis étudiant en Sécurité-Réseau-Système, et j'ai dans mon programme un cours appelé Recherche Opérationnelle et Intelligence Artificielle (gros nomm!!!!) bref!! j'ai un programme sur lequel je bosse et j'ai le code( car fourni par le prof) avec un détail selon lequel il faudrait modifier manuellement une variable pour appliquer voir le comportement des algo tels que le "recherche local naive" "recuit simulé" "algo génétique" sur 6 problèmes différents.

    Etant donné que je ne suis pas un ange du code, j'aimerai savoir s'il est possible de modifier le code de tel sorte qu'il y'ait un compteur et que je n'ai plus à faire varier les valeurs manuellement dans le mainscript voir ligne rouge !!

    Merci
    Voici le code:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System;

    /// <summary>
    /// Classe principale à utiliser pour implémenter vos algorithmes
    /// Si vous souhaitez utiliser plusieurs scripts (1 par algorithme),
    /// vous le pouvez aussi.
    /// </summary>
    public class MainScript : MonoBehaviour
    {

    /// <summary>
    /// Indique si un algorithme est en cours d'exécution
    /// </summary>
    private bool _isRunning = false;

    /// <summary>
    /// Indique si une evaluation de solution est en cours
    /// </summary>
    private bool _inSimulation = false;

    /// <summary>
    /// Méthode utilisée pour gérer les informations et
    /// boutons de l'interface utilisateur
    /// </summary>
    public void OnGUI()
    {
    // Démarrage d'une liste de composants visuels verticale
    GUILayout.BeginVertical();

    // Affiche un bouton permettant le lancement de la recherche locale naïve
    if (GUILayout.Button("DEMARRAGE RECHERCHE LOCALE NAIVE"))
    {
    // Le bouton est inactif si un algorithme est en cours d'exécution
    if (!_isRunning)
    {
    // Démarrage de la recherche locale naïve en pseudo asynchrone
    StartCoroutine("NaiveLocalSearch");
    }
    }

    // Affiche un bouton permettant le lancement de la recherche locale naïve
    if (GUILayout.Button("DEMARRAGE RECUIT SIMULE"))
    {
    // Le bouton est inactif si un algorithme est en cours d'exécution
    if (!_isRunning)
    {
    // Démarrage du recuit simulé en pseudo asynchrone
    StartCoroutine("SimulatedAnnealing");
    }
    }

    // Affiche un bouton permettant le lancement de l'algorithme génétique
    if (GUILayout.Button("DEMARRAGE ALGORITHME GENETIQUE"))
    {
    // Le bouton est inactif si un algorithme est en cours d'exécution
    if (!_isRunning)
    {
    // Démarrage de l'algorithme génétique en pseudo asynchrone
    StartCoroutine("GeneticAlgorithm");
    }
    }

    // Affiche un bouton permettant le lancement de l'algorithme de Djikstra
    if (GUILayout.Button("DEMARRAGE DJIKSTRA"))
    {
    // Le bouton est inactif si un algorithme est en cours d'exécution
    if (!_isRunning)
    {
    // Démarrage de l'algorithme de Djikstra en pseudo asynchrone
    StartCoroutine("Djikstra");
    }
    }

    // Affiche un bouton permettant le lancement de l'algorithme A*
    if (GUILayout.Button("DEMARRAGE A*"))
    {
    // Le bouton est inactif si un algorithme est en cours d'exécution
    if (!_isRunning)
    {
    // Démarrage de l'algorithme A* en pseudo asynchrone
    StartCoroutine("AStar");
    }
    }

    // Fin de la liste de composants visuels verticale
    GUILayout.EndVertical();
    }

    /// <summary>
    /// Initialisation du script
    /// </summary>
    void Start()
    {
    // Pour faire en sorte que l'algorithme puisse continuer d'être actif même
    // en tâche de fond.
    Application.runInBackground = true;
    }

    /// <summary>
    /// Implémentation possible de la recherche locale naïve
    /// sous forme de coroutine pour le mode pseudo asynchone
    /// </summary>
    /// <returns></returns>
    public IEnumerator NaiveLocalSearch()
    {
    // Indique que l'algorithme est en cours d'exécution
    _isRunning = true;

    // Génère une solution initiale au hazard (ici une séquence
    // de 42 mouvements)
    var currentSolution = new PathSolutionScript(42);

    // Récupère le score de la solution initiale
    // Sachant que l'évaluation peut nécessiter une
    // simulation, pour pouvoir la visualiser nous
    // avons recours à une coroutine
    var scoreEnumerator = GetError(currentSolution);
    yield return StartCoroutine(scoreEnumerator);
    float currentError = scoreEnumerator.Current;

    // Nous récupérons l'erreur minimum atteignable
    // Ceci est optionnel et dépendant de la fonction
    // d'erreur
    var minimumError = GetMinError();

    // Affichage de l'erreur initiale
    Debug.Log(currentError);

    // Initialisation du nombre d'itérations
    int iterations = 0;

    // Tout pendant que l'erreur minimale n'est pas atteinte
    while (currentError != GetMinError())
    {
    // On obtient une copie de la solution courante
    // pour ne pas la modifier dans le cas ou la modification
    // ne soit pas conservée.
    var newsolution = CopySolution(currentSolution);

    // On procède à une petite modification de la solution
    // courante.
    RandomChangeInSolution(newsolution);

    // Récupère le score de la nouvelle solution
    // Sachant que l'évaluation peut nécessiter une
    // simulation, pour pouvoir la visualiser nous
    // avons recours à une coroutine
    var newscoreEnumerator = GetError(newsolution);
    yield return StartCoroutine(newscoreEnumerator);
    float newError = newscoreEnumerator.Current;

    // On affiche pour des raisons de Debug et de suivi
    // la comparaison entre l'erreur courante et la
    // nouvelle erreur
    Debug.Log(currentError + " - " + newError);

    // Si la solution a été améliorée
    if (newError <= currentError)
    {
    // On met à jour la solution courante
    currentSolution = newsolution;

    // On met à jour l'erreur courante
    currentError = newError;
    }

    // On incrémente le nombre d'itérations
    iterations++;

    // On rend la main au moteur Unity3D
    yield return 0;
    }

    // Fin de l'algorithme, on indique que son exécution est stoppée
    _isRunning = false;

    // On affiche le nombre d'itérations nécessaire à l'algorithme pour trouver la solution
    Debug.Log("CONGRATULATIONS !!! Solution Found in " + iterations + " iterations !");
    }

    // Coroutine à utiliser pour implémenter l'algorithme de Djikstra
    public IEnumerator Djikstra()
    {
    var matrix = MatrixFromRaycast.CreateMatrixFromRayCast();


    //TODO
    yield return null;
    }

    // Coroutine à utiliser pour implémenter l'algorithme d' A*
    public IEnumerator AStar()
    {
    //TODO
    yield return null;
    }

    // Coroutine à utiliser pour implémenter l'algorithme du recuit simulé
    public IEnumerator SimulatedAnnealing()
    {
    DateTime start = DateTime.Now;

    // Génère une solution initiale au hazard (ici une séquence
    // de 42 mouvements)
    var currentSolution = new PathSolutionScript(12);

    // Récupère le score de la solution initiale
    // Sachant que l'évaluation peut nécessiter une
    // simulation, pour pouvoir la visualiser nous
    // avons recours à une coroutine
    var scoreEnumerator = GetError(currentSolution);
    yield return StartCoroutine(scoreEnumerator);
    float currentError = scoreEnumerator.Current;

    ///Initialisation de la température à une valeur 'plutot basse'.
    float temperature = 2f;

    // Nous récupérons l'erreur minimum atteignable
    // Ceci est optionnel et dépendant de la fonction
    // d'erreur
    float minimumError = GetMinError();

    // Affichage de l'erreur initiale
    Debug.Log("Erreur initiale : " + currentError);
    // Affichage de l'erreur initiale
    Debug.Log("Min erreur : " + minimumError);

    ///Initialisation de la valeur de 'stagnation' qui si elle dépasse un
    ///certain seuil provoquera l'augmentation de la température.
    float stagnation = 0.001f;

    // Initialisation du nombre d'itérations
    int iterations = 0;

    ///Tout pendant que l'erreur n'est pas nulle
    while (currentError != minimumError /*GetMinError()*/)
    {
    // On obtient une copie de la solution courante
    // pour ne pas la modifier dans le cas ou la modification
    // ne soit pas conservée.
    var newsolution = CopySolution(currentSolution);

    // On procède à une petite modification de la solution
    // courante.
    RandomChangeInSolution(newsolution);

    // Récupère le score de la nouvelle solution
    // Sachant que l'évaluation peut nécessiter une
    // simulation, pour pouvoir la visualiser nous
    // avons recours à une coroutine
    var newscoreEnumerator = GetError(newsolution);
    yield return StartCoroutine(newscoreEnumerator);
    float newError = newscoreEnumerator.Current;

    // On affiche pour des raisons de Debug et de suivi
    // la comparaison entre l'erreur courante et la
    // nouvelle erreur
    Debug.Log("currentError : " + currentError + " - newError : " + newError + " - minError : " + GetMinError());

    ///Tirage d'un nombre aléatoire entre 0f et 1f.
    float rdm = UnityEngine.Random.Range(0f, 1f);

    ///Comparaison de ce nombre à la probabilité d'accepter un changement
    ///déterminée par le critère de Boltzman.
    if (rdm < BoltzmanCriteria(temperature, currentError, newError))
    {
    // On met à jour la solution courante
    currentSolution = newsolution;

    // On met à jour l'erreur courante
    currentError = newError;
    }

    ///Si l'erreur stagne
    if (minimumError == currentError)
    {
    ///On incrémente la stagnation
    stagnation *= 1.001f;
    }
    else
    {
    ///Sinon on la réinitialise
    stagnation = 0.001f;
    }

    ///Si l'erreur diminue en deça de la meilleure erreur obtenue
    if (currentError < minimumError)
    {
    ///On met à jour la meilleure erreur obtenue
    minimumError = currentError;

    ///On réinitialise la stagnation
    stagnation = 0.001f;
    }

    ///On met à jour la temperature à chaque tour de boucle :
    /// - si la stagnation est suffisante la temperature va augmenter
    /// - sinon la temperature décroit de manière géométrique
    temperature *= 0.998f + stagnation;

    ///Affichage dans la console de Debug du couple temperature stagnation
    ///pour pouvoir être témoin de l'augmentation de la température lorsque
    ///l'on se retrouve coincé trop longtemps dans un minimum local.
    Debug.Log("Temperature : " + temperature + " - stagnation : " + stagnation);

    // On incrémente le nombre d'itérations
    iterations++;

    // On rend la main au moteur Unity3D
    yield return 0;
    }

    // Fin de l'algorithme, on indique que son exécution est stoppée
    _isRunning = false;

    TimeSpan dur = DateTime.Now - start;

    // On affiche le nombre d'itérations nécessaire à l'algorithme pour trouver la solution
    Debug.Log("CONGRATULATIONS !!! Solution Found in " + iterations + " iterations in" + dur.TotalSeconds + " secondes !");
    }

    /// <summary>
    /// Proposition d'implémentation du critère de Bolztman représentant une
    /// fonction seuil, renvoyant la probabilité d'accepter une permutation
    /// selon la différence entre l'erreur courante et la nouvelle erreur et
    /// ainsi qu'en fonction de la temperature courante.
    /// </summary>
    /// <param name="temperature"></param>
    /// <param name="currentError"></param>
    /// <param name="newError"></param>
    /// <returns></returns>
    float BoltzmanCriteria(float temperature, float currentError, float newError)
    {
    ///Si la temperature est nulle
    ///cas particulier pour éviter une division par zéro
    if (temperature == 0)
    {
    return currentError - newError;
    }

    ///Critère de Boltzman
    return Mathf.Exp(((float)(currentError - newError)) / temperature);
    }

    class ScoredPathIndividual
    {
    /// <summary>
    /// La configuration des chemins (solution)
    /// </summary>
    public PathSolutionScript pathSolution { get; set; }

    /// <summary>
    /// L'erreur de la configuration ci-dessus
    /// </summary>
    public float error { get; set; }
    }

    // Coroutine à utiliser pour implémenter un algorithme génétique
    public IEnumerator GeneticAlgorithm()
    {
    #region Paramètres

    int iteration = 0;

    ///La taille de la population
    int popsize = 50;

    ///Le nombre d'individus séléctionnés pour la reproduction
    ///(ici 40% de la taille de la population)
    int numSelection = (int)(popsize * 0.4f);

    ///Le taux de mutation (c.à.d. la chance avec laquelle un
    ///individu issu du croisement peut subir une mutation)
    float mutationRate = 0.4f;
    #endregion

    #region Initialisation de la population

    ///Initialisation du tableau contenant notre population initiale
    PathSolutionScript[] population = new PathSolutionScript[popsize];

    ///Pour chaque individu que l'on doit créer dans la population initiale
    for (int j = 0; j < popsize; j++)
    {
    population[j] = new PathSolutionScript(42);
    }

    float bestError = 1000;

    #endregion

    ///Tout pendant que la configuration optimale n'est pas trouvée
    while (bestError != GetMinError())
    {
    #region Evaluation de la population

    ///Initialisation du tableau destiné à contenir l'ensemble des
    ///couples chemin/erreur une fois la population évaluée
    var scoredPathIndividuals = new ScoredPathIndividual[popsize];

    ///Pour chaque individu de notre population à évaluer
    for (int i = 0; i < population.Length; i++)
    {
    var newscoreEnumerator = GetError(population[i]);

    yield return StartCoroutine(newscoreEnumerator);
    float newError = newscoreEnumerator.Current;

    ///Création d'un couple configuration/solution et stockage
    ///du score obtenu pour la configuration évaluée.
    scoredPathIndividuals[i] = new ScoredPathIndividual()
    {
    pathSolution = population[i],
    error = newError
    };
    }

    #endregion

    #region Selection des reproducteurs

    ///Récupération de manière concise (grâce à Linq) des reproducteurs :
    /// - Tri de l'ensemble des couples configuration/score par ordre
    /// croissant de score.
    /// - Récupération des meilleurs couples.
    /// - Récupération des meilleurs configurations.
    /// - Stockage des meilleures configurations dans un tableau
    var bestPathSolution = scoredPathIndividuals
    .OrderBy((scoredIn) => scoredIn.error)
    .Take(numSelection)
    .Select((scoredIn) => scoredIn.pathSolution)
    .ToArray();

    bestError = scoredPathIndividuals
    .OrderBy((scoredIn) => scoredIn.error)
    .Select((scoredIn) => scoredIn.error).First();

    #endregion

    #region Affichage du meilleur individu

    ///Affichage Dans la console de Debug du score du meilleur
    ///individu.
    Debug.Log("Meilleur Score de la génération courante : " + bestError);

    #endregion

    #region Croisement de la population

    ///Initialisation de la nouvelle population qui va être générée
    ///par croisement.
    PathSolutionScript[] newpopulation = new PathSolutionScript[popsize];

    ///Pour chaque enfant que l'on doit générer par croisement
    for (int i = 0; i < popsize; i++)
    {
    ///Récupération de deux reproduteurs au hasard
    var parent1 = bestPathSolution[UnityEngine.Random.Range(0, bestPathSolution.Length)];
    var parent2 = bestPathSolution[UnityEngine.Random.Range(0, bestPathSolution.Length)];

    ///Création d'un individu à partir du croisement des deux parents
    newpopulation[i] = Crossover(parent1, parent2);
    }

    #endregion

    #region Mutation de la population

    ///Pour chaque individu de la population
    for (int i = 0; i < popsize; i++)
    {
    ///Tirage d'un nombre au hasard entre 0f et 1f
    float rdm = UnityEngine.Random.Range(0f, 1f);

    ///Comparaison de ce nombre au taux de mutation
    ///S'il est inférieur, on procède à la mutation
    if (rdm < mutationRate)
    {
    ///Mutation proposée :
    // On procède à une petite modification de la solution
    // courante.
    RandomChangeInSolution(newpopulation[i]);
    }
    }

    #endregion

    ///Remplacement de l'ancienne population par la nouvelle
    population = newpopulation;

    iteration++;

    // On rend la main au moteur Unity3D
    yield return 0;
    }

    // Fin de l'algorithme, on indique que son exécution est stoppée
    _isRunning = false;

    // On affiche le nombre d'itérations nécessaire à l'algorithme pour trouver la solution
    Debug.Log("CONGRATULATIONS !!! Solution Found in " + iteration + " iterations !");
    }

    /// <summary>
    /// Méthode proposant une méthode pour obtenir une nouvel
    /// individu par croisement de deux configurations parentes
    /// </summary>
    /// <param name="parent1">Le parent 1</param>
    /// <param name="parent2">Le parent 2</param>
    /// <returns>L'enfant généré par croisement</returns>
    PathSolutionScript Crossover(PathSolutionScript parent1, PathSolutionScript parent2)
    {
    PathSolutionScript child = new PathSolutionScript(42);
    for (int i = 0; i < parent1.Actions.Count(); i++)
    {
    if(i%2 != 0)child.Actions[i].Action = parent1.Actions[i].Action;
    else child.Actions[i].Action = parent2.Actions[i].Action;
    }
    return child;
    }


    /// <summary>
    /// Exemple d'erreur minimum (pas forcément toujours juste) renvoyant
    /// la distance de manhattan entre la case d'arrivée et la case de départ.
    /// </summary>
    /// <returns></returns>
    // int GetMinError()
    // {
    // return (int)(Mathf.Abs(PlayerScript.GoalXPositionInMatrix - PlayerScript.StartXPositionInMatrix) +
    // Mathf.Abs(PlayerScript.GoalYPositionInMatrix - PlayerScript.StartYPositionInMatrix));
    // }

    /// Eemple d'erreur minimum, utilisation de la position de départ et de la position d'arrivé

    int GetMinError()
    {
    return (int)(Mathf.Abs(PlayerScript.StartXPositionInMatrix - PlayerScript.GoalXPositionInMatrix) +
    Mathf.Abs(PlayerScript.StartYPositionInMatrix - PlayerScript.GoalYPositionInMatrix));
    }

    /// <summary>
    /// Exemple d'oracle nous renvoyant un score que l'on essaye de minimiser
    /// Ici est utilisé la position de la case d'arrivée, la position finale
    /// atteinte par la solution. Il est recommandé d'essayer plusieurs oracles
    /// pour étudier le comportement des algorithmes selon la qualité de ces
    /// derniers
    ///
    /// Parmi les paramètres pouvant être utilisés pour calculer le score/erreur :
    ///
    /// - position de la case d'arrivée : PlayerScript.GoalXPositionInMatrix
    /// PlayerScript.GoalYPositionInMatrix
    /// - position du joueur : player.PlayerXPositionInMatrix
    /// player.PlayerYPositionInMatrix
    /// - position de départ du joueur : PlayerScript.StartXPositionInMatrix
    /// PlayerScript.StartYPositionInMatrix
    /// - nombre de cases explorées : player.ExploredPuts
    /// - nombre d'actions exécutées : player.PerformedActionsNumber
    /// - vrai si le la balle a touché la case d'arrivée : player.FoundGoal
    /// - vrai si le la balle a touché un obstacle : player.FoundObstacle
    /// - interrogation de la matrice :
    /// € la case de coordonnée (i, j) est elle un obstacle (i et j entre 0 et 49) :
    /// player.GetPutTypeAtCoordinates(i, j) == LayerMask.NameToLayer("Obstacle")
    /// € la case de coordonnée (i, j) est elle explorée (i et j entre 0 et 49) :
    /// player.GetPutTypeAtCoordinates(i, j) == 1
    /// € la case de coordonnée (i, j) est elle inexplorée (i et j entre 0 et 49) :
    /// player.GetPutTypeAtCoordinates(i, j) == 0
    /// </summary>
    /// <param name="solution"></param>
    /// <returns></returns>
    IEnumerator<float> GetError(PathSolutionScript solution)
    {
    // On indique que l'on s'apprête à lancer la simulation
    _inSimulation = true;

    // On créé notre objet que va exécuter notre séquence d'action
    var player = PlayerScript.CreatePlayer();

    // Pour pouvoir visualiser la simulation (moins rapide)
    player.RunWithoutSimulation = false;

    // On lance la simulation en spécifiant
    // la séquence d'action à exécuter
    player.LaunchSimulation(solution);

    // Tout pendant que la simulation n'est pas terminée
    while (player.InSimulation)
    {
    // On rend la main au moteur Unity3D
    yield return -1f;
    }

    // Calcule la distance de Manhattan entre la case d'arrivée et la case finale de
    // notre objet, la pondère (la multiplie par zéro si le but a été trouvé)
    // et ajoute le nombre d'actions jouées
    var error = (Mathf.Abs(PlayerScript.GoalXPositionInMatrix - player.PlayerXPositionInMatrix)
    + Mathf.Abs(PlayerScript.GoalYPositionInMatrix - player.PlayerYPositionInMatrix))
    * (player.FoundGoal ? 0 : 100) +
    player.PerformedActionsNumber;

    //Debug.Log(player.FoundGoal);

    // Détruit l'objet de la simulation
    Destroy(player.gameObject);

    // Renvoie l'erreur précédemment calculée
    yield return error;

    // Indique que la phase de simulation est terminée
    _inSimulation = false;
    }

    /// <summary>
    /// Execute un changement aléatoire sur une solution
    /// ici, une action de la séquence est tirée au hasard et remplacée
    /// par une nouvelle au hasard.
    /// </summary>
    /// <param name="sol"></param>
    public void RandomChangeInSolution(PathSolutionScript sol)
    {
    sol.Actions[UnityEngine.Random.Range(0, sol.Actions.Length)] = new ActionSolutionScript();
    }

    /// <summary>
    /// Fonction utilitaire ayant pour but de copier
    /// dans un nouvel espace mémoire une solution
    /// </summary>
    /// <param name="sol">La solution à copier</param>
    /// <returns>Une copie de la solution</returns>
    public PathSolutionScript CopySolution(PathSolutionScript sol)
    {
    // Initialisation de la nouvelle séquence d'action
    // de la même longueur que celle que l'on souhaite copier
    var newSol = new PathSolutionScript(sol.Actions.Length);

    // Pour chaque action de la séquence originale,
    // on copie le type d'action.
    for (int i = 0; i < sol.Actions.Length; i++)
    {
    newSol.Actions[i].Action = sol.Actions[i].Action;
    }
    // Renvoi de la solution copiée
    return newSol;
    }
    }

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    332
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2002
    Messages : 332
    Par défaut
    SVP utilisez les balises tels que

    et personne ici n'a le gout ou le temps de faire les devoirs des étudians...

Discussions similaires

  1. modification dynamique code html
    Par xtendance dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 10/10/2006, 11h09
  2. Réponses: 4
    Dernier message: 29/09/2006, 16h38
  3. Réponses: 1
    Dernier message: 03/05/2006, 10h17
  4. [Couleur] Modification du code couleur de l'interface
    Par Therich dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 31/01/2006, 20h00
  5. Modification de code
    Par HADES62 dans le forum Autres langages
    Réponses: 5
    Dernier message: 25/01/2006, 11h42

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