begin process at 2012 02 08 09:33:03
  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 :13 125

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 Zip UN EXAMPLE D'APPLICATION EN CUDA DE L'ALGORITHME DE SCAN POU... par oguzaras
Source avec Zip Source avec une capture CHIFFREMENT DE VIGENERE par lajouad
Source avec Zip Source avec une capture ANALYSE SYNTAXIQUE par lajouad
Source avec Zip Source avec une capture STRUCTURE D'UNE MATRICE PAR LES LISTE LINÉAIRE (NON CONTUGUS... par benzarabel
Source avec Zip Source avec une capture DESSINER UNE ARBRE BINAIRE( MODE CONSOLE): par benzarabel

 Sources en rapport avec celle ci

Source avec Zip UN EXAMPLE D'APPLICATION EN CUDA DE L'ALGORITHME DE SCAN POU... par oguzaras
Source avec Zip Source avec une capture RÉSOLUTION SUDOKU (9X9) PAR BACKTRACKING RÉCURSIF INTELLIGEN... par Gallien69
GÉRER UN COMBAT DANS UN JEU 2D / ALGORITHME PRIMAIRE D'UNE I... par Chiheb2010
Source avec Zip BELLMAN:LA VALEUR DU PLUS COURT CHEMIN ET LE PLUS COURT CHEM... par Perace
Source avec Zip COMPRESSION / DECOMPRESSION SELON L'ALGORITHME LEMPELZIV 78V par th1man

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...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
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,482 sec (3)

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