演算法分析與實踐 大作業

2021-10-07 05:38:13 字數 1520 閱讀 8984

給定n個圓的半徑序列,將它們放到矩形框中,各圓與矩形底邊相切,求具有最小排列長度的原序列。

一般而言我們會想到這種做法:

但是這種只是其中一種,我們並沒有考慮完全,還有一些如:

小球本來可以放到兩個大球的中間,不增加長度的

這個就類似於最短路的問題,由此我們想到了回溯演算法。

開始時設a=[r1,r2,……rn]是所給的n個元的半徑,則相應的排列樹由a[1:n]的所有排列構成。

cter(x)用來計算第n個圓的橫座標

設:圓1的橫座標是x1,半徑是r1,圓2的橫座標是x2,半徑是r2

**(r1+r2)2-(r1-r2)2=(x1-x2)^2

=>4r1r2=(x1-x2)^2

=>2√(r1r1)=x1-x2

**compute函式計算當前排列長度

dfs為核心函式,便利每一種可能

#include

#include

#include

using

namespace std;

const

int n =

100;

const

int inf =

0x3f3f3f3f

;double minn = inf,x[n]

, r[n]

;//分別為最小圓排列長度,每個圓心橫座標,每個圓半徑

int n;

double bestr[n]

;//最小圓排列的半徑順序

double

cter

(int n)

return temp;

}void

compute()

if(high-low

}void

dfs(

int t)

else

swap

(r[t]

, r[j]);

//還原}}

}int

main()

dfs(1)

;printf

("最小圓排列長度為:%.2f\n"

, minn)

;printf

("最小圓排列的順序對應的半徑分別為:\n");

for(

int i =

1; i <= n;

++i)

return0;

}

結果

最壞情況下會遍歷所有的解空間序列,此時的時間複雜度為o(n!)

每次排列都需要呼叫一次compute函式,時間複雜度為o(n)

綜上,該演算法的時間複雜度為o((n+1)!)

演算法分析與設計實踐大作業

圓排列問題 給定n個圓的半徑序列,將它們放到矩形框中,各圓與矩形底邊相切,求具有最小排列長度的圓排列。首先,已知圓的個數n以及記錄各圓半徑的陣列r i i 1 n 記錄各圓圓心橫座標的陣列x i i 1 n。要記錄最短排列長度minlen,最終求出排列順序。要注意,只要大小合適,目標圓就有可能與排列...

演算法分析與實踐 大作業 圓排序問題

圓排列問題 給定n個圓的半徑序列,將它們放到矩形框中,各圓與矩形底邊相切,求具有最小排列長度的圓排列。圓排列問題主要用到了回溯法。問題的解空間是一棵排列數。按照回溯法遍歷每種排列,求得最小排列長度的最優解。變數n為圓的個數 陣列r n 儲存每個圓的半徑,x n 儲存每個圓的圓心座標,bestr n ...

演算法分析與設計實踐 大作業 圓排列問題

給定n個圓的半徑序列,將它們放到矩形框中,各圓與矩形底邊相切,求具有最小排列長度的圓排列。圓排列問題的解空間是一棵排列樹。按照回溯法搜尋排列樹的演算法框架,設開始時a r1,r2,rn 是所給的n個元的半徑,則相應的排列樹由a 1 n 的所有排列構成。定義乙個函式center 來計算圓在當前圓排列中...