算法java实现--回溯法--圆排列问题--排列树

旅行售货员问题的java实现(回溯法--排列树)

具体问题描述以及C/C++实现参见网址

http://blog.csdn.net/liufeng_king/article/details/8890603

/**
 * 圆排列问题--回溯法--排列树
 * @author Lican
 *
 */
public class Circles {
	public int n;//待排列圆的个数
	public float min;//当前最优值
	public float[] x;//当前圆排列圆心横座标
	public float[] r;//当前圆排列
	public float circlePerm(int nn,float[] rr){
		n=nn;
		r=rr;
		min=1000000;
		x=new float[n+1];
		backtrack(1);
		return min;
	}
	public void backtrack(int t){
		if(t>n)
			compute();
		else{
			for(int j=t;j<=n;j++){
				swap(r,t,j);
				float centerx=center(t);
				if(centerx+r[t]+r[1]<min){//下界约束
					x[t]=centerx;
					backtrack(t+1);
				}
				swap(r,t,j);
			}
		}
	}
	public void swap(float[] r,int i,int j){
		float temp=r[i];
		r[i]=r[j];
		r[j]=temp;
	}
	public float center(int t){//计算当前所选择圆的圆心横座标
		float temp=0;
		for(int j=1;j<t;j++){
			float valuex=(float) (x[j]+2.0*Math.sqrt(r[t]*r[j]));
			if(valuex>temp)
				temp=valuex;
		}
		return temp;
	}
	public void compute(){//计算当前圆排列的长度
		float low=0;
		float high=0;
		for(int i=1;i<=n;i++){
			if(x[i]-r[i]<low) low=x[i]-r[i];
			if(x[i]+r[i]>high) high=x[i]+r[i];
		}
		if(high-low<min)
			min=high-low;
	}
	public static void main(String[] args) {
		int n=3;
		float[] r={0,1,1,2};//r下标从1开始, 0无用,只是凑数
		Circles c=new Circles();
		float min=c.circlePerm(n, r);
		System.out.println("最小圆排列长度为"+min);
	}
}
/*
输出:
最小圆排列长度为7.656854

*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章