2011-03-25 16 views
12

Sto cercando di utilizzare http://rss.acs.unt.edu/Rdoc/library/stats/html/constrOptim.html in R per eseguire l'ottimizzazione in R con alcuni vincoli lineari determinati ma non in grado di capire come impostare il problema.ottimizzazione vincolata in R

Ad esempio, ho bisogno di massimizzare $ f (x, y) = log (x) + \ frac {x^2} {y^2} $ soggetto a vincoli $ g_1 (x, y) = x + y < 1 $, $ g_2 (x, y) = x> 0 $ e $ g_3 (x, y) = y> 0 $. Come posso farlo in R? Questo è solo un esempio ipotetico. Non preoccuparti della sua struttura, invece sono interessato a sapere come impostarlo in R.

grazie!

+1

@ G e altri - qualcuno può spiegare perché il post incrociato è disapprovato? Sarebbe accettabile menzionare che stai postando in cross con un link? Non ho sentimenti forti in un modo o nell'altro, ma probabilmente è necessaria una certa chiarezza sulla questione. Se questo è qualcosa che la comunità R in generale ha già affrontato in precedenza, suppongo che il collegamento a tali discussioni sarebbe un buon inizio. – Chase

+0

Se esegui una ricerca nella scheda Meta per "cross posting" trovi una varietà di opinioni, la maggior parte accetta in modo approssimativo il cross-posting. (Il cross-posting simultaneo, tuttavia, sembra infastidire la maggior parte della gente.) C'è una forte etica anti-cross-posting sui gruppi r-help e cugini che è stabilita dalla R-Help Posting Guide. Ho difficoltà a vedere la Guida alla pubblicazione come probante in SO. –

+0

@Chase Quando le persone si incrociano e non permettono a nessuno di sapere che è molto probabile che qualcuno scriva una soluzione per un problema già risolto che può essere uno spreco di tempo. Personalmente non mi interessa se le persone attraversano i post purché lo facciano sapere (e non è eccessivo). – Dason

risposta

16

Impostazione della funzione era banale:

fr <- function(x) {  x1 <- x[1] 
    x2 <- x[2] 
    -(log(x1) + x1^2/x2^2) # need negative since constrOptim is a minimization routine 
} 

Impostazione della matrice dei vincoli è stato problematico a causa della mancanza di molta documentazione, e ho fatto ricorso alla sperimentazione. La pagina di aiuto dice "La regione ammissibile è definita da ui% *% theta - ci> = 0". Così ho provato e questo sembrava "lavoro":

> rbind(c(-1,-1),c(1,0), c(0,1)) %*% c(0.99,0.001) -c(-1,0, 0) 
     [,1] 
[1,] 0.009 
[2,] 0.990 
[3,] 0.001 

così ho messo in una riga per ogni vincolo/confine:

constrOptim(c(0.99,0.001), fr, NULL, ui=rbind(c(-1,-1), # the -x-y > -1 
               c(1,0), # the x > 0 
               c(0,1)), # the y > 0 
              ci=c(-1,0, 0)) # the thresholds 

Per questo problema v'è un potenziale difficoltà che per tutti i valori di x la funzione passa a Inf come y -> 0. Riesco a ottenere un massimo intorno a x = .95 e y = 0 anche quando spingo i valori iniziali verso "l'angolo", ma sono piuttosto sospettoso che questo sia non il vero massimo che avrei immaginato fosse nell'angolo. EDIT: Praticando questo Ho pensato che il gradiente potrebbe fornire "direzione" ulteriore e ha aggiunto una funzione gradiente:

grr <- function(x) { ## Gradient of 'fr' 
    x1 <- x[1] 
    x2 <- x[2] 
    c(-(1/x[1] + 2 * x[1]/x[2]^2), 
     2 * x[1]^2 /x[2]^3) 
} 

Questo ha "guidare" l'ottimizzazione un po 'più vicino al c (0,999 ..., 0) angolo, invece di allontanarsi da esso, come ha fatto per alcuni valori iniziali. Rimango un po 'deluso dal fatto che il processo sembra "dirigersi verso la scogliera" quando i valori di partenza sono vicino al centro della regione ammissibile:

constrOptim(c(0.99,0.001), fr, grr, ui=rbind(c(-1,-1), # the -x-y > -1 
               c(1,0), # the x > 0 
               c(0,1)), # the y > 0 
              ci=c(-1,0, 0)) 
$par 
[1] 9.900007e-01 -3.542673e-16 

$value 
[1] -7.80924e+30 

$counts 
function gradient 
    2001  37 

$convergence 
[1] 11 

$message 
[1] "Objective function increased at outer iteration 2" 

$outer.iterations 
[1] 2 

$barrier.value 
[1] NaN 

Nota: Hans Werner Borchers ha postato un esempio migliore su R-Help che è riuscito a ottenere i valori dell'angolo impostando il vincolo leggermente lontano dal bordo:

> constrOptim(c(0.25,0.25), fr, NULL, 
       ui=rbind(c(-1,-1), c(1,0), c(0,1)), 
       ci=c(-1, 0.0001, 0.0001)) 
$par 
[1] 0.9999 0.0001 
+0

Questo è molto utile. L'esempio che ho postato non era l'ideale, ma posso vedere come impostare la funzione. Cos'è una regione realizzabile? – user236215

+0

Una regione ammissibile è l'insieme di punti che soddisfa tutti i vincoli. Un triangolo nelle tue specifiche. –

Problemi correlati