- 2経路の選択
- 2つの要素
- 2択の場合
- 、ここでは選択肢A,Bのそれぞれに、「実績として起きた事象の数(アリで言えば、アリが落としたフェロモン量)」
- は非線形の程度を決める。はフェロモンがないときの「得点」→ランダム性のための下駄
- 複数の選択肢でどれかが選ばれていく様子
library(MCMCpack)
Niter<-1000
n<-4
k<-20
A<-4
M<-matrix(0,Niter,A)
for(i in 2:Niter){
M[i,]<-M[i-1,]
prob<-(M[i-1,]+k)^n
prob<-prob/sum(prob)
s<-sample(1:A,1,prob=prob)
M[i,s]<-M[i,s]+1
}
matplot(M/((1:Niter)-1),type="l")
- StarLogoというソフト(こちら)
- 平面の探索
- 平面を正方格子で考えると、それは、正方格子というグラフを空間とした行動であって、「グラフ」を空間にすることで一般化できるだろう
- 以下のソースは次のように考えている
- 有限平面を正方格子として、それを表すグラフについて、隣接ノードを列挙する
- アリは、このグラフ上を確率的に移動する
- アリは、複数の状態を持つ(エサを巣に持ち帰るときには、エサを持っている状態と持っていない状態の2状態)
- アリは、自身の状態によって、進行エッジの選択に関して異なる確率ベクトルを持つ
- アリは、複数の進行エッジの先のノードのフェロモン量に応じて、エッジを選ぶが、かなりの乱雑さを持たせることが、集団としての探索がうまく行くコツのようである(この乱雑さは、フェロモンの総量によらずに下駄をはかせる方がよさそうである(どんなにフェロモンが多くても、一定の確率で、フェロモンのない格子点へも進めるようにする)
- アリは自身の状態により、異なるフェロモンを現在地に置く
- アリの置くフェロモンは、特定の状態のアリのエッジ選択情報となる
- フェロモンは時間とともに消失する
- 巣とエサの位置は指定する(複数の格子点を一塊として指定するのがよい)
- エサはアリに持ち帰らせる(結果としていつか消滅する)ようにしてもよいし無尽蔵にしもよい(以下のソースは無尽蔵)
- 巣とエサとは、生物学的な意味であるが、これは、アリの状態を変更する場所であると定義すればよい
- 解く課題は
- 経路の最適化・分布の最適化
- セールスマン問題
- 2次割り付け問題(Quadratic assignment problem(Wikiはこちら))は(こちらの用量反応曲線に関して用いる、Isotonic regression(こちら)の2次計画問題と同様に最適化の困難問題)
N<-100
XY<-expand.grid(1:N,1:N)
Nloc<-length(XY[,1])
Neighbors<-list()
difX<-outer(XY[,1],XY[,1],"-")
difY<-outer(XY[,2],XY[,2],"-")
for(i in 1:Nloc){
Neighbors[[i]]<-which(difX[i,]^2+difY[i,]^2<=1)
Neighbors[[i]]<-Neighbors[[i]][which(Neighbors[[i]]!=i)]
}
Nant<-300
Nstate<-2
half<-floor(N^2/2+N/2)
Ax<-sample(half:(half+1),Nant,replace=TRUE)
Sx<-sample(1:1,Nant,replace=TRUE)
V<-matrix(0,Nloc,Nstate)
for(i in 1:Nant){
V[Ax[i],Sx[i]]<-V[Ax[i],Sx[i]]+1
}
C<-matrix(rep(1:Nstate,Nloc),byrow=TRUE,ncol=Nstate)
Center.1to2<-c(N*2/9,N*2/9)
Radius.1to2<-N/20
Center.2to1<-c(N/2,N/2)
Radius.2to1<-N/20
for(i in 1:Nloc){
if(sum(XY[i,]-Center.1to2)^2<=Radius.1to2){
C[i,1]<-2
}
if(sum(XY[i,]-Center.2to1)^2<=Radius.2to1){
C[i,2]<-1
}
}
P<-matrix(0,Nloc,Nstate)
Pgeta<-rep(0.5,Nstate)
Pexp<-rep(5,Nstate)
Pv<-c(1,1)
Pt<-c(2,1)
Pr<-c(0.95,0.95)
Niter<-10000
par(mfcol=c(2,3))
for(i in 1:Niter){
tmpV<-matrix(0,Nloc,Nstate)
for(j in 1:Nstate){
for(k in 1:Nloc){
destination<-Neighbors[[k]]
prob<-(P[destination,j])^Pexp[j]
if(sum(prob)==0){
prob<-rep(1,length(prob))
}
prob<-prob/sum(prob)
prob<-prob+Pgeta[j]
prob<-prob/sum(prob)
s<-sample(destination,V[k,j],replace=TRUE,prob=prob)
for(l in s){
tmpV[l,j]<-tmpV[l,j]+1
}
}
}
tmpV2<-matrix(0,Nloc,Nstate)
for(j in 1:Nstate){
for(k in 1:Nstate){
tmp<-which(C[,j]==k)
tmpV2[tmp,k]<-tmpV2[tmp,k]+tmpV[tmp,j]
}
}
V<-tmpV2
for(j in 1:Nstate){
P[,j]<-P[,j]*Pr[j]
}
for(j in 1:Nstate){
P[,Pt[j]]<-P[,Pt[j]]+V[,j]*Pv[j]
}
image(matrix(log(P[,1]+1),N,N),main="pheromone1")
image(matrix(log(P[,2]+1),N,N),main="pheromone2")
image(matrix(apply(log(P+1),1,sum),N,N),main="pheromone1+2")
image(matrix(sign(V[,1]),N,N),main="ant1")
image(matrix(sign(V[,2]),N,N),main="ant2")
image(matrix(apply(sign(V),1,sum),N,N),main="ant1+2")
}