/*---------------------------------------------------------------------------
recuit		: procede a un recuit simule pour trouver un codage optimal.
----------------------------------------------------
parametres	:
----------------------------------------------------
return		: rien.
-----------------------------------------------------------------------------*/
recuit()
{
int T,T2 ;
int *nwS, *nwO, *we ;
int *tPoidFutur, *tPoidEtat ;
int *tCod, *bestCod ;
int bestCost, cost, cost2 ;
p_groupe listState ;
int selectLabel ;
int *givTabCod() ;
int *makeTabCode(), *tryAll() ;
int i,j,plusMoins ;
 
if(autoSys->numberState <= 4)
	bestCod = tryAll() ;
else
{
T2 = (autoSys->numberState / 10) + 5 ;

asp(0,0) ;
nwS=(int*)mbkalloc((autoSys->numberState +1)*(autoSys->numberState +1)*sizeof(int)) ;
nwO=(int*)mbkalloc((autoSys->numberState +1)*(autoSys->numberState +1)*sizeof(int ));

mustPoids(nwS,nwO);
we = mustCalcul(nwS,nwO);
tPoidFutur = PoidsFutur();
tPoidEtat = asp_poidEtat();

bestCost = constructBehGivCost(1) ;
bestCod = givTabCod() ;
tCod = makeTabCode(bestCod) ;
bestCod = givTabCod() ;
cost2 = bestCost + 1 ;

if(syf_trace)
	printf("---->initial cost : %d\n",bestCost) ;

listState = stateGeneration();

for(j = 0; j < 3; j++)
	{
	initCode() ;
	switch(j)
		{
		case 0 :
			asp(0,0) ;
			printf("------> ASP\n")  ;
			break ;
		case 1 :
			mustang(0) ;
			printf("------> MUST\n")  ;
			break ;
		case 2 :
			mustJedi() ;
			printf("------> JED\n")  ;
			break ;
		}
	tCod = makeTabCode(tCod) ;
	plusMoins = 1 ;
  while(plusMoins)
	{
	T = 3 ;
	if(NUMBER_CODE(autoSys->numberState) <= T)
		T = NUMBER_CODE(autoSys->numberState) - 1 ;
	while(T)
		{
		write(1,"|",1) ;
		for(i = 0; i<T2; i++)
			{
			listState = stateGeneration();
			while(listState)/* autoSys->cod est affecte automatiquement */
				{	/* tabCod est mis a jour automatiquement */
			   selectLabel=codeModification(we,tPoidEtat,tPoidFutur,tCod,listState);
				listState = delFromgroup(listState,selectLabel);
				}
			fprintf(stdout,".") ;
			fflush(stdout) ;
			cost = constructBehGivCost(1) ;
			if(cost < bestCost)
				{
				bestCost = cost ;
				bestCod = givTabCod() ;
				if(syf_trace)
					printf("---->Best Cost : %d\n",bestCost) ; 
				}
			if(cost2 == cost)
				break ;
			cost2 = cost ;
			}
		printf("\n") ;
		  if(plusMoins == 1)
		  	permutCodPlus(T) ;
		  else
		  	permutCodMoins(T) ;
		/*melangeCod(T) ;*/
		tCod = makeTabCode(tCod) ; /*et non pas giveTabCode*/
		T-- ;
		}
	  plusMoins-- ; 
	  }
	}
tab2Cod(bestCod) ;
postRecuit() ;
}
tab2Cod(bestCod) ;
}
/*---------------------------------------------------------------------------
tryAll		: procede a un codage exhaustif et choisit le meilleur selon une
			  fonction de cout.
----------------------------------------------------
parametres	:
----------------------------------------------------
return		: tabCod.
-----------------------------------------------------------------------------*/
int *tryAll()
{
chain_list *lState, *lCode, *lCode1, *lCode2 ;
int bestCost ;
int *bestCod, *tabCod ;
int i,numberCod ;
void orderCod() ;
chain_list *copyChain(), *delChainData() ;

lState = NULL ;
lCode = NULL ;
orderCod(&lState,&lCode) ;
bestCod = givTabCod() ;
tabCod = givTabCod() ;
numberCod = NUMBER_CODE(autoSys->numberState) ;

bestCost = 99999 ;
lCode1 = copyChain(lCode) ;
lCode2 = copyChain(lCode) ;
for(i = 0; i < numberCod; i++)
	{
	freechain(lCode2) ;
	lCode2 = copyChain(lCode1) ;
	affectCod(numberCod - 1, numberCod -1 -i,tabCod,delChainData(lCode2,numberCod -1 -i),&bestCost,&bestCod) ;
	lCode = lCode->NEXT ;
	resetBdd() ;
	}
return(bestCod) ;
}
/*---------------------------------------------------------------------------
AffectCod		: Affecte de maniere recursive tous les codes disponibles a
				  tous les etats de la table des code.
----------------------------------------------------
parametres	: n : le rang de tabCod a affecter.
			  code : code de n eme element : tabCod[n].
			  tabCod : table des codes a remplir.
			  lCod : list des codes disponibles.
			  bestCost : Le cout du meilleur codage.
			  bestCod : table des codes ayant le meilleur code.
----------------------------------------------------
return		: .
-----------------------------------------------------------------------------*/
affectCod(n, code, tabCod, lCod, bestCost, bestCod)
int n, code ;
int *tabCod ;
chain_list *lCod ;
int *bestCost ;
int **bestCod ;
{
int i, cost ;
chain_list *lCod2, *lCod3, *lCod4,*exlCod, *exlCod2 ;
void displayChainInt() ;
chain_list *copyChain(), *delChainData() ;

tabCod[n] = code ;

if(n == 0)
	{
	tab2Cod(tabCod) ;
	cost = constructBehGivCost(1,LOG_GF,1) ;
	if(cost < *bestCost)
		{
		*bestCost = cost ;
		*bestCod = givTabCod() ;
		if(syf_trace)
			printf("---->Best Cost : %d\n",*bestCost) ;
		}
	}
else
	{
	exlCod = copyChain(lCod) ;
	exlCod2 = copyChain(lCod) ;

	while(lCod)
		{
		freechain(exlCod2) ;
		exlCod2 = copyChain(exlCod) ;
		lCod2 = delChainData(exlCod2,lCod->DATA) ;
		affectCod(n-1, lCod->DATA,tabCod,lCod2,bestCost,bestCod) ;
		lCod = lCod->NEXT ;
		}
	}
}
/*---------------------------------------------------------------------------
postRecuit	: Un traitement post-recuit-simule, tentant d'ameliorer le cout
			  localement.
----------------------------------------------------
parametres	:
----------------------------------------------------
return		: rien.
-----------------------------------------------------------------------------*/
postRecuit()
{
int T ;
int *tCod, *bestCod ;
int bestCost, cost ;
int *givTabCod() ;
int *makeTabCode(), *tryAll() ;
int i, progress ;
 
bestCost = constructBehGivCost(1,LOG_GF,0) ;
bestCod = givTabCod() ;
tCod = makeTabCode(bestCod) ;
bestCod = givTabCod() ;

if(syf_trace)
	printf("---->initial cost : %d\n",bestCost) ;

progress = 1 ;
while(progress)
  {
progress = 0 ;
T = autoSys->numberState ;
for(i = 0; i < T; i++)
	{
	(autoSys->code + tCod[i])->code = i + 1;
	(autoSys->code + tCod[i + 1])->code = i;
	printf(".") ;
	fflush(stdout) ;
	cost = constructBehGivCost(1,LOG_GF,0) ;
	if(cost < bestCost)
		{
		progress = 1 ;
		bestCost = cost ;
		bestCod = givTabCod() ;
		tab2Cod(bestCod) ;
		/*if(syf_trace)*/
		}
	tab2Cod(bestCod) ;
	tCod = makeTabCode(tCod) ; /*et non pas giveTabCode*/
  	}
  }
}
/*---------------------------------------------------------------------------
permutCodPlus	: permute le codage un nbre fini de fois = T.
----------------------------------------------------
parametres	: T.
----------------------------------------------------
return		: rien.
-----------------------------------------------------------------------------*/
permutCodPlus(T)
int T ;
{
pCode cod ;
int i, num ;

num = NUMBER_CODE(autoSys->numberState) ;
if(T >= num)
	{
	printf("SYF : number of permutation > number of code\n") ;
	exit(-1) ;
	}

cod = autoSys->code ;
for(i = 0; i < num; i++)
	{
	cod->code = cod->code + T ;

	if(cod->code >= num)
		cod->code = cod->code - num ;
	cod++ ;
	}
}
/*---------------------------------------------------------------------------
permutCodMoins	: permute le codage un nbre fini de fois = T.
----------------------------------------------------
parametres	: T.
----------------------------------------------------
return		: rien.
-----------------------------------------------------------------------------*/
permutCodMoins(T)
int T ;
{
pCode cod ;
int i, num ;

num = NUMBER_CODE(autoSys->numberState) ;
if(T >= num)
	{
	printf("SYF : number of permutation > number of code\n") ;
	exit(-1) ;
	}

cod = autoSys->code ;
for(i = 0; i < num; i++)
	{
	cod->code = cod->code - T ;

	if(cod->code < 0)
		cod->code = cod->code + num ;
	cod++ ;
	}
}
