2013-07-21 15 views
5

Sto cercando di fare qualcosa che logicamente dovrebbe essere possibile fare. Tuttavia, non sono sicuro di come farlo nell'ambito della programmazione lineare. Sto usando ZMPL/SCIP, ma questo dovrebbe essere leggibile per la maggior parte.possibile indicizzare un set con una variabile?

set I := {1,2,3,4,5}; 
param u[I] := <1> 10, <2> 20, <3> 30, <4> 40, <5> 50; 

var a; 
var b; 

subto bval: 
    b == 2; 

subto works: 
    a == u[2]; 

#subto does_not_work: 
# a == u[b]; 

che sto cercando di fare in modo che la variabile a è uguale al valore dell'indice b in u. Quindi, ad esempio, mi assicuro che sia b == 2 e quindi provo a impostare il vincolo che è a == u[b], ma che non funziona. Si lamenta che sto cercando di indicizzare con una variabile. Sono in grado di fare solo a == u[2] tuttavia, che rende a uguale a 20.

C'è un modo per accedere facilmente a u a un indice specificato da una variabile? Grazie per qualsiasi aiuto/guida.


EDIT: Credo che il consenso è che questo non è possibile perché diventa non più un LP. In tal caso, qualcuno può pensare a un altro modo per scrivere questo in modo che, in base al valore di b, possa ottenere un valore associato dall'insieme u? Questo dovrebbe evitare di indicizzarlo direttamente.


SOLUZIONE: Sulla base della risposta da Ram, sono stato in grado di provarlo e ha scoperto che si trattava sicuramente una soluzione praticabile e lineare. Grazie, Ram! Ecco il codice soluzione campione in ZMPL:

set I := {1,2,3,4,5}; 
param u[I] := <1> 10, <2> 20, <3> 30, <4> 40, <5> 50; 

var a; 
var b; 
var y[I] binary; 

subto bval: 
    b == 4; 

subto only_one: 
    sum <i> in I : y[i] == 1; 

subto trick: 
    b == (sum <i> in I : y[i] * i); 

subto aval: 
    (sum <i> in I : u[i]*y[i]) == a; 
+0

Non essere scortese, ma non è necessario il consenso. Non è lineare perché non soddisfa la definizione di lineare. – raoulcousins

+0

Cool, grazie! Sono contento che non abbiamo bisogno di consenso. – gnychis

risposta

3

Sì, è possibile riscrivere e Linearizzare vostri vincoli, con l'introduzione di un paio in più variabili (0/1 variabili indicatore). Questi tipi di trucchi non sono rari nella programmazione di interi.

Vincoli In inglese

b possono assumere valori tra 1 e 5. b = {1..5}

e in funzione del valore di b, la variabile a dovrebbe diventare u[b]

Variabili indicatore

Introduciamo 5 Y variabili - Y1..Y5 (una per ogni possibile valore di b)

Solo una di queste può essere vera in qualsiasi momento.

Y1 + Y2 + Y3 + Y4 + Y5 = 1 
All Y's are binary {0,1} 

Ecco il trucco. Introduciamo un vincolo lineare per garantire che la corrispondente variabile Y assuma valore 1, solo quando b è quel valore.

b - 1xY1 - 2xY2 - 3xY3 - 4xY4 - 5xY5 = 0 

(Per esempio, se b è 3, il vincolo di cui sopra costringerà Y3 essere 1.)

Ora, vogliamo a ad assumere il valore di u [b].

a = u[1]xY1 + u[2]xY2 + u[3]xY3 + u[4]xY4 + u[5]xY5 

Poiché u [1] ... u [5] sono le costanti precedentemente note, anche il vincolo sopra riportato è lineare.

Qui è one reference su questi tipi di condizioni IF-THEN nella programmazione di interi. Molti di questi trucchi coinvolgono il Big-M, anche se in questo caso non ne abbiamo avuto bisogno.

Spero che ti aiuti ad andare avanti.

+0

Se la domanda è in realtà come "sommare u ma cancellare aggiungendo alla somma quando l'indice non è 5", aggiungere nuove variabili e vincoli è eccessivo. Questa risposta illustra bene una linearizzazione, ma non sono convinto che sia la risposta giusta per la domanda. – raoulcousins