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

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

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.