1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

juliaと遺伝的アルゴリズムでonemax問題

Posted at

最近juliaなるプログラミング言語を見つけ、面白そうだったので勉強を始めました。
今回はその一つとして遺伝的アルゴリズムでOneMax問題を最適していきます
Juliaのwiki
https://ja.wikipedia.org/wiki/Julia_(プログラミング言語)
###初期世代生成

leng = 100
population = 100
mutationRate = 0.1
genelation = 10

function init()
    genom::Array{Int8, 2} = rand(0:1, leng, population)
    return genom
end

最初の世代は0と1の完全にランダムな配列で生成します。
配列の要素は0か1しか使わないので、Int8でデータ量を節約してます。
###個体の選択

function choice(genom::Array{Int8, 2})
    X::Int64 = argmax(sum(genom, dims=2))[1]
    Y::Int64 = 0
    while true
        Y = rand(1:population)
        if Y != X
            break
        end
    end
    return genom[X, :], genom[Y, :]
end

この関数では、最も優秀な遺伝子Xとランダムに選択された遺伝子Yの
配列を返り値としています。Yのランダム選択部分は1:populationの配列かX番目の値を削除して、その中からランダムに選択する方法もありましたが、pop!の使い方がよく分からなかったのでこうなりました。
###交差

function crossover(X::Array{Int8, 1}, Y::Array{Int8, 1})
    genom::Array{Int8, 1} = []
    append!(genom, X)
    append!(genom, Y)
    for i in 1:population-2
        cut = rand(2: leng-1)
        append!(genom, X[1: cut])
        append!(genom, Y[cut+1: leng])
    end
    return reshape(genom, leng * population)
end

交差は一点交差を使い、返り値はこの後の突然変異のためにleng * populationのサイズの一次元配列にreshapeして返します
###突然変異

function mutation(genom::Array{Int8, 1})
    for i in 1: leng * population
        if rand() < mutationRate
            genom[i] = 1 - genom[i]
        end
    end
    return reshape(genom, leng, population)
end

先ほど一次配列にしたものを受け取ってfor文で全ての要素を参照していきmutationRateの確率で
1と0を反転させてます。
ここだけではないですが、もっとスマートな書き方にできそな所が多々ありますね…
もし修正やアドバイス等ありましたらコメントの程お願いします。

###main関数

function main()
    local genom = init()
    for i in 1: genelation
        X, Y = choice(genom)
        genom = crossover(X, Y)
        genom = mutation(genom)
        println("gen: ", i)
        print("avg: ")
        println(sum(genom) / (leng * population))
        print("max: ")
        println(sum(X) / leng)
        println("")
    end
end

あとは作った関数を組み立てて完成です。
できあがたコードはgithubのリンクを貼っておきます↓
https://github.com/AokiMasataka/One-max/blob/master/OneMax.jl

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?