1. 程式人生 > 其它 >群體智慧演算法-黏菌尋找食物最優路線行為模擬

群體智慧演算法-黏菌尋找食物最優路線行為模擬

說明:此文章為騰訊雲機器自動從本人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
                }

            }()

        }
    }
}