Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

MULTIPLICATION MATRICIELLE ENCHAINEE


Information sur la source

Catégorie :Maths & Algorithmes Classé sous : multiplication, dynamique, algorithmique, produit, matrice Niveau : Initié Date de création : 26/09/2006 Date de mise à jour : 26/09/2006 15:46:34 Vu / téléchargé: 4 503 / 172

Note :
8 / 10 - par 1 personne
8,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (1)
Ajouter un commentaire et/ou une note

Description

Cette source s'appuye sur la programmation dynamique, afin de résoudre le problème de la multiplication matricielle enchainée.(i.e trouver le meilleur choix de placer des parenthèses sur un produit de n matrices A1 x A2 x ... x An). Et oui !!, si le placement des parenthèses est mauvais le coût de calcul peut morfler grave ! On fournit en entrée les dimensions des n matrices que l'on shouaite multiplier et le programme nous indique ou placer les parenthèses
 

Source

  • //------------------------------------------------------------------------------//
  • // "ChainedMatrix.cpp"
  • //
  • // Programme montrant l'application de la programmation dynamique.
  • // Problème de la multiplication matricielle enchaînée. Il faut trouver le
  • // parenthésage optimal qui multiplie les matrices [A1 x A2 x...x An] de manière
  • // à nous donner un coût optimal. C'est à dire minimisant le nombre de produits
  • // scalaires.
  • //------------------------------------------------------------------------------//
  • // Rappel Mathématique :
  • //
  • // [0]
  • // Par convention dans notre produit matricielle enchaîné
  • // on dira qu'une matrice Ai est de dimension pi-1 x pi
  • //
  • // [1]
  • // Multiplier une matrice A de dimension p x q
  • // avec une matrice B de dimension q x r
  • // donne une matrice C de dimension p x r
  • //
  • // [2]
  • // Le temps de calcul de C (= le coût) est déterminé par le nombre
  • // de multiplications scalaires nécessaires pour 'remplir' C
  • // = p x q x r
  • #include <cstdlib>
  • #include <iostream>
  • #include <algorithm>
  • using namespace std;
  • void PrintArray(int* * tabToPrint,int size);
  • void RemplirTableau(int* dim, int size);
  • void Afficher_Parenthesage_Optimal(int * * S, int i, int j);
  • //-----------------------------------------------------------------------------
  • // Name : RemplirTableau
  • // Parameter : Les dimensions des matrices
  • // Desc : Cette fonction va déterminer le nombre optimal de multiplications
  • // scalaires nécessaires pour calculer le produit d'une suite de matrices.
  • // On se base sur la fonction récursive suivante
  • //
  • // | 0 si i=j
  • // m[i,j] = |
  • // | min { m[i,k] + m[k+1,j] + pi-1 x pk x pj
  • //
  • // On remplit le tableau M des valeurs optimales. Le tableau S, contient
  • // la valeur de k tel que le produit est optimal.
  • // ( k = ou placer les parenthéses)
  • //-----------------------------------------------------------------------------
  • void RemplirTableau(int* * S, int* * M, int* dim, int size)
  • {
  • int n = size;
  • int j = 0; int q=0;
  • for(int i2=0; i2<n; i2++)
  • {
  • // On remplit la diagonale de 0
  • M[i2][i2] = 0;
  • }
  • // l correspond aux sous-chaines de matrices a multiplier
  • // On commence par calculer les sous chaines de 2, puis 3, et
  • // pour finir on obtiendra la valeur optimale pour la chaine entière
  • for(int l=2; l<=n; l++)
  • {
  • for(int i=0; i<=n-l; i++)
  • {
  • j = i+l-1;
  • M[i][j] = 10000000;
  • // On essaye toutes les valeurs de k afin de trouver le k optimal
  • // qui va donner le meilleur coût pour le produit
  • for(int k=i; k<j; k++)
  • {
  • // formule de récurrence
  • q = M[i][k] + M[k+1][j] + (dim[i] * dim[k+1] * dim[j+1]);
  • // si le q est meilleur celui calculé précedemment
  • // on le garde ainsi que la valeur k
  • if (q < M[i][j] )
  • {
  • M[i][j] = q;
  • S[i][j] = k;
  • }
  • }//for k
  • }
  • }//for l
  • }
  • //-----------------------------------------------------------------------------
  • // Name : Afficher_Parenthesage_Optimal
  • // Desc : Affiche le parenthesage optimal des matrices en se basant sur le
  • // tableau S
  • //-----------------------------------------------------------------------------
  • void Afficher_Parenthesage_Optimal(int * * S, int i, int j)
  • {
  • if(i==j) cout << "A" << i+1;
  • else
  • {
  • cout << "( ";
  • Afficher_Parenthesage_Optimal(S, i, S[i][j]);
  • Afficher_Parenthesage_Optimal(S, S[i][j]+1, j);
  • cout << " )";
  • }
  • }
  • //-----------------------------------------------------------------------------
  • // Name : PrintArray
  • // Desc : Imprime un tableau a 2 dimensions
  • //-----------------------------------------------------------------------------
  • void PrintArray(int* * tabToPrint,int size)
  • {
  • for(int i=0;i<size;i++)
  • {
  • for(int j=0;j<size;j++)
  • {
  • cout << tabToPrint[i][j] << " ,";
  • }
  • cout << endl;
  • }
  • }
  • int main()
  • {
  • int n; int b;
  • int indice=0;
  • cout << "Entrez le nombre de matrices a multiplier" << endl;
  • cin >> n;
  • // Tableau qui va contenir les dimensions des lignes des n matrices
  • // + le nombre de colonne de la dernière matrice
  • int* dimMatrix = new int[n+1];
  • // Tableau a remplir par notre algo dynamique
  • // Ex M[2][4] = coût optimal du calcul A2 x A3 x A4
  • // dimension 1 : tableau de 10 pointeurs vers des tableaux d'entiers
  • int* *M = new int* [n];
  • // initialiser les 10 pointeurs à 0 (NULL)
  • fill_n( M, n, static_cast<int*>(0));
  • // dimension 2 : les tableaux d'entiers
  • for ( int i = 0; i < n; ++i)
  • {
  • M[i] = new int[n];
  • }
  • // Tableau contenant le k optimal
  • // Ex S[2][4] = k optimal pour parentheser A2 x A3 x A4
  • // dimension 1 : tableau de 10 pointeurs vers des tableaux d'entiers
  • int* *S = new int* [n];
  • // initialiser les 10 pointeurs à 0 (NULL)
  • fill_n(S, n, static_cast<int*>(0));
  • // dimension 2 : les tableaux d'entiers
  • for ( int i = 0; i < n; ++i)
  • {
  • S[i] = new int[n];
  • }
  • // Initialisation des tableaux
  • for(int i=0;i<n;i++){
  • for(int j=0;j<n;j++){
  • M[i][j] = 0;
  • S[i][j] = 0;
  • }
  • }
  • // On remplit le tableau des dimensions correspondantes
  • for(b=0; b<n; b++)
  • {
  • cout << "Entrer le nombre de lignes de la matrice " << b+1 <<endl;
  • cin >> indice;
  • dimMatrix[b] = indice;
  • }
  • cout << "Entrez le nombre de colonnes pour la matrice " << n << endl;
  • cin >> indice;
  • dimMatrix[b] = indice;
  • RemplirTableau(S,M,dimMatrix, n);
  • //PrintArray(M,n);
  • //cout << endl;
  • //PrintArray(S,n);
  • cout << " Le meilleur choix des parentheses est le suivant ==> ";
  • cout << endl;
  • Afficher_Parenthesage_Optimal(S, 0, n-1);
  • cout << endl;
  • delete[] S;
  • delete[] M;
  • system("PAUSE");
  • }
//------------------------------------------------------------------------------//
//				"ChainedMatrix.cpp"
//
// Programme montrant l'application de la programmation dynamique.
// Problème de la multiplication matricielle enchaînée. Il faut trouver le 
// parenthésage optimal qui multiplie les matrices [A1 x A2 x...x An] de manière 
// à nous donner un coût optimal. C'est à dire minimisant le nombre de produits
// scalaires.
//------------------------------------------------------------------------------//

// Rappel Mathématique :
//
// [0]
// Par convention dans notre produit matricielle enchaîné
// on dira qu'une matrice Ai est de dimension pi-1 x pi
//
// [1]
// Multiplier une matrice A de dimension p x q 
// avec une matrice B de dimension q x r 
// donne une matrice C de dimension p x r
//
// [2]
// Le temps de calcul de C (= le coût) est déterminé par le nombre 
// de multiplications scalaires nécessaires pour 'remplir' C 
// = p x q x r

#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

void PrintArray(int* * tabToPrint,int size);
void RemplirTableau(int* dim, int size);
void Afficher_Parenthesage_Optimal(int * * S, int i, int j);

//-----------------------------------------------------------------------------
// Name	: RemplirTableau
// Parameter : Les dimensions des matrices
// Desc : Cette fonction va déterminer le nombre optimal de multiplications
// scalaires nécessaires pour calculer le produit d'une suite de matrices.
// On se base sur la fonction récursive suivante
//
//          |	0			si i=j
// m[i,j] = |
//	    |   min { m[i,k] + m[k+1,j] + pi-1 x pk x pj 
// 
// On remplit le tableau M des valeurs optimales. Le tableau S, contient 
// la valeur de k tel que le produit est optimal. 
// ( k = ou placer les parenthéses)
//-----------------------------------------------------------------------------
void RemplirTableau(int* * S, int* * M, int* dim, int size)
{
   int n = size;
   int j = 0; int q=0;
   for(int i2=0; i2<n; i2++)
   {
      // On remplit la diagonale de 0
	  M[i2][i2] = 0;
   }

   // l correspond aux sous-chaines de matrices a multiplier
   // On commence par calculer les sous chaines de 2, puis 3, et
   // pour finir on obtiendra la valeur optimale pour la chaine entière
   for(int l=2; l<=n; l++)
   {
	   for(int i=0; i<=n-l; i++)
	   {
          j = i+l-1;
		  M[i][j] = 10000000;
	   
		  // On essaye toutes les valeurs de k afin de trouver le k optimal
		  // qui va donner le meilleur coût pour le produit
		  for(int k=i; k<j; k++)
		  {
		     // formule de récurrence
			 q = M[i][k] + M[k+1][j] + (dim[i] * dim[k+1] * dim[j+1]);

			 // si le q est meilleur celui calculé précedemment
			 // on le garde ainsi que la valeur k
			 if (q < M[i][j] )
			 {
			    M[i][j] = q;
				S[i][j] = k;
			 }
		  }//for k
	   }
   }//for l

}
//-----------------------------------------------------------------------------
// Name	: Afficher_Parenthesage_Optimal
// Desc : Affiche le parenthesage optimal des matrices en se basant sur le 
//             tableau S
//-----------------------------------------------------------------------------
void Afficher_Parenthesage_Optimal(int * * S, int i, int j)
{
   if(i==j) cout << "A" << i+1;
   else 
   {
	 cout << "( ";
     Afficher_Parenthesage_Optimal(S, i, S[i][j]);
	 Afficher_Parenthesage_Optimal(S, S[i][j]+1, j);
	 cout << " )";
	}
   
}
//-----------------------------------------------------------------------------
// Name	: PrintArray
// Desc : Imprime un tableau a 2 dimensions 
//-----------------------------------------------------------------------------
void PrintArray(int* * tabToPrint,int size)
{
   for(int i=0;i<size;i++)
   {
      for(int j=0;j<size;j++)
	  {
         cout << tabToPrint[i][j] << " ,"; 
      }
	  cout << endl;
   }
}

int main()
{
   
   int n; int b;
   int indice=0;
   cout << "Entrez le nombre de matrices a multiplier" << endl;
   cin  >> n;
   
   // Tableau qui va contenir les dimensions des lignes des n matrices 
   // + le nombre de colonne de la dernière matrice
   int* dimMatrix = new int[n+1];
   
   // Tableau a remplir par notre algo dynamique
   // Ex M[2][4] = coût optimal du calcul A2 x A3 x A4
   
   // dimension 1 : tableau de 10 pointeurs vers des tableaux d'entiers
   int* *M = new int* [n];
   
   // initialiser les 10 pointeurs à 0 (NULL)
   fill_n( M, n, static_cast<int*>(0));
   
   // dimension 2 : les tableaux d'entiers
    for ( int i = 0; i < n; ++i)
    {
        M[i] = new int[n];
    }

   // Tableau contenant le k optimal
   // Ex S[2][4] = k optimal pour parentheser A2 x A3 x A4 
   
   // dimension 1 : tableau de 10 pointeurs vers des tableaux d'entiers
   int* *S = new int* [n];
   
   // initialiser les 10 pointeurs à 0 (NULL)
   fill_n(S, n, static_cast<int*>(0));
   
   // dimension 2 : les tableaux d'entiers
    for ( int i = 0; i < n; ++i)
    {
        S[i] = new int[n];
    }
   
   // Initialisation des tableaux
   for(int i=0;i<n;i++){
	   for(int j=0;j<n;j++){
		   M[i][j] = 0;
		   S[i][j] = 0;
	   }
   }
   // On remplit le tableau des dimensions correspondantes
   for(b=0; b<n; b++)
   {
	  cout << "Entrer le nombre de lignes de la matrice " << b+1 <<endl;
	  cin  >> indice;
	  dimMatrix[b] = indice;
   }
   cout << "Entrez le nombre de colonnes pour la matrice " << n << endl;
   cin  >> indice;
   dimMatrix[b] = indice;


   RemplirTableau(S,M,dimMatrix, n);
   //PrintArray(M,n);
   //cout << endl;
   //PrintArray(S,n);
   cout << " Le meilleur choix des parentheses est le suivant ==>   ";
   cout << endl;
   Afficher_Parenthesage_Optimal(S, 0, n-1);
   cout << endl;
   delete[] S;
   delete[] M;
   system("PAUSE");

}

Conclusion

Le zip contient tout le projet en VC++
 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

26 septembre 2006 15:46:34 :
Mise a jour de la mise en page

Commentaires et avis

signaler à un administrateur
Commentaire de yann_lo_san le 26/09/2006 21:38:32

C'est très utile, je te met 8.
Mais cela aurait été plus clair avec une classe matrice avec opérateurs enchainables.
Voici une spécification quui pourrait marcher.

#pragma once
#include <iostream>

class Matrice
{
int** m_t;
int   m_nbrLignes;
int   m_nbrColonnes;
public:
Matrice(int=3, int=3);
Matrice(const Matrice&);
~Matrice();
friend Matrice operator * (int, const Matrice&);
Matrice operator + (const Matrice&) const;
const Matrice& oprator = (const Matrice&);
friend istream& operator >> (istream&, Matrice&);
friend ostream& operator << (ostream&, const Matrice&);
};

// Attrention au constructeur de copie !
Matrice::Matrice(const Matrice& matCopie)
{
m_nbrLignes = matCopie.m_nbrLignes;
m_nbrColonnes = matCopie.m_nbrColonnes;
m_t = new int*[m_nbrLignes];

for(int i=0; i<m_nbrLignes; i++)
{
m_t[i] = new int[m_nbrColonnes];
for(int j=0; j<m_nbrColonnes; j++)
m_t[i][j] = matCopie.m_t[i][j];
}
}

// pour le reste c'est du tout cuit.

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

allococation dynamique d'une matrice carre en C [ par pedu ] COMMENT ALLOUER DYNAMIQUEMENT AVEC malloc UNE MATRICE CARRE DE DIMENSION[1][1] AFIN DE LA DIMENSIONNER A SA GUISE ET DE LA MANIPULER COMME UN TABLEAU[ Matrice dynamique mal allouée [ par wolflinger ] Bonjour, Je souhaite cr&#233;er une matrice dynamique de type (int **Mat) en C. Mais j'ai un soucis &#224; l'allocation de m&#233;moire. Voici mon co Allocation Dynamique d'une Matrice Help [ par EMSIEN ] Salut à vous toutes et à vous tous,voilà je veux déclarer une matrice de la sorte:     int** MaMatrice;  dans Une ClassePuis au Niveau du Contructeur Multiplication de matrice symétrique [ par sortileges125 ] Voilà mon problème,Je cherche à faire une multiplication de deux matrices symétriques mais seulement avec la partie supérieure ou la partie inférieure constructeur [ par maymouna2008 ] salut t le monde svp repondez moi a cet question:c est une clase matrice chaqu ligne de la matrice représenté par un tableau dynamique ainsi tt les li inverse de matrice dynamique [ par anaisa ] Aidez nous please c pr programmer en langage Votre texte ICIC l inverse de la matrice dynamique merci bcp !!!!!! matrice [ par rif59 ] bonjour; je suis debutant en C++,en fait j'ai un probleme avec ce programme:void produit_vect_mat(double b quadrillage matrices [ par Gaston0510 ] Notre prof d cours nous a demand¨¦ de saisir et afficher des matrices .Les matrices affich¨¦ doivent etr entour¨¦ avec un double qudrillage on utilisa creer une matrice [ par rif59 ] bonjour, on fait j veu creer une matrice de n ligne et de 5 colonnes; j'ai fé un  programme mais ça marche pas, quelcun peut me dire comment faire, ça probleme de compilation DEBUG ERROR DAMAGE AFTER NORMAL BLOCK [ par ali_saguer1 ] Bonjour, Il se trouve que j'ai un projet en C++ et je suis complètement bloqué. A la fin de l'exécutionde mon projet , j'obtient le resultat que j'ai


Nos sponsors

Sondage...

CalendriCode

Octobre 2008
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,296 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.