給定n個大小不等的圓 ,現要將這n個圓排進乙個矩形框中,且要求各圓與矩形框的底邊相切。圓排列問題要求從n個圓的所有排列中找出有最小長度的圓排列。例如,當n=3,且所給的3個圓的半徑分別為1,1,2時,這3個圓的最小長度的圓排列如圖所示。其最小長度為 。
設計乙個隨機化演算法,對於給定的n個圓,計算n個圓的最佳排列方案,使其長度盡可能小。
由檔案input.txt給出輸入資料。第一行有1個正整數n (1≤n≤20)。接下來的1行有n個數,表示n個圓的半徑。
這裡不展開介紹隨機化演算法,它在我看來只是一種使演算法複雜度與輸入資料解耦合的思想,並不是某種特定的演算法。比如我們都知道快速排序對於不同的輸入資料會有不同的時間複雜度,所以我們稱其為不穩定的排序演算法,而採用隨機化的思想就能使其變成穩定的演算法,最簡單的辦法就是對所有輸入資料都進行一次隨機排列。
在本問題中,解題思想也相同,所謂隨機化只是將輸入的圓半徑給隨機打亂罷了。
完整**如下(python3版本)
import numpy as np
import random
# 給定乙個半徑陣列,計算其按順序的長度
defget_len
(a, n)
:len=0
if n <1:
return
none
if n ==1:
return a[0]
len+= a[0]
for i in
range
(n -1)
:len+=2
*((a[i]
*a[i +1]
)**(1
/2))
len+= a[-1
]return
len# 定**圓排列問題的隨機化演算法
defcircle_search
(a, n)
:global min_len
# 將輸入資料中的圓的半徑隨機化,從而讓演算法效能與輸入資料解耦合
a = random.sample(a, n)
# 計算隨機化後的長度
min_len = get_len(a, n)
found =
true
while
(found)
: found =
false
for i in
range
(n):
for j in
range
(n):
a[i]
, a[j]
= a[j]
, a[i]
if get_len(a, n)
< min_len:
found =
true
min_len = get_len(a, n)
else
: a[i]
, a[j]
= a[j]
, a[i]
# 讀取資料
隨機化演算法
隨機化演算法的主要目的是希望讓隨機發生在演算法上,而不是發生在輸入分布上,這樣的話,沒有特別的輸入會引起我們的演算法的最壞情況。即使你最壞的敵人也無法產生最壞的輸入陣列。因為隨機排列使得輸入次序不再相關。只有在隨機數生成器產生乙個不走運的排列時,隨機演算法才會執行得很差。一.隨機優先順序陣列法 我們...
隨機化演算法基礎
隨機化演算法在分析某些涉及概率分析的問題上具有重要意義,因為輸入的分布是我們不能預知的,我們想讓分析的問題達到乙個平均的狀態,就得依靠隨機化,把輸入分布重新排列,使之成為乙個脫離其他外界因數的排列,同時要保證出現這個排列的概率為1 n 下面,有兩個常用的演算法來實現輸入分布的隨機化,以給定的輸入陣列...
隨機化演算法之取樣問題
一 簡單的隨機抽樣 乙個總體的個數為n,如果通過逐個抽取的方法從中抽取 乙個樣本,且每次抽取時各個個體被抽到的概率相等,則這樣的抽樣為簡單的隨機抽樣。例如,從含有6個個體的總體中抽取乙個容量為2的樣本,則在抽樣過程 中某個個體a被抽到的概率是多少?2 6 1 第一次a被抽中 1 6 2 第一次未被抽...