Пример #1
0
/* perform metropolis iteration exchanging double edges. Output the temperature */
double dbl_metrop_switches(Network **RN,int nover,int nlimit,double init_t,int real_vec13[14],int rand_vec13[14])
{

	double t=init_t;
	register int w,k,num_at_t;
	int s1,t1,s2,t2;
	int i,j;
	int sub13[14];
	int add13[14];
	double E1,E2,dE;
	int make_change;
	int tries; //number of tries to find proper pair of edges to exchange
	int twin_i=-1,twin_j=-1;
	w=0;
	if ((w%1000)==0 && GNRL_ST.out_metrop_mat_flag)
		fprintf(GNRL_ST.mat_metrop_fp,"\nBeginning double switches\n");
	k=0,w=0,num_at_t=0;
	t=init_t;

	for (i=1;i<14;i++)
	{
		sub13[i]=0;
		add13[i]=0;
	}

	E1=energy(real_vec13,rand_vec13);

	while ((w<nover)&&(E1>GNRL_ST.e_thresh))
	{
		w++;
		num_at_t++;
		if ((k>nlimit)||(num_at_t>nlimit))
		{
			num_at_t=0;
			k=0;
			t *= TFACTR;		// lower temperature
		}
		w++;
		// random edges to choose : until finding a proper pair of edges which can be candidates
		// should not choose the same edge or the twin one (of the double)
		// try this for 100 times if not getting good candidate then probably
		// there is a only one double edge in the netwprk
		for(i=get_rand((*RN)->e_dbl_num),j=get_rand((*RN)->e_dbl_num),tries=0;
		((j==i) || (j==twin_i)) && (tries<100) ;i=get_rand((*RN)->e_dbl_num),j=get_rand((*RN)->e_dbl_num),tries++);
		//the way out of deadlock
		if(tries==100 || (*RN)->e_dbl_num==2)
			break;
		//this is needed to know if the twin is i-1 or i+1
		if(i & 0x1)
			twin_i=i+1;
		else
			twin_i=i-1;
		if(j & 0x1)
			twin_j=j+1;
		else
			twin_j=j-1;

		s1=(*RN)->e_arr_dbl[i].s;
		t1=(*RN)->e_arr_dbl[i].t;
		s2=(*RN)->e_arr_dbl[j].s;
		t2=(*RN)->e_arr_dbl[j].t;

		//check : 1.that there are no crossing edges in the network,
		//		  2.there are no common vertices of these 2 edges
		//if hasnt passed the check then have to find other pair to switch
		if (( !( MatGet((*RN)->mat,s1,t2) || MatGet((*RN)->mat,s2,t1) || MatGet((*RN)->mat,t1,s2)|| MatGet((*RN)->mat,t2,s1))
			&& (s1!=t2) &&(s2!=t1) && (s1!=s2) && (t1!=t2)) )
		{
			// make fill13_dbl - new function
			fill_13_dbl((*RN),s1,t1,s2,t2,sub13,add13);
			update(rand_vec13,sub13,add13,1);
			E2=energy(real_vec13,rand_vec13);
			dE=E2-E1;
			//	printf("k=%d E=%lf\n",k,E1);
			make_change=metrop(dE,t);

			if (make_change)
			{
				if(DEBUG_LEVEL==1 && GNRL_ST.out_log_flag) {
					fprintf(GNRL_ST.log_fp,"switch #%d: (%d %d) (%d %d)\n", k,s1,t1,s2,t2);
					fprintf(GNRL_ST.log_fp,"i: %d, twin i %d , j: %d twin j : %d\n", i,twin_i,j,twin_j);
				}
				if ((w%1000)==0 && GNRL_ST.out_metrop_mat_flag)
				{
					fprintf(GNRL_ST.mat_metrop_fp,"%lf\n",E1);
					printf("success=%d k=%d E1=%lf T=%lf\n",k,w,E1,t);
				}
				E1=E2;
				if ((w%1000)==0 && GNRL_ST.out_metrop_mat_flag)
						printf("success=%d k=%d E1=%lf T=%lf\n",k,w,E1,t);
				//make the switch
				//update edges array
				(*RN)->e_arr_dbl[i].t=t2;
				(*RN)->e_arr_dbl[twin_i].s=t2;
				(*RN)->e_arr_dbl[j].t=t1;
				(*RN)->e_arr_dbl[twin_j].s=t1;
				if(DEBUG_LEVEL==1 && GNRL_ST.out_log_flag) {
					fprintf(GNRL_ST.log_fp,"(%d %d) (%d %d) (%d %d) (%d %d)\n",
					(*RN)->e_arr_dbl[i].s,(*RN)->e_arr_dbl[i].t,
					(*RN)->e_arr_dbl[twin_i].s,(*RN)->e_arr_dbl[twin_i].t,
					(*RN)->e_arr_dbl[j].s,(*RN)->e_arr_dbl[j].t,
					(*RN)->e_arr_dbl[twin_j].s,(*RN)->e_arr_dbl[twin_j].t
					);
				}

				//update matrix
				MatAsgn((*RN)->mat,s1,t1,0);
				MatAsgn((*RN)->mat,t1,s1,0);
				MatAsgn((*RN)->mat,s2,t2,0);
				MatAsgn((*RN)->mat,t2,s2,0);
				if(DEBUG_LEVEL==1 && GNRL_ST.out_log_flag)
					dump_network(GNRL_ST.log_fp,(*RN));
				MatAsgn((*RN)->mat,s1,t2,1);
				MatAsgn((*RN)->mat,t2,s1,1);
				MatAsgn((*RN)->mat,s2,t1,1);
				MatAsgn((*RN)->mat,t1,s2,1);
				if(DEBUG_LEVEL==1 && GNRL_ST.out_log_flag)
					dump_network(GNRL_ST.log_fp,(*RN));
				if (DEBUG_LEVEL>1 && GNRL_ST.out_metrop_mat_flag)
				{
					fprintf(GNRL_ST.mat_metrop_fp,"%lf %lf  ",E1,t);
					output13(rand_vec13,GNRL_ST.mat_metrop_fp);
				}
				k++;
			}
			else
			/* change rand_vec13 back */
			{
				update(rand_vec13,sub13,add13,0);
			}
		}
	}
	if(GNRL_ST.out_metrop_mat_flag==TRUE){
		fprintf(GNRL_ST.mat_metrop_fp,"%lf\n",E1);
		printf("success=%d k=%d E1=%lf T=%lf\n",k,w,E1,t);
	}
	return(t);
}
Пример #2
0
void anneal(float x[], float y[], int iorder[], int ncity)
{
	int irbit1(unsigned long *iseed);
	int metrop(float de, float t);
	float ran3(long *idum);
	float revcst(float x[], float y[], int iorder[], int ncity, int n[]);
	void reverse(int iorder[], int ncity, int n[]);
	float trncst(float x[], float y[], int iorder[], int ncity, int n[]);
	void trnspt(int iorder[], int ncity, int n[]);
	int ans,nover,nlimit,i1,i2;
	int i,j,k,nsucc,nn,idec;
	static int n[7];
	long idum;
	unsigned long iseed;
	float path,de,t;

	nover=100*ncity;
	nlimit=10*ncity;
	path=0.0;
	t=0.5;
	for (i=1;i<ncity;i++) {
		i1=iorder[i];
		i2=iorder[i+1];
		path += ALEN(x[i1],x[i2],y[i1],y[i2]);
	}
	i1=iorder[ncity];
	i2=iorder[1];
	path += ALEN(x[i1],x[i2],y[i1],y[i2]);
	idum = -1;
	iseed=111;
	for (j=1;j<=100;j++) {
		nsucc=0;
		for (k=1;k<=nover;k++) {
			do {
				n[1]=1+(int) (ncity*ran3(&idum));
				n[2]=1+(int) ((ncity-1)*ran3(&idum));
				if (n[2] >= n[1]) ++n[2];
				nn=1+((n[1]-n[2]+ncity-1) % ncity);
			} while (nn<3);
			idec=irbit1(&iseed);
			if (idec == 0) {
				n[3]=n[2]+(int) (abs(nn-2)*ran3(&idum))+1;
				n[3]=1+((n[3]-1) % ncity);
				de=trncst(x,y,iorder,ncity,n);
				ans=metrop(de,t);
				if (ans) {
					++nsucc;
					path += de;
					trnspt(iorder,ncity,n);
				}
			} else {
				de=revcst(x,y,iorder,ncity,n);
				ans=metrop(de,t);
				if (ans) {
					++nsucc;
					path += de;
					reverse(iorder,ncity,n);
				}
			}
			if (nsucc >= nlimit) break;
		}
		printf("\n %s %10.6f %s %12.6f \n","T =",t,
			"	 Path Length =",path);
		printf("Successful Moves: %6d\n",nsucc);
		t *= TFACTR;
		if (nsucc == 0) return;
	}
}
Пример #3
0
/* perform metropolis iteration exchanging single edges. Output the temperature */
double sin_metrop_switches(Network **RN,int nover,int nlimit,double init_t,int real_vec13[14],int rand_vec13[14])
{

	double t=init_t;
	register int w,k,num_at_t;
	int s1,t1,s2,t2;
	int i,j,l;
	int sub13[14];
	int add13[14];
	double E1,E2,dE;
	int make_change;
	if(GNRL_ST.out_metrop_mat_flag==TRUE)
		printf("\nBeginning single switches\n");

	k=0,w=0,num_at_t=0;
	t=init_t;

	for (i=1;i<14;i++)
	{
		sub13[i]=0;
		add13[i]=0;
	}

	E1=energy(real_vec13,rand_vec13);

	if ((w%1000)==0 && GNRL_ST.out_metrop_mat_flag)
		fprintf(GNRL_ST.mat_metrop_fp,"\nEsin :\n");

	while ((w<nover)&&(E1>GNRL_ST.e_thresh))
	{
		w++;
		num_at_t++;

		if ((k>nlimit)||(num_at_t>nlimit))
		{
			num_at_t=0;
			k=0;
			t *= TFACTR;		// lower temperature
		}

		//get random indexes for edges
		i=get_rand((*RN)->e_sin_num);
		while ((j=get_rand((*RN)->e_sin_num)) == i);

		s1=(*RN)->e_arr_sin[i].s;
		t1=(*RN)->e_arr_sin[i].t;
		s2=(*RN)->e_arr_sin[j].s;
		t2=(*RN)->e_arr_sin[j].t;

		//check : 1.that there are no crossing edges,
		//		  2.there are no common vertices of these 2 edges
		//if hasnt passed the check then have to find other pair to switch

		if ( !(MatGet((*RN)->mat,s1,t2) || MatGet((*RN)->mat,s2,t1)|| MatGet((*RN)->mat,t2,s1) || MatGet((*RN)->mat,t1,s2))
				&&(s1!=s2) && (s1!=t2) && (t1!=s2) && (t1!=t2) )
		{
			fill_13((*RN),s1,t1,s2,t2,sub13,add13);
			update(rand_vec13,sub13,add13,1);
			E2=energy(real_vec13,rand_vec13);
			dE=E2-E1;
			//	printf("k=%d E=%lf\n",k,E1);
			make_change=metrop(dE,t);


			if (make_change)
			{
				if ((w%1000)==0 && GNRL_ST.out_metrop_mat_flag)
				{
					fprintf(GNRL_ST.mat_metrop_fp,"%lf\n",E1);
					printf("success=%d k=%d E1=%lf T=%lf\n",k,w,E1,t);
				}

				if(DEBUG_LEVEL>1 && GNRL_ST.out_metrop_mat_flag)
				{
					fprintf(GNRL_ST.mat_metrop_fp,"The network :\n\n");
					for (l=1;l<=(*RN)->e_sin_num;l++)
						fprintf(GNRL_ST.mat_metrop_fp,"%d %d %d\n",(*RN)->e_arr_sin[l].t,(*RN)->e_arr_sin[l].s,1);
				}


				E1=E2;
				//make the switch
				//update edges array
				(*RN)->e_arr_sin[i].t=t2;
				(*RN)->e_arr_sin[j].t=t1;
				//update matrix
				MatAsgn((*RN)->mat,s1,t1,0);
				MatAsgn((*RN)->mat,s2,t2,0);
				MatAsgn((*RN)->mat,s1,t2,1);
				MatAsgn((*RN)->mat,s2,t1,1);
				//fprintf(GNRL_ST.mat_metrop_fp,"%lf %lf\n  ",E1,t);
				if(DEBUG_LEVEL>1 && GNRL_ST.out_metrop_mat_flag)
				{
					fprintf(GNRL_ST.mat_metrop_fp,"Changed to  :\n\n");
					for (l=1;l<=(*RN)->e_sin_num;l++)
						fprintf(GNRL_ST.mat_metrop_fp,"%d %d %d\n",(*RN)->e_arr_sin[l].t,(*RN)->e_arr_sin[l].s,1);

					fprintf(GNRL_ST.mat_metrop_fp,"rand_vec : \n");
					output13(rand_vec13,GNRL_ST.mat_metrop_fp);
					fprintf(GNRL_ST.mat_metrop_fp,"- : \n");
					output13(sub13,GNRL_ST.mat_metrop_fp);
					fprintf(GNRL_ST.mat_metrop_fp,"+ : \n");
					output13(add13,GNRL_ST.mat_metrop_fp);
					fprintf(GNRL_ST.mat_metrop_fp,"The network :\n\n");
					for (l=1;l<=(*RN)->e_sin_num;l++)
						fprintf(GNRL_ST.mat_metrop_fp,"%d %d %d\n",(*RN)->e_arr_sin[l].t,(*RN)->e_arr_sin[l].s,1);
					fprintf(GNRL_ST.mat_metrop_fp,"\n\n");
				}
				k++;
			}
			else
			/* change rand_vec13 back */
			{
				update(rand_vec13,sub13,add13,0);

			}
		}
	}
	if(GNRL_ST.out_metrop_mat_flag==TRUE) {
		fprintf(GNRL_ST.mat_metrop_fp,"%lf\n",E1);
		printf("success=%d k=%d E1=%lf T=%lf\n",k,w,E1,t);
	}
	return(t);
}