/*************************************************************************************************************************************/
/* */
/* R E S O L U T I O N D ' U N S Y S T E M E L I N E A I R E D E D E U X E Q U A T I O N S */
/* E T D E D E U X I N E Q U A T I O N S A ' N ' I N C O N N U E S */
/* P A R U N E M E T H O D E D U T Y P E " R E C U I T S I M U L E " : */
/* */
/* */
/* Fonction : */
/* */
/* Ce programme resoud le systeme */
/* suivant d'equations : */
/* */
/* i=N-1 */
/* S (V ) = SV */
/* i=0 i */
/* */
/* i=N-1 */
/* S (C1 .V ) = SC1V */
/* i=0 i i */
/* */
/* i=N-1 i=N-1 */
/* S (C2 .V ) <= SC2V < S (C2 .V ) */
/* i=0 i-1 i i=0 i i */
/* */
/* Author of '$xtc/recuit_si.21$c' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, AAAAMMJJhhmmss). */
/* */
/*************************************************************************************************************************************/
#include "INCLUDES.01.I"
/* Introduit le 20051116102057... */
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S D E C O N T R O L E ( O U P A R A M E T R E S " P R I M A I R E S " ) : */
/* */
/*************************************************************************************************************************************/
#define Nvariables \
8 \
/* Nombre de variables. */
#define FACTEUR_DE_L_INCREMENT \
2.00 \
/* Facteur de calcul de 'facteur_de_l_increment'... */
#define PROBABILITE \
0.8 \
/* Probabilite d'agir sur l'une des variables lors de la perturbation aleatoire. ATTENTION, */ \
/* les conventions sont inversees (c'est-a-dire que plus 'PROBABILITE' est proche de 0, */ \
/* plus il y a de chance de perturber la variable courante, alors que plus elle est proche */ \
/* de 1, moins il y a de chance...). */
#define ITERATIONS \
2000000 \
/* Nombre maximal d'iterations avant d'arreter le programme. */
#define PRECIS \
double \
/* Doit-on travailler en entier ('int') ou non ('double') ? */
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S D E R I V E E S ( O U P A R A M E T R E S " S E C O N D A I R E S " ) : */
/* */
/*************************************************************************************************************************************/
#define NON_CONVERGENCE \
(ITERATIONS/20) \
/* Nombre maximal d'iterations avant de detecter la non convergence, et de reinitialiser */ \
/* partiellement. */
/*************************************************************************************************************************************/
/* */
/* C O N S T A N T E S : */
/* */
/*************************************************************************************************************************************/
#define INDEX0 \
0
/*************************************************************************************************************************************/
/* */
/* P R O C E D U R E S U T I L E S : */
/* */
/*************************************************************************************************************************************/
#define INTE(x) \
((int)(x)) \
/* Partie entiere. */
#define FLOT(x) \
((double)(x)) \
/* Conversion flottante. */
#define DEBUG(sequence) \
; \
/* Pour n'executer 'sequence' qu'en cas de besoin... */
#define TEST(sequence) \
; \
/* Pour n'executer 'sequence' qu'en cas de besoin... */
#define SOMME_REELLE_MAXIMALE_VARIABLES \
1000 \
/* Valeur maximale a priori de la somme theorique des variables pour generer le cas reel. */
#define REINITIALISATION(probabilite) \
{ \
DEBUG(printf("\n\n reinitialisation :\n");); \
\
SommeVariables=0; \
SommeCoefficients1Variables=0; \
SommeCoefficients2SupVariables=0; \
SommeCoefficients2InfVariables=0; \
\
for (index1=INDEX0 ; index1<Nvariables ; index1++) \
{ \
if (ALEATOIRE_0_p1>=probabilite) \
{ \
switch (methode) \
{ \
case 1: \
{ \
Variables[index1]=INTE(ALEATOIRE_0_p1*(ExacteSommeVariables/Nvariables)); \
break; \
} \
case 2: \
{ \
Variables[index1]=INTE(SOMME_REELLE_MAXIMALE_VARIABLES/Nvariables); \
break; \
} \
case 3: \
{ \
Variables[index1]=INTE((SOMME_REELLE_MAXIMALE_VARIABLES/Nvariables) \
*(-((double)index1/((double)(Nvariables-1)))+1) \
); \
break; \
} \
default: \
{ \
printf("\n methode non implementee"); \
break; \
} \
} \
\
BestVariables[index1]=Variables[index1]; \
/* Initialisation des "meilleures" valeurs rencontrees. */ \
\
SommeVariables=SommeVariables+Variables[index1]; \
SommeCoefficients1Variables=SommeCoefficients1Variables \
+(Variables[index1]*Coefficients1[index1]); \
SommeCoefficients2SupVariables=SommeCoefficients2SupVariables \
+(Variables[index1]*Coefficients2[index1]); \
if (index1>INDEX0) \
{ \
SommeCoefficients2InfVariables=SommeCoefficients2InfVariables \
+(Variables[index1]*Coefficients2[index1-1]); \
} \
else \
{ \
} \
} \
else \
{ \
} \
} \
\
DEBUG(printf("\n somme des variables=%d",SommeVariables);); \
DEBUG(printf("\n somme ponderee 1 des variables=%f",FLOT(SommeCoefficients1Variables));); \
DEBUG(printf("\n somme ponderee 2 des variables=%f",FLOT(SommeCoefficients2SupVariables));); \
DEBUG(printf("\n somme ponderee 3 des variables=%f",FLOT(SommeCoefficients2InfVariables));); \
} \
/* Reinitialisation des variables partielle ou globale... */
#define CumulVariables(somme) \
{ \
somme=somme+Variables[index1]; \
}
#define CumulCoefficients1Variables(somme) \
{ \
somme=somme+(Coefficients1[index1]*Variables[index1]); \
}
#define CumulCoefficients2SupVariables(somme) \
{ \
somme=somme+(Coefficients2[index1]*Variables[index1]); \
}
#define CumulCoefficients2InfVariables(somme) \
{ \
if (index1>INDEX0) \
{ \
somme=somme+(Coefficients2[index1-1]*Variables[index1]); \
} \
else \
{ \
} \
}
/* Procedures diverses de cumul. */
#define StoreVecteur(vecteur,index,valeur) \
{ \
if ((index>=INDEX0) && (index<Nvariables)) \
{ \
vecteur[index]=valeur; \
} \
else \
{ \
printf("\n ATTENTION : un index (%d) sort des limites [%d,%d]",index,INDEX0,Nvariables-1); \
} \
}
/* Rangement avec validation d'un element d'un vecteur. */
/*************************************************************************************************************************************/
/* */
/* G E N E R A T E U R A L E A T O I R E : */
/* */
/*************************************************************************************************************************************/
#define TOUJOURS \
0.00
#define PARFOIS \
0.75
#define JAMAIS \
1.00
/* Quelques probabilites utiles. ATTENTION, les conventions sont inversees (c'est-a-dire */
/* que plus on est proche de 0, plus l'evenement est probable, alors que plus on est proche */
/* de 1, moins l'evenement est probable...). */
extern double srand48();
extern double drand48();
#define ALEATOIRE \
(random())
#define ALEATOIRE_0_p1 \
(ALEATOIRE)
#define ALEATOIRE_m1_p1 \
(2.0*(ALEATOIRE-0.5))
/* Valeur aleatoire dans [0,+1] et dans [-1,+1]. Utilise 'drand48()' ou 'random()'. */
int initialiser_random=VRAI;
int taux=3.0;
double valeur_random=0.5;
double random()
{
int index;
for (index=1 ; index<=((initialiser_random==VRAI) ? 200 : 1) ; index++)
{
int iterer=VRAI;
while (iterer==VRAI)
{
valeur_random=((taux+1)*valeur_random)-(taux*valeur_random*valeur_random);
if ((valeur_random>=0.0) && (valeur_random<=1.0))
{
iterer=FAUX;
}
else
{
}
}
}
initialiser_random=FAUX;
return(valeur_random);
}
/*************************************************************************************************************************************/
/* */
/* P R O G R A M M E : */
/* */
/*************************************************************************************************************************************/
main()
{
int methode=1;
int iteration,iterer,non_convergence;
int index1,index2;
int Variables[Nvariables],SaveVariables[Nvariables],BestVariables[Nvariables];
int ExacteSommeVariables;
int SommeVariables,SaveSommeVariables;
int increment;
PRECIS Coefficients1[Nvariables];
PRECIS ExacteSommeCoefficients1Variables;
PRECIS SommeCoefficients1Variables,SaveSommeCoefficients1Variables;
PRECIS Coefficients2[Nvariables];
PRECIS ExacteSommeCoefficients2Variables;
PRECIS SommeCoefficients2SupVariables;
PRECIS SommeCoefficients2InfVariables;
double facteur_de_l_increment;
StoreVecteur(Coefficients1,0,300);
StoreVecteur(Coefficients1,1,450);
StoreVecteur(Coefficients1,2,670);
StoreVecteur(Coefficients1,3,1150);
StoreVecteur(Coefficients1,4,1600);
StoreVecteur(Coefficients1,5,2100);
StoreVecteur(Coefficients1,6,2800);
StoreVecteur(Coefficients1,7,3300);
StoreVecteur(Coefficients2,0,20);
StoreVecteur(Coefficients2,1,50);
StoreVecteur(Coefficients2,2,100);
StoreVecteur(Coefficients2,3,250);
StoreVecteur(Coefficients2,4,500);
StoreVecteur(Coefficients2,5,1000);
StoreVecteur(Coefficients2,6,2000);
StoreVecteur(Coefficients2,7,3000);
/* Definition a priori des coefficients. ATTENTION, le nombre de ces initialisations ne */
/* peut etre parametrer par 'Nvariables'... */
/*************************************************************************************************************************************/
/* */
/* C O N S T R U C T I O N D E L A S O L U T I O N E X A C T E Q U I S E R A */
/* E N S U I T E R E C H E R C H E E I T E R A T I V E M E N T : */
/* */
/*************************************************************************************************************************************/
printf("\n solution exacte :\n");
ExacteSommeVariables=0;
ExacteSommeCoefficients1Variables=0;
ExacteSommeCoefficients2Variables=0;
for (index1=INDEX0 ; index1<Nvariables ; index1++)
{
int ListeTest[Nvariables]={6,3,1,2,0,0,0,0};
/* Cette liste, associee a 'TEST(...)' permet de forcer les valeurs de 'variable'. */
int variable=INTE(ALEATOIRE_0_p1*(SOMME_REELLE_MAXIMALE_VARIABLES/Nvariables));
TEST(variable=ListeTest[index1];);
printf("\n variables(%d)=%d",index1,variable);
ExacteSommeVariables=ExacteSommeVariables+variable;
ExacteSommeCoefficients1Variables=ExacteSommeCoefficients1Variables+(variable*Coefficients1[index1]);
for (index2=INDEX0 ; index2<variable ; index2++)
{
PRECIS increment=INTE(ALEATOIRE_0_p1*Coefficients2[index1]);
if ((index1>INDEX0) && (increment<=Coefficients2[index1-1]))
{
increment=Coefficients2[index1-1]+1;
}
else
{
}
ExacteSommeCoefficients2Variables=ExacteSommeCoefficients2Variables+increment;
}
}
printf("\n\n somme des variables=%d",ExacteSommeVariables);
printf("\n somme reelle ponderee 1 des variables=%f",FLOT(ExacteSommeCoefficients1Variables));
printf("\n somme reelle ponderee 2 des variables=%f",FLOT(ExacteSommeCoefficients2Variables));
printf("\n");
/*************************************************************************************************************************************/
/* */
/* I N I T I A L I S A T I O N D E L A R E S O L U T I O N I T E R A T I V E : */
/* */
/*************************************************************************************************************************************/
DEBUG(printf("\n\n\n iterations :"););
facteur_de_l_increment=FACTEUR_DE_L_INCREMENT*FLOT(ExacteSommeVariables)/FLOT(Nvariables);
if (facteur_de_l_increment<2.0)
{
printf("\n\n ATTENTION : afin que le calcul de 'increment' ne redonne pas toujours la meme valeur, on majore");
printf("\n facteur=%f",facteur_de_l_increment);
facteur_de_l_increment=2.0;
}
else
{
}
REINITIALISATION(TOUJOURS);
/*************************************************************************************************************************************/
/* */
/* R E S O L U T I O N I T E R A T I V E : */
/* */
/*************************************************************************************************************************************/
iterer=VRAI;
iteration=0;
non_convergence=0;
while (iterer==VRAI)
{
iteration=iteration+1;
if (iteration>ITERATIONS)
{
iterer=FAUX;
/* Trop d'iterations ont ete effectuees. */
}
else
{
}
SommeVariables=0;
SommeCoefficients1Variables=0;
SommeCoefficients2SupVariables=0;
SommeCoefficients2InfVariables=0;
SaveSommeVariables=0;
SaveSommeCoefficients1Variables=0;
for (index1=INDEX0 ; index1<Nvariables ; index1++)
{
CumulVariables(SaveSommeVariables);
CumulCoefficients1Variables(SaveSommeCoefficients1Variables);
SaveVariables[index1]=Variables[index1];
/* Sauvegarde de l'etat avant la perturbation... */
if (ALEATOIRE_0_p1>PROBABILITE)
{
increment=INTE(facteur_de_l_increment*ALEATOIRE_m1_p1);
/* Calcul de la perturbation aleatoire de la variable courante... */
if ((Variables[index1]+increment)>0)
{
Variables[index1]=Variables[index1]+increment;
/* Perturbation aleatoire... */
}
else
{
}
}
else
{
}
CumulVariables(SommeVariables);
CumulCoefficients1Variables(SommeCoefficients1Variables);
CumulCoefficients2SupVariables(SommeCoefficients2SupVariables);
CumulCoefficients2InfVariables(SommeCoefficients2InfVariables);
}
if ( (ABSO(SommeCoefficients1Variables-ExacteSommeCoefficients1Variables)
>=ABSO(SaveSommeCoefficients1Variables-ExacteSommeCoefficients1Variables)
)
|| (ABSO(SommeVariables-ExacteSommeVariables)
>=ABSO(SaveSommeVariables-ExacteSommeVariables)
)
|| ( (ExacteSommeCoefficients2Variables>=SommeCoefficients2SupVariables)
|| (ExacteSommeCoefficients2Variables<SommeCoefficients2InfVariables)
)
)
/* Cas ou l'etat perturbe est moins bon que l'etat anterieur : */
{
non_convergence=non_convergence+1;
/* Detecteur de non convergence. */
if (non_convergence < NON_CONVERGENCE)
{
for (index1=INDEX0 ; index1<Nvariables ; index1++)
{
Variables[index1]=SaveVariables[index1];
/* On revient alors a l'etat anterieur... */
}
}
else
{
REINITIALISATION(PARFOIS);
}
}
else
/* Cas ou l'etat perturbe est meilleur que l'etat anterieur : */
{
non_convergence=0;
/* Reinitialisation du detecteur de non convergence. */
if ( (ExacteSommeCoefficients2Variables<SommeCoefficients2SupVariables)
&& (ExacteSommeCoefficients2Variables>=SommeCoefficients2InfVariables)
)
{
for (index1=INDEX0 ; index1<Nvariables ; index1++)
{
BestVariables[index1]=Variables[index1];
/* En tout etat de cause, on memorise ce resultat... */
}
DEBUG(printf("\n iteration=%d",iteration););
DEBUG(printf("\n somme des variables=%d",SommeVariables););
DEBUG(printf("\n somme ponderee 1 des variables=%f",FLOT(SommeCoefficients1Variables)););
DEBUG(printf("\n somme ponderee 2 des variables=%f",FLOT(SommeCoefficients2SupVariables)););
DEBUG(printf("\n somme ponderee 3 des variables=%f",FLOT(SommeCoefficients2InfVariables)););
}
else
{
}
if ( (SommeCoefficients1Variables==ExacteSommeCoefficients1Variables)
&& (SommeVariables==ExacteSommeVariables)
&& (ExacteSommeCoefficients2Variables<SommeCoefficients2SupVariables)
&& (ExacteSommeCoefficients2Variables>=SommeCoefficients2InfVariables)
)
{
printf("\n\n une solution exacte a ete trouvee\n");
iterer=FAUX;
/* S'il correspond a l'etat "reel", on peut s'arreter... */
}
else
{
}
}
}
/*************************************************************************************************************************************/
/* */
/* E D I T I O N D E L A S O L U T I O N T R O U V E E : */
/* */
/*************************************************************************************************************************************/
printf("\n\n meilleurs resultats :\n");
SommeVariables=0;
SommeCoefficients1Variables=0;
SommeCoefficients2SupVariables=0;
SommeCoefficients2InfVariables=0;
for (index1=INDEX0 ; index1<Nvariables ; index1++)
{
printf("\n variables(%d)=%d",index1,BestVariables[index1]);
CumulVariables(SommeVariables);
CumulCoefficients1Variables(SommeCoefficients1Variables);
CumulCoefficients2SupVariables(SommeCoefficients2SupVariables);
CumulCoefficients2InfVariables(SommeCoefficients2InfVariables);
}
printf("\n somme des variables=%d",SommeVariables);
printf("\n somme ponderee 1 des variables=%f",FLOT(SommeCoefficients1Variables));
printf("\n somme ponderee 2 des variables=%f",FLOT(SommeCoefficients2SupVariables));
printf("\n somme ponderee 3 des variables=%f",FLOT(SommeCoefficients2InfVariables));
if ( (ExacteSommeCoefficients2Variables<SommeCoefficients2SupVariables)
&& (ExacteSommeCoefficients2Variables>=SommeCoefficients2InfVariables)
)
{
}
else
{
printf("\n les relations d'inegalite ne sont pas satisfaites");
}
printf("\n");
}