Java et récursivité ???

Résolu
Enderounet Messages postés 29 Date d'inscription mardi 2 août 2005 Statut Membre Dernière intervention 30 août 2005 - 3 août 2005 à 09:27
Enderounet Messages postés 29 Date d'inscription mardi 2 août 2005 Statut Membre Dernière intervention 30 août 2005 - 5 août 2005 à 13:51
J'ai cette méthode dans ma classe qui est un peu barbare :

protected static double CalculB(int J, int S, double B, double DB, double BZ){
double RC, DZ, RX, sO, fO, nO, iO, eO, sC, fC, nC, iC, eC, nu, de;
RX = OrCd/CuivreCd;
sO = 15.622;
fO = 0.21;
nO = 0.0030576;
iO = 1490;
eO = 4.906;
sC = 0.7115;
fC = 0.45;
nC = 0.006549;
iC = 2.79;
eC = 577;
nu = nO * fO * (sO * ((StrictMath.pow(50000, B-1/2)-StrictMath.pow(0.5, B-1/2))/(B-1/2)) + iO * StrictMath.pow(eO, B));
de = nC * fC * (sC * ((StrictMath.pow(50000, B-1/2)-StrictMath.pow(0.5, B-1/2))/(B-1/2)) + iC * StrictMath.pow(eC, B));
RC = nu / de;
DZ = RC - RX;
if (DZ < 0) S = -1;
Min = StrictMath.abs(DZ) / RX; if (B 0) BZ Min;
if (Min < DB)
{
DB = DB / 10;
J = J - 1;
if (J <= 0) return B;
else
{
BZ = Min;
B = B + S * DB;
return CalculB(J, S, B, DB, BZ);
}
}
else
{
if (BZ < Min)
{
B = B - S * DB;
return B;
}
else
{
BZ = Min;
B = B + S * DB;
return CalculB(J, S, B, DB, BZ);
}
}
}

Elle est censée représenter un algo de calcul, mais au test j'ai ce message d'erreur:

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at criticité.Données.CalculB(Données.java:57)
at criticité.Données.CalculB(Données.java:81)

Problème de mémoire? de récursivité? ...
Cet algo est a la base ecrit en BASIC et ca passe bien ( test avec des valeurs calculées, et je tombe pas en boucle infinie ).
Help merci

24 réponses

cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 11
5 août 2005 à 11:50
et voila le resultat de ma traduction ;o) tu vera que null par je n utilise la réentrence... car l algo que tu nous as donné n est qu une simple boucle ...
je l ai converti a l arrache la ;o) et je ne l ai pas tester mais bon il n y aucun resonnement dc pas trop d erreur possible ;o) ...

public void tonCalcul( double cv, double cr, double cd, double au, double in, double ni, double mg )
{
// 3010
double rx = au / cd ;
double s0 = 15.622 ;
double fo = .21 ;
double no = .0030576 ;
double io = 1490 ;
double eo = 4.906 ;
double sc = .7115 ;
double fc = .45 ;
double nc = .006549 ;
double ic = 2.79 ;
double ec = 577 ;
double ei = .105 ;
double ex = 100000 ; // 100000! je ne sai pas le traduire dc pas fait
double ed = .5 ;
double j = 2 ;
double s = 1 ;
double bb = 0 ;
double db = .01 ;


double bz = 0;

while ( true )
{
double B2 = bb - .5 ; double e2 ( Math.pow( ex, B2 ) - Math.pow( ed, B2 ) ) / B2 ; // e2 (ex ^ B2 - ed ^ B2) / B2
double nu = no * fo * ( s0 * e2 + io * Math.pow( eo, bb ) ) ;
double de = nc * fc * (sc * e2 + ic * Math.pow( ec, bb ) ) ;
double rc = nu / de ;;
double dz = rc - rx ;
if ( dz < 0 ) { s--; }
double az = Math.abs(dz) / rx ; if (bb 0 ) { bz az; }
if( az < db )
{
db = db / 10 ;
j = j - 1 ;
bz = az;
if( j <= 0 ) // condition de sortie
{
System.out.println( " COMPOSANTE EN K/E**b" );
System.out.println( "ParamŠtre b = " + bb );
break; // kitte la boucle
}
}
else if( az > bz )
{
az = bz ;
bb = bb - s * db;
System.out.println( "( minimum relatif = " + az + " )" );
break;
}
bz = az ;
bb = bb + s * db ;
} // while
}

GL

++
GodConan
super_toinou Messages postés 764 Date d'inscription mardi 25 mai 2004 Statut Membre Dernière intervention 8 mars 2011 6
3 août 2005 à 09:35
je crois que tu dépasse la memoire alloué a ta JVM en faisant ca : trop d empilement de variable pdt ta récursivuté
je connais pas le fonctionnement de BASIC mais essaye de lancer ton programme avec l option -Xmx256m ou -Xmx512m ca te permettera d avoir plus de ram pr empiler tes données

++ Toinou
Enderounet Messages postés 29 Date d'inscription mardi 2 août 2005 Statut Membre Dernière intervention 30 août 2005
3 août 2005 à 10:15
j ai lu aussi qu il est possible de gerer les exceptions. est ce que ce serait une solution pour mon cas? et comment?
super_toinou Messages postés 764 Date d'inscription mardi 25 mai 2004 Statut Membre Dernière intervention 8 mars 2011 6
3 août 2005 à 10:26
deja t as essayé mon truc???
sinon oui tu peux catcher l exception java.lang.StackOverflowError et appler explicitement le garbage collector
mais a mon avis si t en arrive a de telles solution c que doit y avoir une couille dans le paté, tu gere pas d objet complexe, que des types primitifs,

Toinou

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

Posez votre question
Madvin Messages postés 123 Date d'inscription mardi 5 août 2003 Statut Membre Dernière intervention 26 août 2012 3
3 août 2005 à 10:32
Salut,

ben ce serait utile si cet algo est utilisé dans une application et que tu ne veux pas qu'elle plante, mais si l'exception java.lang.StackOverflowError est lancée, tu n'auras pas le résultat à ton calcul.

@+
Enderounet Messages postés 29 Date d'inscription mardi 2 août 2005 Statut Membre Dernière intervention 30 août 2005
3 août 2005 à 11:01
j'ai essayé de mettre moins de variables et ca plantait tjs.
en fait je bosse sur netbeans ( assez gourmand ), et je lance le projet direct. mais en compilant et lancant a part ca plante plus.
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 11
3 août 2005 à 11:58
la premiere chose a faire est de verifier la validité de ton algo ... ;o)
verifi bien les condition de sorti et de réentrence....
j ai mi un compteur à ton algo et a mon 3 ieme test de valeurs bidon je pété déja la pile avec 1252 passage

autrement si tu as réélement un gro besoin en recursivité ;o)
essaye en faisant de l object par des allocation successive...

GL
ps : oui aussi ;o) ecrit plustot j-- ou j++ au lieu de j j-1 et j j+1 tu meme ecrire j += 2 par exemple ;o) et il est aussi conventionnel de réserver l usage de la majuscule en 1 ere lettre pour les nom de class et dc pas pour les variables.... ;o)

GodConan
Enderounet Messages postés 29 Date d'inscription mardi 2 août 2005 Statut Membre Dernière intervention 30 août 2005
3 août 2005 à 14:42
bah en fait je viens de m'appercevoir que je trouve pas les bons résultats malgré que le prog tourne :/
etant debutant je veut bien une explication sur les allocations successives, parce que je pense que ca plante a cause de trop de recursivité ...

ps : dsl pour les noms, mais c des formules physiques, et je m'y retrouve plus facilement comme ca :s

Merci
Guillemouze Messages postés 991 Date d'inscription samedi 25 octobre 2003 Statut Membre Dernière intervention 29 août 2013 6
3 août 2005 à 15:40
deja a ta place, je mettrai les variables sO, fO, ...eC en var de
classe (eventuellement static) vu qu'elle sont constantes. Si comme
conan le dis, il y a 1252 passages, ca te fai deja economiser 1252 * la
taille de 10 doubles, cad. 1252*10*8 (je crois) = 100160 octets + tous
les pointeurs dans la pile. bon c sur ya pas de koi remplir ta barette
de ram mais c deja ca!
Enderounet Messages postés 29 Date d'inscription mardi 2 août 2005 Statut Membre Dernière intervention 30 août 2005
3 août 2005 à 15:53
Vi c est pas faux tout ca
Voila ma classe apres ttes ces modifs :

public class Données {
protected static String Numéro;
protected static String Description;
protected static double CuivreAv;
protected static double CuivreAr;
protected static double CuivreCd;
protected static double OrCd;
protected static double IndiumCd;
protected static double NickelCd;
protected static double Magnésium;
protected static double B;
protected static double Min;
protected static int compteur;

/** Creates a new instance of Données */
protected Données() {
InitDonnées();
}

protected void InitDonnées(){
CuivreAv = 0;
CuivreAr = 0;
CuivreCd = 0;
OrCd = 0;
IndiumCd = 0;
NickelCd = 0;
Magnésium = 0;
B = 0;
Min = 0;
compteur = 0;
}

protected static double CalculB(int J, int S, double B, double DB, double BZ){
double RC, DZ, RX, nu, de;
RX = OrCd/CuivreCd;
Données.compteur ++;
nu = 0.0030576 * 0.21 * (15.622 * ((StrictMath.pow(100000, B-1/2)-StrictMath.pow(0.5, B-1/2))/(B-1/2)) + 1490 * StrictMath.pow(4.906, B));
de = 0.006549 * 0.45 * (0.7115 * ((StrictMath.pow(100000, B-1/2)-StrictMath.pow(0.5, B-1/2))/(B-1/2)) + 2.79 * StrictMath.pow(577, B));
RC = nu / de;
DZ = RC - RX;
if (DZ < 0) S = -1;
Min = StrictMath.abs(DZ) / RX; if (B 0) BZ Données.Min;
if (Données.Min < DB)
{
DB /= 10;
J--;
if (J <= 0) return B;
else
{
BZ = Données.Min;
B += (S * DB);
return CalculB(J, S, B, DB, BZ);
}
}
else
{
if (BZ < Données.Min)
{
Données.Min = BZ;
B -= (S * DB);
return B;
}
else
{
BZ = Données.Min;
B += (S * DB);
return CalculB(J, S, B, DB, BZ);
}
}
}
}

j'ai mis un compteur et pour n'importe quelles valeurs en entrée il fait toujours que 86 passages :/
je sent que je dois me planter qque part dans les appels ou dans l utilisation des variables.
c a plus rien y comprendre.
Enderounet Messages postés 29 Date d'inscription mardi 2 août 2005 Statut Membre Dernière intervention 30 août 2005
4 août 2005 à 11:41
il me donne meme le meme resultat pour b, je commence a peter les plombs lol
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 11
4 août 2005 à 14:59
donne nous plutot l algo en pseudo code ou ce qui ta amené a cette methode ... ;o)
on verra bien ;o) si tu t es planté (ou plutot comment.. ; o) )


GL

++

GodConan
Enderounet Messages postés 29 Date d'inscription mardi 2 août 2005 Statut Membre Dernière intervention 30 août 2005
4 août 2005 à 15:38
l'algo en fait est une méthode d'evaluation d'une inconnue dans une formule. on calcule le membre de droite et celui de gauche ( qui comprend la valeur inconnue b ) et on essaye de s'en approcher dans une certaine limite.
cet algo est repris mot pour mot d'un algo fait en basic a la base, et la dessus je n ai plus aucun doute. le probleme doit venir de mon utilisation des variables ou alors de la possibilité de java a gerer la recursivité. et la c le vide total lol
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 11
4 août 2005 à 21:15
c est peu etre un prob de traduction ;o) montre l algo en basic ... ;o)

GodConan
Guillemouze Messages postés 991 Date d'inscription samedi 25 octobre 2003 Statut Membre Dernière intervention 29 août 2013 6
4 août 2005 à 21:29
alors ds ce cas, peux tu nous filer l'algo en basic.... on pourra mieux comprendre
Guillemouze Messages postés 991 Date d'inscription samedi 25 octobre 2003 Statut Membre Dernière intervention 29 août 2013 6
4 août 2005 à 21:31
erf faudra que je refresh la page la prochaine fois avant de poster un message
Enderounet Messages postés 29 Date d'inscription mardi 2 août 2005 Statut Membre Dernière intervention 30 août 2005
4 août 2005 à 22:05
voila :

<!--StartFragment --> <TT>3010 LPRINT
LPRINT " Nombre de noyaux activ‚s par gramme d'‚l‚ment cible : N*
(g-1)"
LPRINT
LPRINT " CV="; cv
LPRINT " CR="; cr
LPRINT " CD="; cd
LPRINT " AU="; au
LPRINT " IN="; in
LPRINT " NI="; ni
LPRINT " MG="; mg
LPRINT M$
rx = au / cd
s0 = 15.622
fo = .21
no = .0030576
io = 1490
eo = 4.906
sc = .7115
fc = .45
nc = .006549
ic = 2.79
ec = 577
ei = .105
ex = 100000!
ed = .5
j = 2
s = 1
bb = 0
db = .01
3110 B2 = bb - .5
e2 = (ex ^ B2 - ed ^ B2) / B2
nu = no * fo * (s0 * e2 + io * eo ^ bb)
de = nc * fc * (sc * e2 + ic * ec ^ bb)
rc = nu / de
dz = rc - rx
IF dz < 0 THEN s = -1
az = ABS(dz) / rx
IF bb 0 THEN bz az
IF az < db GOTO 3240
IF az > bz GOTO 3280
3220 bz = az
GOTO 3260
3240 db = db / 10
j = j - 1
bz = az
IF j <= 0 GOTO 3290
3260 bb = bb + s * db
GOTO 3110
3280 az = bz
bb = bb - s * db
LPRINT TAB(10); "( minimum relatif = "; az; " )"
LPRINT
3290 LPRINT TAB(10); " COMPOSANTE EN K/E**b"
LPRINT TAB(34); "ParamŠtre b = "; bb

je l ai meme repris sur papier en suivant ttes les conditions
j attend votre avis avec impatience

merci encore</TT>
Enderounet Messages postés 29 Date d'inscription mardi 2 août 2005 Statut Membre Dernière intervention 30 août 2005
4 août 2005 à 22:08
oula lol, faites un copier/coller sinon c illisible la lol
Guillemouze Messages postés 991 Date d'inscription samedi 25 octobre 2003 Statut Membre Dernière intervention 29 août 2013 6
4 août 2005 à 23:17
meme avec le copier/coller c illisible!!! recolle avec les sauts de
ligne sinon on sait pas quand il faut faire un retour a la lige. Et
comme le retour chariot est un caractere de fin d'instruction en
basic...
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 11
5 août 2005 à 10:10
deja au vu de ce petit morceau tu peut voir une error evidente d interpretation ;o) ...
ici il n y a aucun gosub ni return mais que des goto donc la pile (stack) n est jamais solicité ...

aller je vai regarder de plus pret ;o)

++

GodConan
Rejoignez-nous