1. ホーム
  2. r

[解決済み] GRG ノンリニアR

2022-02-25 08:58:37

質問

私はExcelのソルバーモデルをRのモデルに変換したいのですが、他の5つの与えられた座標への距離を最小にする3つの座標のセットを見つける必要があります。各入力から与えられた座標までの最小距離を出力する距離行列を計算するプログラムを作りました。この関数を入力を変化させて最小化したい。つまり、最小距離の和が最小になるような座標を探したい。そのためにいくつかの方法を試してみました。以下のコードをご覧ください(確かに私の距離行列関数は多少不便かもしれませんが、これはnloprtのようないくつかのアルゴリズムを実行するために入力を1変数に減らす必要があったからです(そうしないと警告が出るので)。また、他の質問もいくつか見かけました。 GRG 非線形最小二乗法 (最適化) が、解答に変化・改善はありませんでした。

# First half of p describes x coordinates, second half the y coordinates # yes thats cluncky
p<-c(2,4,6,5,3,2) # initial points

x_given <- c(2,2.5,4,4,5)
y_given <- c(9,5,7,1,2)

f <- function(Coordinates){ 

# Predining
Term_1                       <-     NULL
Term_2                       <-     NULL
x                            <-     NULL
Distance                     <-     NULL
min_prob                     <-     NULL
l                            <-     length(Coordinates)
l2                           <-     length(x_given)
half_length                  <-     l/2
s                            <-     l2*half_length
Distance_Matrix              <-     matrix(c(rep(1,s)), nrow=half_length)

# Creating the distance matrix
for (k in 1:half_length){
  for (i in 1:l2){
    Term_1[i]                <-     (Coordinates[k]-x_given[i])^2
    Term_2[i]                <-     (Coordinates[k+half_length]-y_given[i])^2
    Distance[i]              <-     sqrt(Term_1[i]+Term_2[i])
    Distance_Matrix[k,i]     <-     Distance[i]
  }
}
d                            <-     Distance_Matrix

# Find the minimum in each row, thats what we want to obtain ánd minimize
for (l in 1:nrow(d)){
  min_prob[l] <- min(d[l,])
}
som<-sum(min_prob)
return(som)
}

# Minimise
sol<-optim(p,f)
x<-sol$par[1:3]
y<-sol$par[4:6]
plot(x_given,y_given)
points(x,y,pch=19)

しかし、この解決策は明らかに最適とは言えません。nloptr関数を使おうとしたのですが、どのアルゴリズムを使えばいいのかわかりません。どのアルゴリズムを使えばいいのか、あるいはこの問題を解決する別の関数を使ったりプログラムしたりできるのでしょうか?事前にありがとうございます(そして詳細な長い質問で申し訳ありません)

どのように解決するのですか?

の出力を見てください。 optim . 反復の限界に達しており、まだ収束していないのです。

> optim(p, f)
$`par`
[1] 2.501441 5.002441 5.003209 5.001237 1.995857 2.000265

$value
[1] 0.009927249

$counts
function gradient 
     501       NA 

$convergence
[1] 1

$message
NULL

結果はそれほど変わりませんが、収束させるためには反復回数を増やす必要があります。 それでも収束しない場合は、開始値を変えてみてください。

> optim(p, f, control = list(maxit = 1000))
$`par`
[1] 2.502806 4.999866 5.000000 5.003009 1.999112 2.000000

$value
[1] 0.005012449

$counts
function gradient 
     755       NA 

$convergence
[1] 0

$message
NULL