Résolution de systèmes d'équations linéaires

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 537 fois - Téléchargée 28 fois

Contenu du snippet

permet de résoudre des systèmes d'équations linéaires selon la méthode du pivot maximum. il admet tout type de système, carré ou non. si vous avez plus d'inconnues que d'équations, les inconnues sont exprimées en fonctions des autres de manière à diminuer le nombre d'inconnues. d'abord on rentre la taille du système puis les coefficients, puis les constantes.

Source / Exemple :


#include <math.h>
#include <conio.h>
#include <conio.c>
#define beep printf("%c",0x07);
#define precision 0.0001

void clreos(void)
 {int i,x,y;
  clreol();
  x=wherex(); y=wherey();
  for (i=wherey()+1;i<=25;i++)
    {gotoxy(1,i); clreol();}
  gotoxy(x,y)  ;
 return;
 }   
///////////////////////////////////////////////////////////////////////////////////////////

void afficher(int n,int p, float A[n][p],float B[n], int imposs)
{int ref,i,j,i2; 
 
if (n==0) printf("syst%cme vide",138);
else 
if ((imposs==1) || (n>p)) {textcolor(12); printf("Syst%cme impossible",138); textcolor(7); }
         else if (n==1) 
                      {
                       i=0;
                       while ((i<p) && (A[0][i]!=1))
                              i++;  //i est donc la position d'un "1", il y en a forcément au moins un
                       printf("X%d = ",i+1);
                       ref=0; 
                       for (j=0;j<p;j++)
                            {if (j==i) continue;
                             if (fabs(A[0][j])>precision)
                                    {if ((A[0][j]<0) && (ref==1)) printf("+");
                                     if (A[0][j]==1) {printf("-X%d",j+1); ref=1;}
                                           else if (A[0][j]==-1) {printf("X%d",j+1); ref=1;}
                                                  else {printf("%8.3fX%d",-A[0][j],j+1); ref=1;}
                                    }
                          
                            }
                      if (fabs(B[0])>precision)
                            {if ((ref==1) && (B[0]>0)) printf("+");
                             printf("%8.3f",B[0]);     
                            } 
                      }
               
              else   
              for (i=0;i<n;i++)
               {  
                for (j=0;j<p;j++)
                    if (A[i][j]==1)
                         {i2=0; 
                          while (i2<n)
                              {if (i2==i) {i2++; continue;}
                               if (fabs(A[i2][j])<precision)i2++;
                              }
                          if (i2==n)
                          {printf("X%d",j+1);  i2=j;}//juste pour ne pas perdre l'indice de la valeur déjà écrite
                         }     
                printf(" = ");
                
                ref=0;   //drapeau
                for (j=0;j<p;j++)
                   {if (j==i2) continue;  //tous les autres différents de 0 seront écrits
                      
                      if (fabs(A[i][j])>precision)
                             {if ((ref==1) && (A[i][j]<0)) printf("+");
                             
                              if (A[i][j]==1) {printf("-X%d",j+1); ref=1;}
                                  else if (A[i][j]==-1) {printf("X%d",j+1); ref=1;}
                                        else {printf("%8.3fX%d",-A[i][j],j+1); ref=1;}
                             }                                     
                                      
                   }        
                if (fabs(B[i])>precision)   
                       {if ((ref==1) && (B[i]>0)) printf("+");                
                        printf("%8.3f",B[i]);
                       }
               printf("\n");            
                
               }//fin du for i (pour chaque ligne) et donc fin du else
return;
}//fin de la fonction afficher
////////////////////////////////////////////////////////////////////////////////////////

float saisie (int i, int j)
{float coef;
 int compteur;
 char * coefstring;
 coefstring=(char*)malloc(sizeof(char));
 
    gotoxy(1,8); clreos();
    printf("entrez le nombre [%d][%d] : ",i+1,j+1); 
    gets(coefstring); 
    compteur=sscanf(coefstring,"%f",&coef);
 
 while (compteur!=1)
   {beep
    gotoxy(1,8); clreos();
    printf("entrez le nombre [%d][%d] : ",i+1,j+1); 
    gets(coefstring); 
    //scanf("%s",coefstring);
    compteur=sscanf(coefstring,"%f",&coef);
   }
   
 return coef;
}
/////////////////////////////////////////////////////////////////////////////////////////

float saisie2(int i)
{float coef;
 int compteur;
 char * coefstring;
 coefstring=(char*)malloc(sizeof(char));
 
    gotoxy(1,8); clreos();
    printf("entrez la constante %d : ",i+1); 
    gets(coefstring);
    compteur=sscanf(coefstring,"%f",&coef);  
  
  while (compteur!=1)
   {beep
    gotoxy(1,8); clreos();
    printf("entrez la constante %d : ",i+1); 
    gets(coefstring);
    //scanf("%s",coefstring);
    compteur=sscanf(coefstring,"%f",&coef);
   }
    
 return coef;
}
/////////////////////////////////////////////////////////////////////////////////////////

void resoudre(int n,int p)
{ float A[n][p];
  float B[n];
  
  float max,constante;
  int i,i2,j,rang;
  char refaire,impossible;

 

  for (i=0;i<n;i++)
      for (j=0;j<p;j++)
      A[i][j]=saisie(i,j);
  
  for (i=0;i<n;i++)
      B[i]=saisie2(i);  
  
  
  
  gotoxy(1,wherey()-1); clreos(); 
  printf("Le syst%cme suivant \n",138);;
  for (i=0;i<n;i++)
     {for (j=0;j<p;j++)
         {if ((j>0) && (A[i][j]>=0)) printf("+");  
          printf("%8.3f X%d ",A[i][j],j+1);
         } 
      printf("  =  %8.3f\n",B[i]);
     }

  printf("\nest %cquivalent %c\n",130,133);

  impossible=0;
  for(j=0;(j<n) && (impossible==0);j++)
 {
     refaire=1;
     while (refaire==1)
     {
     /*recherche du max de la jieme ligne*/
     max=A[j][0]; rang=0;
          for(i=1;i<p;i++)
            if (fabs(A[j][i])>fabs(max)) {max=A[j][i];
                                          rang=i;}

           /*verifier que le max n'est pas nul*/
           if (fabs(max)<precision)       //car la gestion de nombres à virgules n'est pas efficace au delà d'un certain rang - equivalent à max==0
                    if (fabs(B[j])>precision) {impossible=1; refaire=0; }     //equivalent à if B[j]!=0 
                    else if (j<(n-1))         //s'il y a encore une équation après
                                  {for(i=0;i<p;i++)            //une equation est combinaison lineaire des autres, elle est donc inutile
                                     A[j][i]=A[n-1][i];       //remonter la n-1 ieme équation en jieme position
                                     B[j]=B[n-1];
                                     n--; refaire=1;
                                   }
                           else { refaire=0;   max=1; //max a une valeur quelconque autre que 0 (pour la division)
                                  n--;
                                }

          else refaire=0;

     }

     /*printf("max = %7.20f\n",max);*/

     if (impossible==0)
        {         /*division de la jieme equation par max*/
          for (i=0;i<p;i++)
             A[j][i]/=max;
             B[j]/=max;

          /*soustractions aux autres equations*/
          for (i=j+1;i<n;i++)    /*pour chaque equation d'après*/
             {constante=A[i][rang];
              B[i]-=constante*B[j];
              for (i2=0;i2<p;i2++)            /*pour chaque coefficient*/
                 A[i][i2]-=constante*A[j][i2];
             }

        }/*fin du if*/

   }/*fin de la boucle j*/

 if ((impossible==0) && (n!=0))
           {
                /*remonter le systeme*/
                for(j=n-1;j>=0;j--)
                   {    max=A[j][0];  rang=0;
                        for(i=0;i<p;i++)
                            if (fabs(A[j][i])>max)  {max=A[j][i]; rang=i;}

                        for(i=0;i<p;i++)
                         A[j][i]/=max;

                        for(i=j-1;i>=0;i--)
                          {   constante=A[i][rang];
                              B[i]-=constante*B[j];
                              for(i2=0;i2<p;i2++)
                                 A[i][i2]-=constante*A[j][i2];
                          }
                    }

              }

  afficher(n,p,A,B,impossible);
 
}//fin de la fonction resoudre
/////////////////////////////////////////////////////////////////////////////////////

int main()
 {int n,p,i;
  char * temp;
  temp=(char*)malloc(sizeof(char));    
  printf("%c",201);
  for (i=1;i<=78;i++) printf("%c",205);
  printf("%c",187);    printf("%c",186);
  printf("                      M%cthode du pivot maximum                                ",130);
  printf("%c",186);   printf("%c",200);
  for (i=1;i<=78;i++) printf("%c",205);
  printf("%c\n\n\n",188);
     
  
      gotoxy(1,7);
      clreos();
      printf("Combien d'%cquations : ",130);
      gets(temp);
      i=sscanf(temp,"%d",&n);
      if (n<=0) i=0;
  
  while (i!=1)
     {beep
      gotoxy(1,7);
      clreos();
      printf("Combien d'%cquations : ",130);
      gets(temp);
      //scanf("%d",&n);
      i=sscanf(temp,"%d",&n);
      if (n<=0) i=0;
     }
  
     
      gotoxy(1,8);
      clreos();
      printf("Combien d'inconnues : ");
      gets(temp);
      //scanf("%d",&p);
      i=sscanf(temp,"%d",&p);
      if (p<=0) i=0;
      
  while  (i!=1)
     {beep
      gotoxy(1,8);
      clreos();
      printf("Combien d'inconnues : ");
      gets(temp);
      //scanf("%d",&p);
      i=sscanf(temp,"%d",&p);
      if (p<=0) i=0;
     }
  
  
  gotoxy(1,7); clreos();
  printf("R%csolution d'un syst%cme  %d x %d\n\n",130,138,n,p);
  
  resoudre(n,p);
 
 printf("\nfini");
 getchar();
 return 0;
 }

Conclusion :


inconvénients : non ansi, peu convivial, lectures non sécurisées ; mais si on n'est pas trop benêt, ça marche impeccable !
autre inconvénient : le programme se trompe si vous mettez des coefficients trop proches les uns des autres (de l'orde du dix-millième), mais faut déjà le vouloir !

avantages (bah ouais, il y en a) : résoud tous types de systèmes linéaires, carrés ou non.

A voir également

Ajouter un commentaire Commentaires
merci c bien
Messages postés
1
Date d'inscription
mardi 27 juillet 2004
Statut
Membre
Dernière intervention
28 juillet 2004

Formidable mais je crois qu'il manque la resolution dual qui n'est d'ailleur, qu'un complement. J'ai fait le même style en qbasic 4.5. J'aimerai aprofondir la chose en C.
On peux gérer du petrole ou tout simplement faire une ration alimentaire équilibrée au moindre cout avec cette méthode.
Messages postés
51
Date d'inscription
lundi 7 juin 2004
Statut
Membre
Dernière intervention
15 juillet 2005

méthode du pivot de gauss ? bah oué, à part juste qu'on pivote sur le maximum, mais sinon, c'est exactement pareil. pour ce qui est de la précision, libre à chacun de la modifier selon ses besoins. le dix millième me suffit générallement, alors ... et la fabs pourrait facilement être remplacée par une simple abs maison qui ne prendrait pas plus de 2 lignes -> faire une fonction complète de comparaison me semble superflu.
Messages postés
1138
Date d'inscription
mardi 10 juin 2003
Statut
Membre
Dernière intervention
25 janvier 2009
3
Ca ne serait pas par pur hasard la methode du pivot de Gauss ... ?
Bon sinon j'aime bien le faite que tu testes avec une precision (un peu petite tout dememe), mais il faudrait peut etre faire un fonction de comparaison de floatant, en plus tu n'aurais pas de fabs a faire.
Messages postés
51
Date d'inscription
lundi 7 juin 2004
Statut
Membre
Dernière intervention
15 juillet 2005

l'algo peut paraître ardu mais en fait c'est très simple. on cherche par des opérations élémentaires sur les lignes à rendre le système triangulaire. puis on le remonte pour isoler les variables. c'est de mon cru.
Afficher les 6 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.