接前面
同书上“图10.5贪心法求得的近似解”是一样的。
![]() |
---|
七边形最小分割弦
文章讲了怎么求七边形的最小分割弦。用到了公式,书本上对公式做了详细说明。使用公式要配合动态规划算法,并比较了贪心法,还直接给出了贪心算法的最后切割图形,如上图。
红黑视觉化
讲到了所见即所得,可视化的好处,这次分割图的时候也画出来。
最美公式
负数索引
要切割成三角形就要跳过一个点,按照V0、V1、V2…的顺序,比较Line(0,2)、Line(1,3)、Line(2,4)…而且走到后面的点的时候还要跟最前面的点连接。怎样才能写得简洁呢,用负数索引是很好的办法。
i-2正好是前两个;0,1的时候也适用
math.sqrt((xy[i][0]-xy[i-2][0])**2+(xy[i][1]-xy[i-2][1])**2)
f l o a t ( ′ i n f ′ ) float('inf') float(′inf′)
最大实数。是一种表示正无穷大的方法,inf是无穷大(infinity)的缩写。正好是float类型,可以跟计算出来的小数距离值比较。
递归调用
找最短的一条切割线,切割图形。对切割得到的图形重复前面的过程。
代码
注意。
1、xy.pop(dian-1)#切掉的点要去掉,再进行下一次递归切割。
2、画蓝色底图添加了缝合点,(0,10);drawline画切割线的时候要去掉这个缝合的点。
import matplotlib.pyplot as plt
import math
xy=[(0,10),(0,20),(8,26),(15,26),(27,21),(22,12),(10,0),(0,10)]
plt.figure()
plt.plot([x[0] for x in xy],[y[1] for y in xy])
#选最短切割线
def drawline(xy,total=0):
if 2>=len(xy):
return total
line=float('inf')
dian = 0 #记录最短切割线的终点
for i in range(len(xy)):#i-2正好是前两个;0,1的时候也适用
t = math.sqrt((xy[i][0]-xy[i-2][0])**2+(xy[i][1]-xy[i-2][1])**2)
if t < line:
dian = i
line = t
plt.plot([xy[dian-2][0],xy[dian][0]],[xy[dian-2][1],xy[dian][1]],'r--') #前面是两个x坐标,后面是两个y坐标
total += line
xy.pop(dian-1)#切掉的点
drawline(xy,total)
return total
drawline(xy[:-1],0)#要去掉最后缝合的点。
plt.show()
总长:91.4828803402364
同书上“图10.5贪心法求得的近似解”是一样的。
![]() |
---|
测评
算法思路简洁而且有图形展示;但代码行数比规划法还多,而且不是最优解。什么时候能把图10.4动态规划法求得的最优解画出来就好了。