vec=vecb
# 减低温度
T=T*cool
return vec
4 遗传算法:这个搜索过程基于一个假设认为全局最优解很可能 存在于当前 最优解种群中的下一代,这个下一代通常由当前最优解种群,通过解空间的某些维的交叉或者变异产生(这里有很多概率:变异范围概率P1,交叉还是变异的概率p2……),新产生的一代中,重新计算成本,保留一定数量最优解,作为当前最优解种群,如此循环经过几代遗传,最终在最后一代最优解种群中选择解。计划这个算法在另外文章中再详细介绍。
为了熟悉这些算法,所以实验了这个案例。除了以上算法,我们还需要编写一个成本函数,这个非常关键,这里列出一种计算方法,通过计算解所描述的图上点之间的距离和线交叉情况,来评估该图分布是否均衡合理(比如:交叉少便于阅读),
代码如下:
def crosscount(v):
loc=dict([(people
,(v[i*2],v[i*2+1])) for i in range(0,len(people))])
total=0
# Loop through every pair of links
for i in range(len(links)):
for j in range(i+1,len(links)):
# 计算线交叉情况
(x1,y1),(x2,y2)=loc[links
[0]],loc[links[1]]
(x3,y3),(x4,y4)=loc[links[j][0]],loc[links[j][1]]
den=(y4-y3)*(x2-x1)-(x4-x3)*(y2-y1)
if den==0: continue
ua=((x4-x3)*(y1-y3)-(y4-y3)*(x1-x3))/den
ub=((x2-x1)*(y1-y3)-(y2-y1)*(x1-x3))/den
if ua>0 and ua<1 and ub>0 and ub<1:
total+=1
#计算点互相的距离
for i in range(len(people)):
for j in range(i+1,len(people)):
(x1,y1),(x2,y2)=loc[people
],loc[people[j]]
dist=math.sqrt(math.pow(x1-x2,2)+math.pow(y1-y2,2))
if dist<50:
total+=(1.0-(dist/50.0))
return total
效果如下:
>>> sol=optimization.annealingoptimize(socialnetwork.domain,socialnetwork.crossc
ount,step=100,cool=0.99)
>>> socialnetwork.crosscount(sol)
总体感觉效果不是很好,这个可能和我们的成本函数也有关,成本函数需要比较好的评价每个解的好与坏。
后来想,是否可以从一个比较好初始状态开始,再利用优化算法进行简单的优化,于是写了一个函数 ,根据人数量,先平均切割块,把关系多的人放在位于中间的联通性比较好的块,这个解作为搜索的初始值:
def init_pos(peoples,height=400):
result =[]
pos_len= round(1+math.sqrt(len(peoples)))
pos_unit=int(height/pos_len)
helf_unit=int(pos_unit/5)
#生成初始位置列表
for i in range(1,pos_len+1):
for j in range(1,pos_len+1):
result.append((pos_weigh(i*pos_unit,j*pos_unit,height),(i*pos_unit-helf_unit,j*pos_unit-helf_unit)))
result.sort()
result.reverse()
#计算每个人的权重
people_weigh={}
for link in links:
people_weigh.setdefault(link[0],0)
people_weigh[link[0]]+=1
people_weigh.setdefault(link[1],0)
people_weigh[link[1]]+=1
people_queue=[]
for item in people_weigh:
people_queue.append((people_weigh[item],item))
people_queue.sort()
people_queue.reverse()
#放置人,根据权重大小先后放置
pos=dict([(people_queue
[1],(result[1])) for i in range(0,len(people_queue))])
pos_values=[]
for i in range(0,len(people)):
pos_values.append(pos[people
][0])
pos_values.append(pos[people][1])
return pos_values
优化的一个结果:
由于时间关系,没有做再多的实验。。。几个算法优化结果都差不多,退火和下山稍微比随机好一点。
总结:
优化算法的一个特点往往给出的是一个局部最优解,不是绝对的最优解,或者说全局最优解。一种优化算法是否有用很大程度取决问题本身,如果问题解本身就是比较无序的,或许随机搜索是最有效的。如以下这种情况,最优解可能位于一个狭小的空间,算法通常很难找到这个最优解的途径,因为任何解决的解成本都很高,都很有可能被排除在外。
那是否能够事先给出一个比较优的初始解,再在这个基础在利用优化算法,是否可以得到较优解,我想可能是存在的,在以上的这个例子当中,我做了下尝试,效果感觉不是很明显,当然也有很有可能是我方法不对。后来分析觉得 实际系统应该是使用类似 mass and spring 算法,这个算法也 模拟自然界中 球和弹簧的运动模型来的:各个节点施力企图远离对方,而节点间的连线又企图拉近其链接的2个节点。
附:
SOSO华尔兹是腾讯(TM)旗下搜索门户SOSO(搜搜)于2009年8月起新增的一项搜索功能。在这个页面里我们可以看到许多明星人物肖像被做成小图标,一个图标所链接的页面就是关于此图片人物的热门关联及其相关热门搜索。
SOSO华尔兹的特点在于:能够把与你要搜索的人物相关的其他人物都连成一个关系网,按照热门程度来进行相关联,您可以在这个页面中发现此人与其相关联人物之间的关系,以及在什么时候发生了什么事情等等。通过点击查看详细,更可以看到关联此事件的网页新闻,博客,搜吧,图片等等。让人非常方便的直接找到关注点以及所关联的人与事。
以上内容是 个人的一些学习笔记,资料大多源于互联网,有很多也是个人的理解,不一定正确,供大家参考。
if vecb[0]: vecb=domain[0]