算法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

*/

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