面試筆試題——12個工廠分佈

                

面試筆試題——12個工廠分佈          

           12個工廠分佈在一條東西向高速公路的兩側,工廠距離公路最西端的距離分別是0、4、5、10、12、18、27、30、31、38、39、47.在這12個工廠中選取3個原料供應廠,使得剩餘工廠到最近的原料供應廠距離之和最短,問應該選哪三個廠 ?(需注意不知道工廠的分佈情況!)

         上面是在羣裏面貼出來的,自己就收藏了一下,想等有空的時候想想。下面我就解這道題的思路說一下,有不對的地方還請指出。

首先要注意在12個工廠中有一個到最西端的爲0,我設這一點爲第0個工廠,我們可以看到每個工廠都是離最西端一點的距離,那麼我們是不是可以將這個問題這樣理解?就是所有節點以最西端爲圓心的一個圓,那麼第0個工廠就是在圓心位置(因爲它離最西端爲零),那麼就可以將上面的問題描述成下面的一個圖:

   

             個人認爲這個工廠位置可以通過上圖描述出來。那麼得到這樣一個圖如何求選擇哪三個工廠作爲原料廠呢?下面將進行講解:

           我們假設原則的三個原料廠爲p、q、r。那麼所有節點到離其最進的原料廠的距離之和爲最小時,則這三個廠爲原料廠。要求得圖中每個節點到其的最短距離這是一個Dijkstra算法,所以此處需要對圖中所有節點求一次Dijkstra算法,我們通過一個Map來存儲,Map的key爲當前Dijkstra的源點,值爲通過Dijkstra算得的dist[]數組。此時我們就得到了所有節點的Dijkstra的dist[]數組,並將其進行存儲在Map中。那麼如何取得三個原料廠呢?那就是從這12個廠中任選三個,並求的所有節點到離其最近的原料廠的距離之和,我們將這個和賦給一個tempmin變量。如何任選三個工廠,那麼就需要使用三重循環,其實這裏是個排列組合,那麼共有12*12*12種,但注意還要減去不能選擇相同工廠的情況,就是通過一個if判斷來避免選擇相同工廠的情況,當我們任選了三個工廠作爲原料廠,那麼就需要求的所有節點(但必須出去已被選定作爲原料廠的工廠)到和其最近的原料廠距離之和,同時賦給tempmin,注意該變量是記錄每任取三個原料的距離之和。取得每次的距離之和在進行比較,將會產生一個最短的情況,那麼這種情況的所選的三個原料廠是最好的情況。詳細代碼如下:(解題方法僅供參考!如有不足歡迎討論!)

public class Factory{

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		float[][] a = new float[12][12];
		for (int i = 0; i < 12; i++) {
			for (int j = 0; j < 12; j++) {
				if (i == j) {
					a[i][j] = 0;
				} else {

					a[i][j] = Float.MAX_VALUE;
				}
			}

		}
		a[0][1] = 4;
		a[1][0] = 4;
		a[0][2] = 5;
		a[2][0] = 5;
		a[0][3] = 10;
		a[3][0] = 10;
		a[0][4] = 12;
		a[4][0] = 12;
		a[0][5] = 18;
		a[5][0] = 18;
		a[0][6] = 27;
		a[6][0] = 27;
		a[0][7] = 30;
		a[7][0] = 30;
		a[0][8] = 31;
		a[8][0] = 31;
		a[0][9] = 38;
		a[9][0] = 38;
		a[0][10] = 39;
		a[10][0] = 39;
		a[0][11] = 47;
		a[11][0] = 47;
		Float[] dist = new Float[12];
		int[] prev = new int[12];
		Map<String, Float[]> distMap = new HashMap<String, Float[]>();
		List<Float[]> list = new ArrayList<Float[]>(12);
		for (int i = 0; i < 12; i++) {
			//System.out.print(i+"--->");
			dijkstra(i, a, dist, prev);
			distMap.put(i+"f", dist);
			/*for(int j=0; j<12; j++)
			{
				System.out.print(dist[j]+"  ");
			}
			System.out.println();*/
			dist = new Float[12];
			//System.out.println();
		}
		float min = Float.MAX_VALUE;
		int p = -1, q=-1, r=-1;
		Map<String, Float[]> tempMap = new HashMap<String, Float[]>();
		for (int i = 0; i < 12; i++) {
			for (int j = 0; j < 12; j++) {
				for (int k = 0; k < 12; k++) {
					if(i!=j&&i!=k&&j!=k)
					{
					tempMap.put(i+"y", distMap.get(i+"f"));
					tempMap.put(j+"y", distMap.get(j+"f"));
					tempMap.put(k+"y", distMap.get(k+"f"));
					float tempmin = 0.0f;
					for (int m = 0; m < 12; m++) {
						float temp = Float.MAX_VALUE;
						if (m != i && m != j && m != k) {
							//取得當前的點到當前所選的三個原料廠中那個地點最短
							for (Map.Entry<String, Float[]> entry : tempMap
									.entrySet()) {
								if (temp > entry.getValue()[m]) {
									temp = entry.getValue()[m];
								}
							}
							
							//此處是求的當前所選的三個節點,所有節點到和其最進的節點距離之和
							tempmin+=temp;
						}
					}
					tempMap.clear();
					//比較整個最小
					System.out.println("最小和爲: "+tempmin+"三個原料廠爲:"+i+" "+j+"  "+k);
					if(min>tempmin)
					{
						min=tempmin;
						p=i;
						q=j;
						r=k;
					}
					}
				}
			}
		}
		System.out.println("最小和爲: "+min+"三個原料廠爲:"+p+" "+q+"  "+r);
	}

	public static void dijkstra(int v, float[][] a, Float[] dist, int[] prev) {
		int n = dist.length - 1;
		if (v < 0 || v >n)
			return;
		boolean[] s = new boolean[n + 1];
		//此處的循環是初始化  
		for (int i = 0; i <= n; i++) {
			dist[i] = a[v][i];
			s[i] = false;
			if (dist[i] == Float.MAX_VALUE)
				prev[i] = -1;
			else
				prev[i] = v;
		}
		//此處開始遍歷  
		dist[v] = 0.0f;
		s[v] = true;
		//該循環是求的所有節點到源節點的路徑,每循環一次求的一個節點到源節點的距離  
		for (int i = 0; i <=n; i++) {
			float temp = Float.MAX_VALUE;
			int u = v;
			//shortestPath(此處取該循環爲shortestPath)  
			for (int j = 0; j < n; j++) {
				if ((!s[j]) && (dist[j] < temp)) {
					u = j;
					temp = dist[j];
				}
			}
			//System.out.print(u+" dist:"+dist[u]+"  ");
			s[u] = true;
			//updateDist(取名爲updateDist)  
			for (int j = 0; j <=n; j++) {
				if ((!s[j]) && (a[u][j] < Float.MAX_VALUE)) {
					float newdist = dist[u] + a[u][j];
					if (newdist < dist[j]) {
						dist[j] = newdist;
						prev[j] = u;
					}
				}
			}
		}
	}

}


發佈了40 篇原創文章 · 獲贊 26 · 訪問量 41萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章