群體智慧演算法-黏菌尋找食物最優路線行為模擬
阿新 • • 發佈:2022-05-03
說明:此文章為騰訊雲機器自動從本人csdn部落格搬遷過來。是本人授權操作。
申明:無本人授權,不可轉載本文。如有轉載,本人保留追究其法律責任的權利。
龔浩華,QQ 29185807,月牙寂 道長
第一時間獲取文章,可以關注本人公眾號 月牙寂道長 yueyajidaozhang
昨天看了一個視訊(http://www.tudou.com/programs/view/4QmfLMMBZBg) 講的就是黏菌 尋找食物時候會構造一個強大的網路。
如下圖
通過對黏菌行為的觀察。我想通過一個分散式的群體演算法來模擬黏菌的行為,來實現最優路徑的尋找。
目前實現了簡單的行為模擬。 主要有兩個方面
1、黏菌的擴張行為。
首先定義了一個生命力值來模擬。在黏菌的位置,生命力是最強的。隨著黏菌的擴張,擴張的邊緣的生命力會遞減。黏菌會不斷的擴張。
2、食物的獲取
在這裡假設,黏菌的擴張部分只能吸收食物,但不能將食物轉換成能量。猶如人體一樣,只有胃能夠消化食物,將食物轉換成能量供人體吸收。
假設黏菌的核心才能將食物轉換成能量,其他部分只能是吸收傳遞能量。
那麼表現為能量的傳輸為從生命力低的地方傳送到生命力高的地方,也就只有在黏菌的初始位置。
程式模擬
1、黏菌的各個部分只能從其周圍的部分獲取到資訊。也只能與周圍的部分進行資訊交流,以及食物的傳遞。
目前只簡單的用陣列來演示。沒有做介面演示。
首先說明下 陣列中的含義【生命力,食物含量,食物傳送數量統計】
其中黏菌的初始位置在【10,0,0】處,食物防在圖中的【0,5000,0】
原始碼如下
package main import ( "fmt" "sync" "time" ) func main() { for { select {} } } var max_x int = 10 var max_y int = 10 var AllPart []Parts type Parts []*Part var lock *sync.RWMutex func Print() { tick := time.Tick(1 * time.Second) for { select { case <-tick: fmt.Println("-------------------------------------------------") lock.Lock() for y := 0; y < max_y; y++ { for x := 0; x < max_x; x++ { fmt.Printf("%d,%d,%dt", AllPart[y][x].en, AllPart[y][x].food, AllPart[y][x].countfood) } fmt.Println() } lock.Unlock() } } } func init() { lock = &sync.RWMutex{} AllPart = make([]Parts, max_y, max_y) for y := 0; y < max_y; y++ { AllPart[y] = Parts(make([]*Part, max_x, max_x)) } for y := 0; y < max_y; y++ { for x := 0; x < max_x; x++ { AllPart[y][x] = NewPart(x, y) } } AllPart[8][3].en = 10 AllPart[8][3].ismother = true AllPart[3][8].food = 5000 AllPart[3][8].isfood = true for y := 0; y < max_y; y++ { for x := 0; x < max_x; x++ { go AllPart[y][x].run() } } go Print() } type Part struct { x int y int en int food int countfood int ismother bool isfood bool } func NewPart(x, y int) *Part { p := Part{x, y, 0, 0, 0, false, false} return &p } func getEn(x, y int) int { if x < 0 || y < 0 { return -1 } if x >= max_x || y >= max_y { return -1 } return AllPart[y][x].en } func (p *Part) run() { tick := time.Tick(1 * time.Second) for !p.ismother { select { case <-tick: func() { lock.RLock() defer lock.RUnlock() max_node := 0 maxcount := 0 other := make(map[*Part]int) getmax := func(xi, yi int) { en := getEn(xi, yi) if en > p.en { maxcount++ other[AllPart[yi][xi]] = en } if en > max_node { max_node = en } } getmax(p.x-1, p.y-1) getmax(p.x, p.y-1) getmax(p.x+1, p.y-1) getmax(p.x-1, p.y) getmax(p.x+1, p.y) getmax(p.x-1, p.y+1) getmax(p.x, p.y+1) getmax(p.x+1, p.y+1) if max_node > p.en { p.en = max_node - 1 } if p.en == 0 || p.food <= 0 || maxcount <= 0 { return } food := p.food if p.isfood { food = 8 } avf := food / maxcount for k, _ := range other { k.food += avf p.countfood += avf p.food -= avf } }() } } }