begin process at 2010 02 09 17:30:15
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths & Algorithmes

 > ALGORITHME D'EUCLIDE ETENDU

ALGORITHME D'EUCLIDE ETENDU


 Information sur la source

Note :
Aucune note
Catégorie :Maths & Algorithmes Classé sous :algorithme, euclide, etendu Niveau :Initié Date de création :06/03/2006 Date de mise à jour :06/03/2006 23:53:21 Vu :9 569

Auteur : nickydaquick

Ecrire un message privé
Site perso
Commentaire sur cette source (11)
Ajouter un commentaire et/ou une note

 Description

  Voici une implementation tres simple de l'algorithme d'Euclide Etendu. L'algorithme consiste a trouver pour 2 entiers a et b , 2 autres entiers x et y tels que ax + by = pgcd(a,b).  Cette formule est utile en cryptographie RSA, pour la generation de cle de decryptage pour une cle de cryptage E donnee.

  Il s'agit de ma 2eme source, soyez indulgents je vous en prie ... j'attends vos critiques avec impatience.

Source

  • int find_pgcd(int a , int b)
  • {
  • if(a==0)
  • return b;
  • if(a<b)
  • return find_pgcd(b%a,a);
  • else
  • return find_pgcd(a%b,b);
  • }
  • void algorithme_euclide_ex(int a , int b, int* x, int* y)
  • {
  • /******************************************************
  • *
  • * objectif : retourner x et y tels que
  • * ax + by = pgcd(a,b);
  • * avec a <= b
  • *******************************************************/
  • // posons y1 = -y
  • int x1,y1;
  • int x2,y2;
  • int x3,y3;
  • int status;
  • int reste;
  • int quotient;
  • int pgcd;
  • char positionChangeante;
  • x1 = y1 = 0;
  • x2 = y2 = 0;
  • x3 = y3 = 0;
  • //reordonnons a et b
  • if(a>b)
  • {
  • a ^= b;
  • b ^= a;
  • a ^= b;
  • }
  • // a ce niveau a est inferieur ou egal a b
  • pgcd = find_pgcd(a,b);
  • reste = b%a;
  • quotient = b/a;
  • status = 1; //prochaine mise a jour , les variables x1 , et y1;
  • //on se met a la position bx + ay1 [ notre but c (ax + by1) <= positionChangeante = 0]
  • positionChangeante = 1;
  • //tant que l'on progresse vers la decouverte du pgcd de a et b sans atteindre 0 comme reste
  • while((reste!=pgcd) && (reste!=0))
  • {
  • switch(status)
  • {
  • case 1://mise a jour des variables x1 , et y1;
  • if(!x1)// il s'agit de la premiere mise a jour des variables x1 et y1
  • {
  • x1 = 1;
  • y1 = quotient;
  • }
  • else
  • {
  • x1 = x2 + quotient*y3;
  • y1 = quotient*x3 + y2;
  • }
  • status = 2;//prochaine mise a jour , les variables x2 , et y2;
  • break;
  • case 2://mise a jour des variables x2 , et y2;
  • if(!x2)// il s'agit de la premiere mise a jour des variables x2 et y2
  • {
  • x2 = 1+quotient*y1;
  • y2 = quotient;
  • }
  • else
  • {
  • x2 = x3 + quotient*y1;
  • y2 = quotient*x1 + y3;
  • }
  • status = 3;//prochaine mise a jour , les variables x3 , et y3;
  • break;
  • case 3://mise a jour des variables x3 , et y3;
  • x3 = x1 + quotient*y2;
  • y3 = quotient*x2 + y1;
  • status = 1;//prochaine mise a jour , les variables x1 , et y1;
  • break;
  • }
  • // les prochains operateurs : a et b seront , le b%a et a
  • b = a;
  • a = reste;
  • reste = b%a;
  • quotient = b/a;
  • positionChangeante = !positionChangeante;//on change la position des coefficients
  • }
  • if(status == 1) // si on sort avant la mise a jour de x1 et y1
  • {
  • if(!x1)//on est pas entre dans la boucle
  • {
  • if(b%a==0)// cas de a et b / a divise b
  • {
  • *x = 1;
  • *y = 0;
  • }
  • else // cas de b%a = pgcd(a,b)
  • {
  • *x = -1;
  • *y = -1;
  • }
  • }
  • else //execute le calcul des variables x1, y1 mais dans *x et *y
  • {
  • *x = x2 + quotient*y3;
  • *y = quotient*x3 + y2;
  • }
  • }
  • else if(status == 2) //execute le calcul des variables x2, y2
  • {
  • *x = x3 + quotient*y1;
  • *y = quotient*x1 + y3;
  • }
  • else if(status == 3) //execute le calcul des variables x3, y3
  • {
  • *x = x1 + quotient*y2;
  • *y = quotient*x2 + y1;
  • }
  • //si on est arrive a un changement de position , intervertir les coefficients
  • if(positionChangeante && x1)
  • {
  • *x ^= *y;
  • *y ^= *x;
  • *x ^= *y;
  • }
  • // a ce niveau *y contient y1 / y1 = -y <=> *y = -y
  • *y = 0 - *y; // reajuste y , ce qui donne *y = y
  • }
int find_pgcd(int a , int b)
{
	if(a==0)
		return b;
	if(a<b)
		return find_pgcd(b%a,a);
	else
		return find_pgcd(a%b,b);
}

void algorithme_euclide_ex(int a , int b, int* x, int* y)
{
	/******************************************************
	*
	* objectif : retourner x et y tels que 
	*				ax + by = pgcd(a,b);
	*				  avec a <= b
	*******************************************************/

        // posons y1 = -y

	int x1,y1;
	int x2,y2;
	int x3,y3;
	int status;
	int reste;
	int quotient;

	int pgcd;
	char positionChangeante;

	x1 = y1 = 0;
	x2 = y2 = 0;
	x3 = y3 = 0;

	//reordonnons a et b
	if(a>b)
	{
		a ^= b;
		b ^= a;
		a ^= b;
	}
	// a ce niveau a est inferieur ou egal a b
	pgcd = find_pgcd(a,b);
	
	reste		= b%a;
	quotient	= b/a;

	status = 1;	//prochaine mise a jour , les variables x1 , et y1;

        //on se met a la position bx + ay1 [ notre but c (ax + by1) <= positionChangeante = 0] 
	positionChangeante = 1;

        //tant que l'on progresse vers la decouverte du pgcd de a et b sans atteindre 0 comme reste
	while((reste!=pgcd) && (reste!=0))
	{
		switch(status)
		{
			case 1://mise a jour des variables x1 , et y1;
				if(!x1)// il s'agit de la premiere mise a jour des variables x1 et y1
				{
					x1 = 1;
					y1 = quotient;
				}
				else
				{
					x1 = x2 + quotient*y3;
					y1 = quotient*x3 + y2;
				}
				status = 2;//prochaine mise a jour , les variables x2 , et y2;
				break;

			case 2://mise a jour des variables x2 , et y2;
				if(!x2)// il s'agit de la premiere mise a jour des variables x2 et y2
				{
					x2 = 1+quotient*y1;
					y2 = quotient;
				}
				else
				{
					x2 = x3 + quotient*y1;
					y2 = quotient*x1 + y3;
				}
				status = 3;//prochaine mise a jour , les variables x3 , et y3;
				break;

			case 3://mise a jour des variables x3 , et y3;
				
				x3 = x1 + quotient*y2;
				y3 = quotient*x2 + y1;
				status = 1;//prochaine mise a jour , les variables x1 , et y1;
				break;
		}
		// les prochains operateurs : a et b seront , le b%a et a
		b = a;
		a = reste;
		reste = b%a;
		quotient = b/a;
		positionChangeante = !positionChangeante;//on change la position des coefficients
	}

	if(status == 1) // si on sort avant la mise a jour de x1 et y1
	{
		if(!x1)//on est pas entre dans la boucle
		{
			if(b%a==0)// cas de a et b / a divise b
			{
				*x = 1;
				*y = 0;
			}
			else		// cas de b%a = pgcd(a,b)
			{
				*x = -1;
				*y = -1;
			}
		}
		else	//execute le calcul des variables x1, y1 mais dans *x et *y
		{
			*x = x2 + quotient*y3;
			*y = quotient*x3 + y2;
		}
	}

	else if(status == 2)	//execute le calcul des variables x2, y2
	{
		*x = x3 + quotient*y1;
		*y = quotient*x1 + y3;
	}
	else if(status == 3)    //execute le calcul des variables x3, y3
	{
		*x = x1 + quotient*y2;
		*y = quotient*x2 + y1;
	}

	//si on est arrive a un changement de position , intervertir les coefficients
	if(positionChangeante && x1) 
	{
		*x ^= *y;
		*y ^= *x;
		*x ^= *y;
	}

        // a ce niveau *y contient y1 / y1 = -y <=> *y = -y
        *y = 0 - *y; // reajuste y , ce qui donne *y = y
}

 Conclusion

Enjoy it :D


 Historique

06 mars 2006 23:53:21 :
Corrigé le 6 Mars 2006, au niveau du status 1 lors de l'affectation directe des arguments *x et *y : Deux cas etaient a prendre en compte : a divise b , et b%a = pgcd(a,b) ; j'avais juste mentionne le cas numero 1. MErci

 Sources du même auteur

Source avec Zip LE QUICKSORT NON-RECURSIF ET L'IMPACT DE L'INSERTIONSORT SUR...
QUICKSORT - NON RECURSIF

 Sources de la même categorie

Source avec une capture OPÉRATIONS SUR MATRICES C++ par Minilogus
[DEV-C++] CALCUL DE LA RACINE CARRÉE D'UN RÉEL par Jhep
PROGRAMME QUI CALCUL LE PPCM ET LE PGCD par AnoSantino
EVALUER UNE EXPRESSION MATHÉMATIQUE par begueradj
Source avec Zip Source avec une capture COMPRESSION FICHIERS ALGORITHME HUFFMAN C par xtremejames183

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture RESOLUTION DE SYSTEME LINEAIRE PAR LA METHODE DU GRADIENT CO... par zangul
Source avec Zip ALGO : RESOLUTION "LE COMPTE EST BON" AVEC DES ARBRES BINAIR... par panini21
Source avec une capture CALCUL DE L'ENVELOPPE CONVEXE D'UN NUAGE DE POINTS DANS UN P... par Lucky92
Source avec Zip COMBSORT ALGORITHME DE TRI SIMPLE RAPIDE NON-RECURSIF par xtremejames183
Source avec Zip Source avec une capture SIMPLE ALGORITHME DE CRYPTAGE par Matden000

Commentaires et avis

Commentaire de Cyberboy2054 le 06/03/2006 18:46:25

Ecris ton calcul de pgcd en itératif, c'est bien mieux et pas plus dur:
template<class T>
void Swap (T& a, T& b)
{
T c = b;
b = a;
a = c;
}

int pgcd (int a, int b)
{
int c = 1;
if (a < b)
Swap (a,b); // met le plus grand nombre dans a
while (1)
{
c = a%b;
if (c== 0)
return b;
a = b;
b= c;
}
return -1; // on est jamais a l'abris d'une boulette
}

Commentaire de Pamaury le 06/03/2006 18:51:14

il me semble que c'est ce qu'on appèle les coefficient de Bézout non ?

Commentaire de nickydaquick le 06/03/2006 21:02:30

   Merci pour vos commentaires. Pamaury, tu as absolument raison Les coefficients de Bezout sont x et y tels que ax+by = pgcd(a,b); seulement ils sont trouves ( ou resolus) grace a l'algorithme d'Euclide Etendu.
    Cyberboy2054 , Merci pour ta critique mais ce site est destine a la comprehension des algorithmes , si j'avais mis une version beaucoup plus compliquee et moins commentee en serais - tu satisfait? et je tiens a te dire que le pgcd ne se limite pas a des entiers en passant.
    Merci et aurevoir

Commentaire de Cyberboy2054 le 06/03/2006 21:33:04

Expliquer l'algorithme d'euclide c'est pas dur,
tant que le reste c de la division euclidienne de a par b n'est pas nul, on met b dans a et c dans b, sinon, on renvoit b
Je trouve pas ca plus difficile qu'une fonction récursive, si bien sur c'est détaillé... Apres va falloir que tu m'explique en quoi ta fonction de calcul du pgcd ( find_pgcd ) est plus commentée que la mienne :)
Par contre, je ne savais pas que le pgcd n'etait pas limité qu'aux entiers. J'ai pas trop le temps de chercher la dessus, mais est ce que tu peux détailler un peu plus stp ? Je suis curieux de voir qu'elles applications cela peut avoir. En cryptographie, les entiers (meme s'ils sont tres grands) suffisent il me semble...

Commentaire de Pamaury le 06/03/2006 21:44:52

Cyberboy: ton Swap est inutile car si a<b,
ton algo fera:
c=a%b=a
car a<b et donc
a'=b;b'=c;
donnera:
a'=b;
b'=a;
donc a et b serons inversés et donc ce cas particulier est inutile:

int GetPgcd(int a,int b)
{
    if(b==0)
        return a;
    return GetPgcd(b,a%b);
}

NickyDasuick: moi je l'avais codé comme çà il y a quelques temps:(STL)
typedef std::pair<int,int> BezoutFactors;

BezoutFactors GetBezoutFactors(int a,int b)
{
    //printf("pgcd(%d,%d)=%d\n",a,b,GetPgcd(a,b));
    //printf("%d %% %d = %d\n",a,b,a%b);
    if(b==0)
        return BezoutFactors(1,-1);
    if((a%b)==GetPgcd(a,b))
        return BezoutFactors(1,-(a/b));
    int mult=a/b;
    BezoutFactors factors=GetBezoutFactors(b,a%b);
    //printf("a=%d b=%d mult=%d facts: %d %d\n",a,b,mult,factors.first,factors.second);
    
    return BezoutFactors(factors.second,-factors.second*mult+factors.first);
}

Cela ressemble un peu à ton algo amsi en beaucoup moins compliqué il me semble .
Et cela marche parfaitement d'après mes test.
Bonne soirée

Commentaire de DormeurDev le 07/03/2006 10:21:14

Cyberboy2054
>
"""
Ecris ton calcul de pgcd en itératif, c'est bien mieux et pas plus dur:
template<class T>
void Swap (T& a, T& b)
{
T c = b;
b = a;
a = c;
}

int pgcd (int a, int b)
{
int c = 1;
if (a < b)
Swap (a,b); // met le plus grand nombre dans a
while (1)
{
c = a%b;
if (c== 0)
return b;
a = b;
b= c;
}
return -1; // on est jamais a l'abris d'une boulette
}
"""

dans le code>
"""
# int find_pgcd(int a , int b)
# {
#     if(a==0)
#         return b;
#     if(a<b)
#         return find_pgcd(b%a,a);
#     else
#         return find_pgcd(a%b,b);
# }
"""

En quoi c'est mieux de faire de l'itératif ?
En tout cas ca simplifie pas le problème...

J'attends la réponse avec la plus grande impatience :p

Commentaire de BruNews le 07/03/2006 10:33:38 administrateur CS

La récurrence implique des passages de params et appels de fonction, l'empilage des params est très couteux. Un algo en itératif correctement écrit DOIT être plus performant car il n'a pas tout ces emplilages dépilages.

Commentaire de nickydaquick le 07/03/2006 12:42:55

  Merci pour tous vos commentaires ... Je suis d'avis avec  vous que le recursif est plus couteux que l'iteratif . Seulement comme l'indique le titre de ma source mon but n'est pas d'ecrire une fonction trouver_pgcd , mais trouver les coefficients de Bezout grace a l'algorithme d'euclide etendu. J'aimerais bien avoir des commentaires la dessus. Et en passant , trouver un pgcd c faire des soustractions successives :D . J'attends vos commentaires avec impatience sur mon algorithme d'euclide Etendu.
            Merci et aurevoir

Commentaire de Pamaury le 07/03/2006 18:50:01

moi je t'ai mis un algo dans mon précédent message et il me semble qu'il est plus simple que le tiens mais je me trompe . En tout cas il est en récursif .

Commentaire de nickydaquick le 07/03/2006 21:22:03

Merci Pamaury. Ton algorithme est en effet tres efficace. Je dirais meme que C'est l'algorithme pour les coefficients de Bezout. Moi j'ai en fait tente une autre approche en utilisant une formule tire d'une recurrence par des suites numeriques.
    Merci Pamaury , pour ton commentaire.

Commentaire de svenstek le 11/02/2009 00:16:29

Bonjour je cherche a ecrire un  programme en C qui permet de calculer le pgcd de deux nombres quelconques et de aussi de calculer les coefficients de Bezout avez vous une idée ?

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

algorithme d'euclide [ par dOsSpr0uTosS ] salut à tous, je debute en C++(mais alors vraiment c'est à dire que j'ai commencer y'a une semaine et j'ai pas appris grand chose ...) et donc pour m' programme de l algorithme [ par mery2 ] salut les amis j'ai besoin d un programme en langage c concernant l'algorithme de dijkstra.en utulisant toutes les fonctions et les procedures.merci d algorithme dijkstra [ par mery2 ] salut.j ai d&#233;ja envoyer un message pour vous demander de m'aider pour realiser le programme en langage c de lalgorithme dijkstra et j n ai pas re implémentation de l'algorithme de huffman [ par sousou25 ] sousou25bonsoir &#224; vous tous,d&#233;sol&#233;e du d&#233;rangmt mais je voudrais savoir cmt&nbsp;utiliser des tableaux pour l'impl&#233;mentation un algorithme en c++ du routage avec roy warshall [ par amicole ] je voudrais recevoir un algorithme de routage avec roy warshall,algorithme de parcours en profondeur,en largeur ,algorithme de marimot,de foulkes (en algorithme du morpion en c [ par amoated ] bonjour à tous, je suis débutant en programmation et j'aimerais avoir l'algo du morpion en langage c. Merci de me répondre. Algorithme des nombres aleatoires [ par goast_tu ] Salut! Pour mon application j'ai besoin programmer l'algorithme de Prim en c [ par alkaram ] Bonjour tout le monde,Je suis entrain de chercher à programmer l'algorithme de Prim en langage c.Si quelqu'un à une idée, veuillez me contacter.merci Algorithme de Bellman Ford, chemin le plus cours [ par Nuggy ] Bonjour :je recherche de l'aide pour un programme en c++, le travail consiste a réaliser un algorithme de Bellman Ford .Cet algo permet de calculer le Quelques questions sur rsa [ par jean84 ] Salut a tous ! Je me suis interesse a l'algorithme de cryptage rsa il y a quelque temps mais j'avoue avoir encore du mal avec certains points


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), 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

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,747 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales