在這裡,權值可以是任何和弦長,邊長有關的權函式,一般來說,我們使用三角形的邊長作為權值。
在這個問題中,是具有最優子結構的。
設一共有n邊的凸多邊形點的集合為,在以v0和vn-1為底的情況下,求k∈(0,n-1),使v0,vn-1,vk組成的三角形權值最小。
這樣,剩下的兩個點集和就可以組成新的凸多邊形。
在其中,定義乙個二維陣列t[ i ][ j ],它的含義是在凸多邊形的最優三角剖分的權值(以vi-1,vj為底,尋找k∈[i,j]的第三個頂點,使權值最小。這樣說可能更容易理解),以i來代替i-1可以避開兩個點被判定為三角形的情況所造成的麻煩。因此可得遞迴式:
這個式子跟矩陣連乘問題還是非常相似的,因此我們再定義乙個二維陣列s,負責記錄在凸多邊形中的第三頂點k。
同樣地,t和s只使用右上部分,對角線為0,剩下的以如下順序記錄:
這個圖有點問題,因為第0行是不使用的,因為不可能有第-1個點給0當底。
作為例子的多邊形是我在網上檔的,因為看見好幾篇都用的這個例子也無法找到原出處了。
weight =[[
0,2,
2,3,
1,4]
,[2,
0,1,
5,2,
3],[
2,1,
0,2,
1,4]
,[3,
5,2,
0,6,
2],[
1,2,
1,6,
0,1]
,[4,
3,4,
2,1,
0]]def
w(a, b, c)
:global weight
return weight[a]
[b]+ weight[b]
[c]+ weight[a]
[c]def
min_weight_triangulation
(t, s, n)
:for r in
range(1
, n -1)
:for i in
range(1
, n - r)
: j = i + r
t[i]
[j]= t[i +1]
[j]+ w(i -
1, i, j)
s[i]
[j]= i
for k in
range
(i +
1, j)
: u = t[i]
[k]+ t[k +1]
[j]+ w(i -
1, k, j)
if u < t[i]
[j]:
t[i]
[j]= u
s[i]
[j]= k
return t[1]
[n-1
]def
traceback
(i, j, s)
:if i == j:
return
traceback(i, s[i]
[j], s)
traceback(s[i]
[j]+
1, j, s)
print
(str
(i -1)
+' '
+str
(j)+
' '+
str(s[i]
[j])
)if __name__ ==
'__main__'
: n =
6 t =
s =for i in
range(0
, n):[
]))for j in
range(0
, n)
: t[i]0)
s[i]0)
print
("最優剖分權值:"
+str
(min_weight_triangulation(t, s, n)))
traceback(1,
5, s)
凸多邊形最優三角剖分 動態規劃
解答 題目中頂點座標編號從1開始,為了方便程式設計,將頂點從0開始,頂點的編號變為0到7。定義t i j 0 由於退化的兩點多邊形的權值為0,t i i 0。最優子結構的性質,t i j 的值是t i k 的值加上t k j 的值,再加上三角形vivkvj的權值,其中,it i j t i k t ...
凸多邊形最優三角剖分 動態規劃
凸多邊形最優分割是典型的動態規劃問題 凸多邊形最優剖分 給定凸多邊形,以及定義在由多邊形的邊和弦上的權函式,使得該多邊形三角剖分後所有三角形權值之和最小。思路 先將多邊形三角剖分 2 三角剖分 最優子結構性質 若n 1邊形的最優三角剖分包含三角形v0vkvn 1 k n 則t的權為三個部分權之和 三...
動態規劃DP 凸多邊形最優三角剖分
我們可以把披薩餅看作是乙個凸多邊形,凸多邊形是指多邊形的任意兩點的連線均落在多邊形的內部或邊界上。1 什麼是凸多邊形?如下圖所示,是乙個凸多邊形 如下圖所示,不是乙個凸多邊,因為v1v3連線落在了多邊形的外部 凸多邊形不相鄰的兩個頂點的連線稱為凸多邊形的弦 2 什麼是凸多邊形的三角剖分?凸多邊形的三...