Algo dijkstra java

Résolu
Utilisateur anonyme -  
sandul Messages postés 3927 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour,


Afin de trouver le chemin de plus court j'ai implémenté l'algo de dijkstra, il est censé afficher le chemin le plus court (les numéros des sommets à parcourir) entre le premier point et le dernier. Nous avons le tableau des points contenant les indices des points, un tableau contenant la distance entre 2points, -1 si ils ne sont pas relié et un tableau contenant l'indice des sommets pas encore parcourus. Je me suis inspirée de l'aglo disponible sur wikipédia.

Le problème vient sans doute d'une initialisation, il renvoie toujours 0 (c'est à dire le premier point, soit le point de départ, mais après 4heures passées dessus je ne trouve plus rien. Si quelqu'un pouvait y jeter un oeil...

int tabaretes[][] = new int [10][10];
for (int i=0; i<10; i++)
for (int j=0; j<10; j++)
tabaretes[i][j]=-1;
tabaretes[0][1] = 6;
tabaretes[0][2] = 4;
tabaretes[1][0] = 6;
tabaretes[1][3] = 2;
tabaretes[1][4] = 7;
tabaretes[2][0] = 4;
tabaretes[2][6] = 3;
tabaretes[3][1] = 2;
tabaretes[3][5] = 8;
tabaretes[4][1] = 7;
tabaretes[5][3] = 8;
tabaretes[5][9] = 7;
tabaretes[6][2] = 3;
tabaretes[6][7] = 5;
tabaretes[6][8] = 6;
tabaretes[7][6] = 5;
tabaretes[8][6] = 6;
tabaretes[9][5] = 7;
tabaretes[9][7] = 4;
tabaretes[7][9] = 4;
Vector listepoints = new Vector (10);
listepoints.setSize(10);
int debut = 0;
int fin = 9;
int tailleVu = 10;


int nbnoeud = listepoints.size();
Vector Points = new Vector (nbnoeud);
Vector pasencorevu = new Vector (nbnoeud);
Vector chemin = new Vector ();
int n1 = 0;
noeud noeudFin = new noeud ();

for(int n=0; n<nbnoeud; n++)
{
noeud temp = new noeud();
temp.indice = n;
temp.parcouru = -1;
temp.precedent = 0;
Points.addElement(temp);
Integer i = new Integer (n);
//on remplit le tableau des noeuds pas encore vu.
pasencorevu.addElement(i);
}

// on initialise le point de depart.
noeud noeudDepart = (noeud)Points.elementAt(debut);
noeudDepart.parcouru = 0;
// on trouve le minimum dans le tableau des arretes.

float min = 0;

initialisation sans doute inutile :
/*for(int i=0; i<nbnoeud; i++)
{
if(tabaretes[debut][i]>0)
{
min = tabaretes[debut][i];
break;
}
}*/

while(!pasencorevu.isEmpty())
{


for(int i=1; i<nbnoeud; i++)
{
Integer j = new Integer (i);
if(pasencorevu.contains(j))//on traite les points qui ne le sont pas encore.
{
Integer courant = (Integer)pasencorevu.elementAt(1);
int courant2 = (int)courant.intValue();
if(tabaretes [courant2][i] < min && tabaretes[courant2][i] != -1)
{
min=tabaretes [courant2][i];
n1 = i;
System.out.println(n1);
}
System.out.println("je suis dans la boucle 1");
}
}
Integer n = new Integer (n1);
pasencorevu.remove(n);//on enleve le point de poids minimum que l'on va traiter de la table des points pas encore vus.
pasencorevu.setSize(--tailleVu);

for(int n2=0; n2<nbnoeud; n2++)
{
System.out.println("je suis dans la boucle 2");
if(tabaretes[n1][n2] != -1)//il existe un lien entre les noeud d'indice n1 et n2 (une arrete).
{

noeud j1 = (noeud)Points.elementAt(n1);
noeud j2 = (noeud)Points.elementAt(n2);

initialisation sans doutes inutile
//if(pasencorevu.size()==9)
//j2.parcouru=tabaretes[debut][n1];

if(j2.parcouru > j1.parcouru + tabaretes[n1][n2]+1)
{
System.out.println("recherche precedent");
j2.parcouru = j1.parcouru + tabaretes[n1][n2];
j2.precedent = n1;
noeudFin = j2;
//Points[n2].parcouru = n1.parcouru + tabarette[n1][n2];
//n2.précédent = n1;
}
}
}
}
//chemin=NULL;

noeud p = (noeud)Points.elementAt(debut);
while(noeudFin.indice != p.indice)
{
Integer i = new Integer (noeudFin.indice);
chemin.add(i);
noeudFin.indice = noeudFin.precedent;
}
Integer i = new Integer (debut);
chemin.add (i);
//return chemin;
int l = (int)chemin.size();
for (int k=0; k<l; k++)
{

Integer j = (Integer)chemin.elementAt(k);
System.out.println (j);
}

}
A voir également:

18 réponses

Utilisateur anonyme
 
Salut, merci de ta réponse, je débute seulement Java, et je n'ai malheureusement pas le code en entier (projet à deux, j'ai chopé à l'arrache le morceau qui ne marchait pas).

Mais nous avons progressé depuis et j'ai un nouvel algo qui je crois est sous forme exécutable... Je le poste, si tu pouvais le regarder je t'en serais infiniment reconnaissante!



import java.applet.Applet;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Material;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.JApplet;
import javax.swing.Timer;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Tuple3d;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.universe.SimpleUniverse;

import java.lang.Math;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

public class suivi_objet extends JApplet implements ActionListener{

class noeud
{
public int indice;
public int parcouru;
public int precedent;
}
public void go()
{

//initialisation du tableau de graphe
int tabaretes[][] = new int [10][10];
for (int i=0; i<10; i++)
for (int j=0; j<10; j++)
tabaretes[i][j]=Integer.MAX_VALUE;
tabaretes[0][1] = 6;
tabaretes[0][2] = 4;
tabaretes[1][0] = 6;
tabaretes[1][3] = 2;
tabaretes[1][4] = 7;
tabaretes[2][0] = 4;
tabaretes[2][6] = 3;
tabaretes[3][1] = 2;
tabaretes[3][5] = 8;
tabaretes[4][1] = 7;
tabaretes[5][3] = 8;
tabaretes[5][9] = 7;
tabaretes[6][2] = 3;
tabaretes[6][7] = 5;
tabaretes[6][8] = 6;
tabaretes[7][6] = 5;
tabaretes[8][6] = 6;
tabaretes[9][5] = 7;
tabaretes[9][7] = 4;
tabaretes[7][9] = 4;

//liste des points (donnés par leur indice de 0 à 9)
Vector listepoints = new Vector (10);
listepoints.setSize(10);
int indiceSommetDepart = 0;
int fin = 9;
int tailleVu = 10;


int nbnoeud = listepoints.size();
Vector Points = new Vector (nbnoeud);
Vector pasencorevu = new Vector (nbnoeud);
Vector chemin = new Vector ();
int n1 = 0;
noeud noeudFin = new noeud ();

for(int n=0; n<nbnoeud; n++)
{
noeud temp = new noeud();
temp.indice = n;
temp.parcouru = Integer.MAX_VALUE;
temp.precedent = 0;
Points.addElement(temp);
Integer i = new Integer (n);
//on remplit le tableau des noeuds pas encore traités (ici aussi reconnu par leur indice)
pasencorevu.addElement(i);
}

// on initialise le point de depart.
noeud noeudDepart = (noeud)Points.elementAt(indiceSommetDepart);
noeudDepart.parcouru = 0;
// on trouve le minimum dans le tableau des arretes.

float min = 0;
pasencorevu.remove(new Integer (0));//on enleve le point de poids minimum que l'on va traiter de la table des points pas encore vus.
pasencorevu.setSize(--tailleVu);


noeud Noeud_n1=new noeud();

int sommetEnCours=indiceSommetDepart;

//l'algo sera fini lorsque tous les points auront étét traités
while(!pasencorevu.isEmpty())
{

System.out.println("début boucle 1");
min=Integer.MAX_VALUE;
for(int i=0; i<nbnoeud; i++)
{
if (tabaretes [sommetEnCours][i]!=Integer.MAX_VALUE)

if(pasencorevu.contains(new Integer (i)))//on traite les points qui ne le sont pas encore.
{
System.out.println(" en cours = " + sommetEnCours+" i=" +i +" val="+ tabaretes [sommetEnCours][i]+ " min = "+min);

if(tabaretes [sommetEnCours][i] < min )
{
min=tabaretes [sommetEnCours][i];
n1 = i;
}
// changer la valeur du fils
int valProposéeFils=Integer.MAX_VALUE;
if (((noeud)Points.elementAt(sommetEnCours)).parcouru !=Integer.MAX_VALUE )
valProposéeFils=((noeud)Points.elementAt(sommetEnCours)).parcouru
+
tabaretes [sommetEnCours][i];
int valActuelleFils=((noeud)Points.elementAt(i)).parcouru;

if (valProposéeFils<valActuelleFils) {
//System.out.println("i="+i+" anc = "+valActuelleFils+"nouvell="+valProposéeFils);
//System.out.println(((noeud)Points.elementAt(sommetEnCours)).parcouru +"----- "+tabaretes [sommetEnCours][i]);
((noeud)Points.elementAt(i)).parcouru=
((noeud)Points.elementAt(sommetEnCours)).parcouru
+
tabaretes [sommetEnCours][i];
}

}
}
System.out.println("fin boucle 1 : n1 retenu = "+n1);




Noeud_n1 = (noeud)Points.elementAt(n1);
int nouvelleValeurSommet= ((noeud)Points.elementAt(sommetEnCours)).parcouru+ tabaretes[n1][sommetEnCours];
int actuelleValeurSommet= Noeud_n1.parcouru;
if (nouvelleValeurSommet<actuelleValeurSommet)
Noeud_n1.parcouru = nouvelleValeurSommet ;


System.out.println("nouveau depart = "+n1);

int indiceNouveauMinmum =-1;
int nouveauMinimum =nouvelleValeurSommet;

System.out.println("début boucle 2 nouveauMinimum "+nouveauMinimum);
for(int n2=0; n2<nbnoeud; n2++)
{
if(pasencorevu.contains(new Integer (n2)))//on traite les points qui ne le sont pas encore.
{
System.out.println("traite B2 "+n2+" ="+((noeud)Points.elementAt(n2)).parcouru);
if ( ((noeud)Points.elementAt(n2)).parcouru < nouveauMinimum)
{

nouveauMinimum = ((noeud)Points.elementAt(n2)).parcouru;
indiceNouveauMinmum =n2;
System.out.println("nouveau min n2="+n2+" val="+nouveauMinimum);

}

}
}

if (indiceNouveauMinmum!=-1) {
n1=indiceNouveauMinmum;
// (utile?) pasencorevu.remove(new Integer (n1));//on enleve le point de poids minimum que l'on va traiter de la table des points pas encore vus.
// (utile?) pasencorevu.setSize(--tailleVu);

}

pasencorevu.remove(new Integer (n1));//on enleve le point de poids minimum que l'on va traiter de la table des points pas encore vus.
pasencorevu.setSize(--tailleVu);

((noeud)Points.elementAt(n1)).precedent=sommetEnCours;
sommetEnCours=n1;
System.out.println("nouveau depart = "+sommetEnCours);




} // fin du while principal


// ***************************
//System.exit(0); (pour les tests)


//récupération du chemin

noeud p = (noeud)Points.elementAt(indiceSommetDepart);

while(Noeud_n1.indice != p.indice)
{
Integer i = new Integer (Noeud_n1.indice);
chemin.add(i);
Noeud_n1.indice = Noeud_n1.precedent;
}
Integer i = new Integer (indiceSommetDepart);
chemin.add (i);
//return chemin;
int l = (int)chemin.size();
for (int k=0; k<l; k++)
{

Integer j = (Integer)chemin.elementAt(k);
System.out.println (j);
}

}

public static void main(String[] args)
{ suivi_objet o=new suivi_objet();
o.go();
}

public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub

}
}

Je ne connais pas les balises <code> enfin je ne crois pas, si tu pouvais m'expliquer ;)
1
Utilisateur anonyme
 
Il n'y a personne ici qui sait programmer plus qu'une boucle while?
0
Utilisateur anonyme
 
personne donc...
0
sandul Messages postés 3927 Date d'inscription   Statut Membre Dernière intervention   723
 
'Soir,

Il n'y a personne ici qui sait programmer plus qu'une boucle while?
Je pourrais m'évertuer à le faire (je sais gérer jusqu'à 3 boucles while!). Mais ton code a une boucle for, quelle horreur, pas de chance... xD

Si tu donnais un code exécutable, ceci serait plus facile à regarder. Et entre des balises <code> aussi...

++
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
sandul Messages postés 3927 Date d'inscription   Statut Membre Dernière intervention   723
 
Mvoui, c'est exécutable... Mais il faut du temps pour décortiquer ton code. Beaucoup de temps.

while (Noeud_n1.indice != p.indice) {
Integer i = new Integer(Noeud_n1.indice);
chemin.add(i);
Noeud_n1.indice = Noeud_n1.precedent;
}

==> boucle infinie, nan? Comment on quitte ici ?
0
Utilisateur anonyme
 
Euh... je ne crois pas puisqu'on prend le précédent du noeud jusqu'à ce que le noeud soit égal au premier... Vu que le chemin mène du premier au dernier à force de précédent on arrive bien au premier non?

Enfin avant mène cette partie il ne trouve pas le bon chemin... Il y a plein de "print" pour ces tests justement...
On y a passé 4heures ce matin, je ne me souviens plus de tout et à la fin tout se mélange, pour ça qu'un oeil extérieur ne ferait pas de mal.
0
sandul Messages postés 3927 Date d'inscription   Statut Membre Dernière intervention   723
 
Euh... je ne crois pas puisqu'on prend le précédent du noeud jusqu'à ce que le noeud soit égal au premier...
Et pourtant sur ma machine ta boucle me fait sortir avec
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2760)
at java.util.Arrays.copyOf(Arrays.java:2734)
at java.util.Vector.ensureCapacityHelper(Vector.java:226)
at java.util.Vector.add(Vector.java:728)
at suivi_objet.go(suivi_objet.java:191)
at suivi_objet.main(suivi_objet.java:208)
La condition du while n'est jamais vraie.

Oui, il faut passer du temps.... Et je ne pense pas être au mieux de ma forme pour ce faire. Ce soir, en tout K. Têtre bien demain =)
0
Utilisateur anonyme
 
Pas de soucis, c'est déjà sympa de m'avoir répondu!
0
Utilisateur anonyme
 
Un petit up... En espérant avoir une réponse utile un jour...
0
sandul Messages postés 3927 Date d'inscription   Statut Membre Dernière intervention   723
 
Hello,

Tu attends toujours la pluie, toi ? xD
Que veux-tu, en fait: corriger ton code ou avoir un code limpide implémentant ton algo ? Est-ce que cela t'est égal ou pas ?

++
0
Utilisateur anonyme
 
Là tout de suite j'avoue que ça m'est égal étant donné l'urgence de la situation ;) .
0
sandul Messages postés 3927 Date d'inscription   Statut Membre Dernière intervention   723
 
O_O... Comment on fait ses TPs de nos jours ^^
http://renaud.waldura.com/doc/java/dijkstra/

Amuse-toi bien ;-)
0
Utilisateur anonyme
 
C'est pas un TP c'est un projet ;) cet algo n'est qu'une petite partie... A un moment il faut rendre le projet...

Bon je vais essayer de comprendre ce que tu m'as passé...

Merci, si je m'en sors pas tu pourras me donner quelques précisions?
0
sandul Messages postés 3927 Date d'inscription   Statut Membre Dernière intervention   723
 
Okay, entendu. Passer 4 heures dessus devrait suffire. As ma bénédiction pleine et entière de faire désormais du copier-coller =)
0
oumal_kaire Messages postés 1 Date d'inscription   Statut Membre Dernière intervention  
 
j ss debutante é j n'arrive ps a saisir tt cs codes
0
sandul Messages postés 3927 Date d'inscription   Statut Membre Dernière intervention   723
 
Mmmh? Et proposes quoi ? Je n'ai pas le numéro de mobile d'Edsger, chuis navré. Et pis, ce n'est même pas de sa faute si ce problème existe =)
0
Utilisateur anonyme
 
Bon, je vais être chiante (enfin surtout mon partenaire de projet), il préfèrerait avoir une petite correction de celui sur lequel on a passé euh... 8heures au total... Si tu as un peu de temps à y consacrer.

On a pensé que peut être il faudrait faire 2 tableau comme lla liste "pasencorevu" (après réflexion c'était plus simple de faire des booléens, on y a pensé que plus tard, du coup on a du tout transtypé en Integer, ce qu'on peut être cons des fois...). Il y en aurait un pour chacune des deux boucle. Parce que tel qu'il est je crois que le problème c'est qu'il ne eut plus accéder à certain noeuds dont on a besoin après la deuxième boucle... Mais je ne sais pas si ça suffirait à régler les problèmes...

Pour le contexte on fait un suivi d'objet en fait. Mais vu qu'on fait pas la gestion de collision, on utilise un graphe de déplacement. Voilà pourquoi on a besoin de cet algo... Je ne m'occupe pas de cette partie en principe, mais vu qu'on est coincé là dessus je suis un peu obligée.

Et en passant si tu es compétent là dedans, on voudrait pouvoir remplir le tableau du graphe à partir d'un fichier, est-ce que tu connaitrais quelques fonctions utiles?
0
sandul Messages postés 3927 Date d'inscription   Statut Membre Dernière intervention   723
 
Ton partenaire s'appelle oumal_kaire? :tilt:

Ecoute, corriger ton code n'est toujours pas possible à cause du temps nécessaire. Pour la partie lecture d'un fichier csv ce n'est pas sorcier:

Tu déclares un BufferedReader, e.g. un truc comme ceci

	FileReader fileIn = new FileReader("fichier.csv");
	BufferedReader buffIn = new BufferedReader(fileIn);


Par la suite, tu lis ligne par ligne le contenu du fichier avec un readLine(). Exemple:

	String curLine = null;
	while ((curLine = buffIn.readLine()) != null) {
		// faire qqchose avec le contenu de cette ligne
		// tu peux, par exemple, utiliser StringTokenizer et parser le contenu
		// en tenant compte du délimitateur dans le fichier csv
		// Les valeurs des tokens seront à allouer aux cellules de tes tableaux
	}
0
Utilisateur anonyme
 
Non pas du tout je ne fais pas de projet avec des gens qui écrivent en sms et qui ne connaissent rien au java...
0
sandul Messages postés 3927 Date d'inscription   Statut Membre Dernière intervention   723
 
Je m'en doutais, t'inquiète =)
0