#==========
Julia の修行をするときに,いろいろなプログラムを書き換えるのは有効な方法だ。
以下のプログラムを Julia に翻訳してみる。
AHP (Analytic Hierachy Process)
http://aoki2.si.gunma-u.ac.jp/R/AHP.html
ファイル名: ahp.jl 関数名: ahp
翻訳するときに書いたメモ
内包表記と for ループ どちらがよいだろうか?
==========#
using LinearAlgebra, Rmath, Plots
function ahp(x, y)
n = items(length(x))
weightx = makematrix(x)
nitemsy = items(size(y, 1))
weighty = zeros(nitemsy, n)
for i = 1:n
weighty[:, i] = makematrix(y[:, i])
end
score = weighty * weightx
sortedscore = sort(score)
printahp(weightx, weighty, score, sortedscore)
plotahp(score, nitemsy)
Dict(:weightx => weightx, :weighty => weighty,
:score => score, :sortedscore => sortedscore)
end
function items(n)
retval = (1 + sqrt(1 + 8 * n)) / 2
retval != floor(retval) ? NaN : Int(retval)
end
function makematrix(x)
n = items(length(x))
!isnan(n) || error("size error")
mat = Array{Float64}(I, n, n)
lowertri = [i > j for i = 1:n, j = 1:n]
mat[lowertri] = x
mat = transpose(mat) + mat
uppertri = [i < j for i = 1:n, j = 1:n]
mat[uppertri] = 1 ./ mat[uppertri]
[mat[i, i] = 1 for i in 1:n]
values, vectors = eigen(mat)
val = real(values[n])
vec = real(vectors[:, n])
weight = vec / sum(vec)
ci = (val - n) / (n - 1)
cr = ci / [0, 0, 0.58, 0.9, 1.12, 1.24, 1.32, 1.41, 1.45, 1.49, 1.51, 1.53][n]
if ci > 0.1 || cr > 0.1
println("\nCI = $ci, CR = $cr")
println(mat)
W = weight ./ weight'
println(W)
println(mat - W)
end
return weight
end
function printahp(weightx, weighty, score, sortedscore, digits = 5)
println("\n評価基準の重み")
println(round.(weightx, digits = digits))
println("\n代替案の評価結果")
println(round.(weighty, digits = digits))
println("\nスコア")
println(round.(score, digits = digits))
println("\nソートされたスコア")
println(round.(sortedscore, digits = digits))
end
function plotahp(score, nc)
pyplot(size=(600, 60))
plt = scatter(score, repeat([25], nc), grid=false, tick_direction=:out,
yshowaxis=false, ylims=(0, 60), yticks=false, label="")
for i = 1:nc
annotate!(score[i], 50, text(string(i), 10, :red), label="")
end
display(plt)
end
x = [1 / 3, 1 / 5, 1 / 7, 1 / 5, 1 / 7, 1 / 3];
y = hcat([1 / 2, 1 / 3, 1 / 2], [5, 2, 1 / 7], [1 / 3, 1 / 2, 2], [2, 2, 1]);
ahp(x, y)
# CI = 0.05947572619908503, CR = 0.10254435551566386
# [1.0 0.2 0.5; 5.0 1.0 7.0; 2.0 0.14285714285714285 1.0]
# [1.0 0.14189834119703848 0.7047298732064893; 7.0472987320648866 1.0 4.96644194189634; 1.4189834119703837 0.20135139234471133 1.0]
# [0.0 0.05810165880296153 -0.20472987320648928; -2.0472987320648866 0.0 2.03355805810366; 0.5810165880296163 -0.058494249487568484 0.0]
# 評価基準の重み
# [0.54374, 0.31093, 0.09745, 0.04789]
# 代替案の評価結果
# [0.53961 0.10564 0.53961 0.2; 0.29696 0.74446 0.16342 0.4; 0.16342 0.1499 0.29696 0.4]
# スコア
# [0.38842, 0.42802, 0.18356]
# ソートされたスコア
# [0.18356, 0.38842, 0.42802]