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 :

Stack Overflow en r�ccursif


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre �m�rite
    Avatar de Ange_blond
    Homme Profil pro
    Ing�nieur d�veloppement en 3D temps r�el
    Inscrit en
    Mars 2007
    Messages
    902
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 40
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement en 3D temps r�el
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Par d�faut Stack Overflow en r�ccursif
    Bonjour,

    Voil� je travaille actuellement sur un algo de traitement de l'image. Le but �tant de reconnaitre les formes sur une image binaris�e (noir et blanc). Mon algo se base sur un th�orie que j'ai pens�e � force de m'�nerver sur les algos classiques qui ne marchent pas ^^

    Je parcours mon image en long et en large, et lorsque je trouve un pixel interessant ( en noir) je lance ma boucle r�ccursive qui va chercher tous les voisins � partir de ce pixel noir, et les voisins des voisins... etc...

    Apres avoir �t� confront� � une tonne de stack overflow... j'ai compris que d'augmenter la taille de la pile pourrait suffir � d�bugguer mon programme. En effet, le code fonctionne tres bien, cependant, j'ai besoin des parametres de pile suivants :

    taille de la r�serve de pile : 4000000
    taille de validation de pile : 10000

    (soit : /STACK:4000000,10000 )

    Est ce normal d'en arriver l� pour faire tourner un algo r�ccursif qui ne me parrait pas si "bourrin" que �a ?

    PS : je tourne sous Visual C++ express

    Voil� le code utilis� :

    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
     
            ImagePGM pgm_bin("test.pgm");
     
    	Binaire bin2(200);	//seuil de binarisation
     
    	S2D<unsigned char> s_bin = bin2(pgm_bin.GetData());
    	pgm_bin.Save("test_binarise.pgm");
     
    	S2D<int> C(pgm_bin.Width(),pgm_bin.Height());
    	C.set(0);
     
    	int classe = 1;
     
    	for(int i=1 ; i<pgm_bin.Width(); i++)
    		for(int j=1 ; j<pgm_bin.Height(); j++)
    		{
    			//Si il dépasse le seuil on le récupere (et si il n'est pas déjà classé)
    			if((s_bin[j][i] > 200) && (C[j][i] == 0))
    			{
     
    				select_classe(&s_bin, &C, i, j, classe, 200);
    				classe++;
    				cout << "classe " << classe << endl;
    				//system("pause");
    			}
    		}
    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    /** Fonction récursive de selection d'une classe par propagation **/
    void select_classe( S2D<unsigned char>* s_bin, S2D<int>* C, int w, int h, int classe, int seuil)
    {
    	/*		1 | 2 | 3
    			4 | X | 5
    			6 | 7 | 8
    	*/
     
    	//cout << "Appel en ["<<w<<"]["<<h<<"]"<<endl;
    	//cas d'arret
    	if(((*s_bin)[h][w] > seuil) && ((*C)[h][w] == 0))
    	{
     
    		//on marque le courant.
    		(*C)[h][w] = classe;
     
    		//cout<<"On marque C["<<h<<"]["<<w<<"] avec la classe "<<classe<<endl;
    		//system("pause");
     
    		/*
    		//les voisins sont > seuil ou encore non classés
    		if(((*s_bin)[h-1][w-1] > seuil) && ((*C)[h-1][w-1] == 0))	//1
    			select_classe(s_bin, C, w-1, h-1, classe, seuil);
    		*/
    		if(((*s_bin)[h][w-1] > seuil) && ((*C)[h][w-1] == 0))		//2
    			select_classe(s_bin, C, w-1, h, classe, seuil);
    		/*
    		if(((*s_bin)[h+1][w-1] > seuil) && ((*C)[h+1][w-1] == 0))	//3
    			select_classe(s_bin, C, w-1, h+1, classe, seuil);
    		*/
    		if(((*s_bin)[h-1][w] > seuil) && ((*C)[h-1][w] == 0))		//4
    			select_classe(s_bin, C, w, h-1, classe, seuil);
     
    		if(((*s_bin)[h+1][w] > seuil) && ((*C)[h+1][w] == 0))		//5
    			select_classe(s_bin, C, w, h+1, classe, seuil);
    		/*
    		if(((*s_bin)[h-1][w+1] > seuil) && ((*C)[h-1][w+1] == 0))	//6
    			select_classe(s_bin, C, w+1, h-1, classe, seuil);
    		*/
    		if(((*s_bin)[h][w+1] > seuil) && ((*C)[h][w+1] == 0))		//7
    			select_classe(s_bin, C, w+1, h, classe, seuil);
    	  	/*
    		if(((*s_bin)[h+1][w+1] > seuil) && ((*C)[h+1][w+1] == 0))	//8
    			select_classe(s_bin, C, w+1, h+1, classe, seuil);
    		*/
    	}
     
    	return;
     
    }

    Merci de vos conseils.

  2. #2
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    �a me parait pas tr�s normal en effet.
    Vu qu'il n'y a aucune grosse variable locale dans ton code, il faut vraiment que ta fonction descende � un niveau impressionnant pour que �a plante comme �a...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Expert confirm�

    Inscrit en
    Novembre 2005
    Messages
    5 145
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par d�faut
    Citation Envoy� par Ange_blond Voir le message
    Est ce normal d'en arriver l� pour faire tourner un algo r�ccursif qui ne me parrait pas si "bourrin" que �a ?
    Il me semble plut�t bourrin dans son utilisation de la r�cursivit�. Dans le pire cas, tu as une profondeur d'appel r�cursive �gale au nombre de points de ta classe. Plut�t que de la r�cursivit�, je placerais les points encore � examiner dans une FIFO (une pile revient � ton algo r�cursif, en pire); une structure associative peut avoir des avantages.

    Tu peux essayer aussi d'�tre intelligent et de ne pas placer dans la FIFO des choses redondantes (par exemple le point 3 si tu as d�j� mis le point 2:


  4. #4
    Membre �m�rite
    Avatar de Ange_blond
    Homme Profil pro
    Ing�nieur d�veloppement en 3D temps r�el
    Inscrit en
    Mars 2007
    Messages
    902
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 40
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement en 3D temps r�el
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Par d�faut
    Citation Envoy� par Jean-Marc.Bourguet Voir le message
    Tu peux essayer aussi d'�tre intelligent et de ne pas placer dans la FIFO des choses redondantes (par exemple le point 3 si tu as d�j� mis le point 2:

    En fait, d'apres l'algo, les choses se pr�sentent ainsi :

    1 2 3
    4 X 5
    6 7 8

    Avec X �tant le pixel en cours d'analyse. Si le voisin 2 est selectionn� comme �tant correct (ou non) le voisin 3 doit etre trait� au meme niveau. le test au d�but de la fonction r�cursive permet de ne pas traiter le voisin 3 si on l'a d�j� trait� dans les appels r�ccursifs du voisinage de 2. Dans tous les cas, chaque pixel qui sera trait� par la fonction r�ccursive sera utilis� par 7 autres appels. C'est tres fortement redondant, mais normalement grace aux tests �a devrai aller vite et bien et je suis surpris que �a s'enfonce si loin dans la pile.

    Je vais essayer mettre des tests suppl�mentaires avant chaque appel r�ccursif pour �viter d'empiler des appels qui vont retourner du vide, mais je ne sais pas si �a va vraiment alleger la chose.

    Dans le dernier des cas je retournerai en it�ratif, mais je l'ai tent� et j'ai �chou� lamentablement � plusieurs reprises...

    Merci, je vous tiens au courant.

  5. #5
    Expert confirm�

    Inscrit en
    Novembre 2005
    Messages
    5 145
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par d�faut
    Admettons que tu as la situation suivante:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    -------
    -ABCDE-
    -FGHIJ-
    -KLMNO-
    -PQRST-
    -UVWXY-
    -------
    Et que tu partes de C. Tu vas visiter les pixels dans l'ordre: CBAFKPUVQLGHMRWXSNIDEJOTY avec � chaque fois un appel r�cursif. Pas s�r que ce soit l'id�al.

  6. #6
    Membre �m�rite
    Avatar de Ange_blond
    Homme Profil pro
    Ing�nieur d�veloppement en 3D temps r�el
    Inscrit en
    Mars 2007
    Messages
    902
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 40
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement en 3D temps r�el
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Par d�faut
    je te rapelle que l'ago fonctionne dans l'ordre : haut - droite - bas - gauche

    Donc sur ton exemple, je crois plut�t que �a donnerait :

    CDJEOTYXS...

    (obtenu en d�roulant � la main sur un brouillon les appels)

    Mais la question n'est pas l�, car je ne suis pas sur que de blinder les tests avant la r�cursivit� r�duise le nombre d'appels... mais �a se tente

  7. #7
    Expert confirm�

    Inscrit en
    Novembre 2005
    Messages
    5 145
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par d�faut
    Citation Envoy� par Ange_blond Voir le message
    je te rapelle que l'ago fonctionne dans l'ordre : haut - droite - bas - gauche

    Donc sur ton exemple, je crois plut�t que �a donnerait :

    CDJEOTYXS...

    (obtenu en d�roulant � la main sur un brouillon les appels)
    Pas d'importance. Le principe est le meme

    Mais la question n'est pas l�, car je ne suis pas sur que de blinder les tests avant la r�cursivit� r�duise le nombre d'appels... mais �a se tente
    Ca depend comment tu fais tes tests. A mon avis, c'est possible de s'en sortir avec de la recursivite mais c'est plus complique qu'en manipulant une structure de donnee explicitement, meme si celle-ci est un pile (comme je l'ai deja ecrit, il me semble qu'une file aura de meilleurs resultats, mais c'est a confirmer).

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. [GNU-Prolog][M�moire] Local stack overflow
    Par Maxoo dans le forum Prolog
    R�ponses: 15
    Dernier message: 04/06/2008, 22h15
  2. stack overflow: question insoluble
    Par coyotte507 dans le forum SDL
    R�ponses: 3
    Dernier message: 19/12/2006, 17h50
  3. Stack OverFlow
    Par Goundy dans le forum Langage
    R�ponses: 2
    Dernier message: 24/12/2005, 21h35
  4. Probl�me de stack overflow
    Par heider dans le forum Langage
    R�ponses: 13
    Dernier message: 22/09/2005, 19h50
  5. Stack overflow
    Par portu dans le forum Langage
    R�ponses: 3
    Dernier message: 26/11/2003, 15h16

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