Algo dijkstra java

Résolu/Fermé
Utilisateur anonyme - 20 oct. 2009 à 10:35
sandul Messages postés 3924 Date d'inscription jeudi 22 mai 2008 Statut Membre Dernière intervention 8 octobre 2010 - 23 oct. 2009 à 15:24
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
20 oct. 2009 à 19:34
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
20 oct. 2009 à 18:43
Il n'y a personne ici qui sait programmer plus qu'une boucle while?
0
Utilisateur anonyme
20 oct. 2009 à 19:09
personne donc...
0
sandul Messages postés 3924 Date d'inscription jeudi 22 mai 2008 Statut Membre Dernière intervention 8 octobre 2010 722
20 oct. 2009 à 19:20
'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 3924 Date d'inscription jeudi 22 mai 2008 Statut Membre Dernière intervention 8 octobre 2010 722
20 oct. 2009 à 19:51
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
20 oct. 2009 à 19:58
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 3924 Date d'inscription jeudi 22 mai 2008 Statut Membre Dernière intervention 8 octobre 2010 722
20 oct. 2009 à 20:03
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
20 oct. 2009 à 20:19
Pas de soucis, c'est déjà sympa de m'avoir répondu!
0
Utilisateur anonyme
23 oct. 2009 à 12:47
Un petit up... En espérant avoir une réponse utile un jour...
0
sandul Messages postés 3924 Date d'inscription jeudi 22 mai 2008 Statut Membre Dernière intervention 8 octobre 2010 722
23 oct. 2009 à 14:11
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
23 oct. 2009 à 14:13
Là tout de suite j'avoue que ça m'est égal étant donné l'urgence de la situation ;) .
0
sandul Messages postés 3924 Date d'inscription jeudi 22 mai 2008 Statut Membre Dernière intervention 8 octobre 2010 722
23 oct. 2009 à 14:14
O_O... Comment on fait ses TPs de nos jours ^^
http://renaud.waldura.com/doc/java/dijkstra/

Amuse-toi bien ;-)
0
Utilisateur anonyme
23 oct. 2009 à 14:18
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 3924 Date d'inscription jeudi 22 mai 2008 Statut Membre Dernière intervention 8 octobre 2010 722
23 oct. 2009 à 14:26
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 vendredi 23 octobre 2009 Statut Membre Dernière intervention 23 octobre 2009
23 oct. 2009 à 14:19
j ss debutante é j n'arrive ps a saisir tt cs codes
0
sandul Messages postés 3924 Date d'inscription jeudi 22 mai 2008 Statut Membre Dernière intervention 8 octobre 2010 722
23 oct. 2009 à 14:24
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
23 oct. 2009 à 14:40
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 3924 Date d'inscription jeudi 22 mai 2008 Statut Membre Dernière intervention 8 octobre 2010 722
23 oct. 2009 à 15:14
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
23 oct. 2009 à 15:22
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 3924 Date d'inscription jeudi 22 mai 2008 Statut Membre Dernière intervention 8 octobre 2010 722
23 oct. 2009 à 15:24
Je m'en doutais, t'inquiète =)
0