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

Langage Java Discussion :

Problème de récursivité


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 78
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut Problème de récursivité
    Bonjour à tous !
    Je développe une classe de matrices de rationnels.
    J'ai déjà une classe de rationnels (entièrement testée).
    Voici le début de ma classe MatRat (matrices de rationnels).
    Tout a été testé et fonctionne normalement a l'exception du déterminant. J'ai utilisé la méthode du développement suivant la première ligne. Ce n'est pas, et de loin la meilleure, mais c'est sans importance mes matrices sont petites.
    Voici le code. J'ai commenté la méthode 'Det':
    Code Java : 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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
     
    import java.util.Vector;
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    /**
     *
     * @author gilles
     */
    public class MatRat extends Object {
     
        public int lignes;
        public int colonnes;
        public Vector V;
     
        public MatRat(int m, int n) {
            lignes = m;
            colonnes = n;
            V = new Vector();
            V.setSize(m * n);
        }
     
        public MatRat(int m) {
            lignes = colonnes = m;
            V = new Vector();
            V.setSize(m * m);
        }
     
        public void setAt(int i, int j, Rationnel r) {
            V.setElementAt(r, i * colonnes + j);
        }
     
        public Rationnel getAt(int i, int j) {
            return (Rationnel) V.get(i * colonnes + j);
        }
     
        @Override
        public String toString() {
            String result = new String();
            result = "{";
            String ligne = new String();
            for (int i = 0; i < lignes; i++) {
                ligne = "(";
                {
                    for (int j = 0; j < colonnes; j++) {
                        ligne = ligne.concat(this.getAt(i, j).toString());
                        if (j != colonnes - 1) {
                            ligne = ligne.concat(",");
                        }
                    }
                    ligne = ligne.concat(")");
                    result = result.concat(ligne);
                    if (i != lignes - 1) {
                        result = result.concat(";");
                    }
                }
            }
            result = result.concat("}");
            return result;
        }
     
        public MatRat Mineur(int i, int j) {
            MatRat M = new MatRat(lignes - 1, colonnes - 1);
            int k = 0;
            for (int u = 0; u < lignes; u++) {
                for (int v = 0; v < colonnes; v++) {
                    if ((u != i) && (v != j)) {
                        M.V.setElementAt(this.getAt(u, v), k);
                        k++;
                    }
                }
            }
            return M;
     
        }
        // Calcul du déterminant par la formule du développement suivant la première ligne.
     
        public Rationnel Det() {
            // variables locales 
            Rationnel r; // résultat à retourner
            Rationnel m; // variable de boucle
            int signe; //idem
            int j; // compteur
            MatRat H; //pas indispensable juste pour augmenter lisibilité
            // condition terminale de la récursivité
            if (lignes == 1) {
                r = getAt(0, 0); // le déterminant est l'unique coefficient
            } else {
                r = new Rationnel(0, 1); // r initialisé à zéro-accumulateur
                signe = +1; // on commence avec un signe +
                for (j = 0; j < colonnes; j++) {
                    H = Mineur(0, j); // on prend le mineur
                    m = H.Det(); // appel récursif
                    m = m.multiply(getAt(0, j)); // multiplier par le coeff 
                    if (signe == -1) {
                        m = new Rationnel(-m.getNumerator(), m.getDenominator());
                    } // changer  le signe une fois sur deux
                    signe = -signe; // pour l'alterrnance des signes
                    r = r.add(m); // ajouter à l'accu.
                }
            }
            return r;// résultat
        }
    }
    A l'exception des matrices (1,1) Tout appel à Det provoque un plantage (apparemment une boucle infinie, on ne sort pas de la récursion). Je ne comprends pas pourquoi. J'ai programmé cela cent fois dans d'autres langages sans le moindre problème. Si quelqu'un voit ce qui se passe. Merci ...
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 71
    Par défaut
    Voir les détails et commentaires divers dans le code ci-après:

    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
     
    // Mon implem. J'ai mis des commentaires dedans avec qq petits
    // conseils pour si tu es débutant sur le langage Java
    public class MatRat {
     
        // Je crée une base de classe qui décrit les nombres
        // rationnels pour pouvoir compiler et tester...
        private static final class Rational {
     
            private int _numerator;
            private int _denominator;
     
            public Rational(final int numerator, final int denominator) {
                _numerator = numerator;
                _denominator = denominator;
            }
     
            public int getNumerator() {
                return _numerator;
            }
     
            public int getDenominator() {
                return _denominator;
            }
     
            public void setNumerator(final int numerator) {
                _numerator = numerator;
            }
     
            public void setDenominator(final int denominator) {
                _denominator = denominator;
            }
     
            /**
             * {@inheritDoc}
             */
            @Override
            public String toString() {
                if (_numerator == 0)
                    return "0";
                else if (_denominator == 1)
                    return Integer.toString(_numerator);
                else
                    return
                        Integer.toString(_numerator) +
                        '/' +
                        Integer.toString(_denominator);
            }
     
            public static Rational additionNeutralElement() {
                return new Rational(0, 1);
            }
     
            public Rational add(final Rational rational) {
     
                final int numerator =
                    _numerator * rational.getDenominator() +
                    _denominator * rational.getNumerator();
     
                return new Rational(numerator,
                                    _denominator * rational.getDenominator());
     
            }
     
            public Rational multiply(final Rational rational) {
                return new Rational(_numerator * rational.getNumerator(),
                                    _denominator * rational.getDenominator());
            }
     
            public void sign(final int sign) {
                if (sign < 0)
                    _numerator = -_numerator;
            }
     
        }
     
        public int _lineCount;
        public int _columnCount;
     
        // Comme on connait la taille et qu'elle est fixe, avec un
        // tableau, c'est plus simple et plus peformant. Sinon,
        // préférer ArrayList à Vector
        public Rational[] _values;
     
        public MatRat(final int m, final int n) {
            _lineCount = m;
            _columnCount = n;
            _values = new Rational[n * m];
        }
     
        public MatRat(final int m) {
            // C'est mieux de rappeler l'autre constructeur, ça évite
            // de dupliquer le code
            this(m, m);
        }
     
        public void setAt(final int i, final int j, final Rational r) {
            setAt(i * _columnCount + j, r);
        }
     
        public void setAt(final int k, final Rational r) {
            _values[k] = r;
        }
     
        public Rational getAt(final int i, final int j) {
            return _values[i * _columnCount + j];
        }
     
        // Implem pas très performante. Fait des tas d'allocations de
        // chaines de caractères qui ne sont pas utiles. Voir commentaires
        // dedans et corrigé après
    //    @Override
    //    public String toString() {
    //
    //        // (1) Cette ligne ne sert à rien, une nouvelle chaine est allouée
    //        // à la ligne suivante
    //        String result = new String();
    //
    //        // Est quasi-équivalent (en moins bien) à result = new String("{");
    //        // donc la référence allouée à la ligne précédente est perdue
    //        result = "{";
    //
    //        // Même constat que dans les lignes précédentes (1)
    //        String ligne = new String();
    //
    //        for (int i = 0; i < _lineCount; i++) {
    //            ligne = "(";
    //            {
    //                for (int j = 0; j < _columnCount; j++) {
    //                    ligne = ligne.concat(this.getAt(i, j).toString());
    //                    if (j != _columnCount - 1)
    //                        ligne = ligne.concat(",");
    //                }
    //                ligne = ligne.concat(")");
    //                result = result.concat(ligne);
    //                if (i != _lineCount - 1)
    //                    result = result.concat(";");
    //            }
    //        }
    //        result = result.concat("}");
    //        return result;
    //    }
     
        @Override
        public String toString() {
     
            final StringBuilder result = new StringBuilder()
                .append('{');
     
            for (int i = 0; i < _lineCount; i++) {
                result.append('(');
                for (int j = 0; j < _columnCount; j++) {
                    result.append(getAt(i, j));
                    if (j != _columnCount - 1)
                        result.append(',').append(' ');
                }
                result.append(')');
                if (i != _lineCount - 1)
                    result.append(';').append(' ');
            }
     
            return result.append('}').toString();
     
        }
     
        public MatRat minor(final int i, final int j) {
     
            final MatRat minor = new MatRat(_lineCount - 1, _columnCount - 1);
            int k = 0;
     
            for (int u = 0; u < _lineCount; u++)
                for (int v = 0; v < _columnCount; v++)
                    if ((u != i) && (v != j))
                        minor.setAt(k++, getAt(u, v));
     
            return minor;
     
     
        }
     
        // Calcul du déterminant par la formule du développement suivant
        // la première ligne.
        //
        // En simplifiant légèrement le code (et avec qq petites optims)
        // on y voit plus clair !!
        // Ceci étant dit, j'obtiens les même résultats qu'avec ton implem
        // qui marche chez moi. Es-tu sur que le problème venait vraiment
        // de cette méthode ???
        public Rational determinant() {
     
            if (_lineCount == 1)
                return getAt(0, 0);
            else {
     
                Rational determinant = Rational.additionNeutralElement();
                int sign = 1;
     
                for (int j = 0; j < _columnCount; j++) {
     
                    final Rational m = minor(0, j)
                        .determinant()
                        .multiply(getAt(0, j));
     
                    m.sign(sign);
                    sign = -sign;
     
                    determinant = determinant.add(m);
     
                }
     
                return determinant;
     
            }
     
        }
     
    }

  3. #3
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 78
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Merci Yomgui, pour le temps passé.
    J'ai la solution et tu as raison.
    Voilà ce qui s'est passé.
    J'ai emprunté une classe Rationnel sur le web et j'ai fait les tests (de l'auteur - pas les miens). La classe avait un bug énorme au niveau du constructeur quand le numérateur est nul.
    De sorte que quand je mettais à zéro mon accumulateur, le constructeur se mettait en boucle indéfiniment.
    Moralité: Faut pas être paresseux. J'aurais mis une heure ou deux à construire ma propre classe. J'ai passé une après-midi à debugger celle d'un autre.
    Merci encore pour ton aide.
    Je mets le tag résolu.
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    333
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 333
    Par défaut
    je me disais aussi que je trouvais pas le moindre problème de récursivité dans ta classe .... ça me rassure je croyais avoir tout perdu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème Arnaud <> récursivité
    Par Kanter dans le forum Delphi
    Réponses: 13
    Dernier message: 20/02/2007, 16h54
  2. Problème de récursivité
    Par nmathon dans le forum Delphi
    Réponses: 5
    Dernier message: 12/01/2007, 16h40
  3. Problème de récursivité en Prolog
    Par poooky dans le forum Prolog
    Réponses: 5
    Dernier message: 04/01/2007, 17h35
  4. Problème de récursivité
    Par mehdi.berra dans le forum C
    Réponses: 8
    Dernier message: 14/12/2006, 17h42
  5. Problème de récursivité
    Par tazmania dans le forum C
    Réponses: 24
    Dernier message: 14/12/2005, 14h34

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