2013-07-21 17 views
5

Próbuję zrobić coś, co logicznie powinno być możliwe. Jednak nie jestem pewien, jak to zrobić w ramach programowania liniowego. Używam ZMPL/SCIP, ale powinno to być możliwe do odczytania dla większości.można indeksować zestaw według zmiennej?

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]; 

Staram się upewnić, że zmienna a jest równa wartości w indeksie b w u. Tak na przykład, zapewniam, że b == 2, a następnie próbuję ustawić ograniczenie, które a == u[b], ale to nie działa. Narzeka, że ​​próbuję indeksować za pomocą zmiennej. Mogę jednak zrobić tylko a == u[2], co powoduje, że a jest równe 20.

Czy istnieje sposób na łatwy dostęp do u w indeksie określonym przez zmienną? Dzięki za pomoc/wskazówki.


EDIT: Myślę, że konsensus jest, że nie jest to możliwe, ponieważ nie staje się PR. W takim przypadku, czy ktokolwiek może wymyślić inny sposób zapisu tego, aby w zależności od wartości b, uzyskać skojarzoną wartość z zestawu u? Musiałoby to uniknąć bezpośredniego indeksowania.


ROZWIĄZANIE: Na podstawie odpowiedzi z pamięci RAM, udało mi się go wypróbować i okazało się, że to z pewnością rozwiązanie opłacalne i liniowy. Dzięki, Ram! Oto przykładowy kod rozwiązanie w 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

Nie należy być niegrzecznym, ale nie potrzeba konsensusu. Nie jest liniowy, ponieważ nie spełnia definicji liniowej. – raoulcousins

+0

Fajnie, dzięki! Cieszę się, że nie potrzebujemy konsensusu. – gnychis

Odpowiedz

3

Tak, można przepisać i zlinearyzować twoje ograniczenia, poprzez wprowadzenie kilku dodatkowych 0/1 zmienne (zmienne wskaźnikowe). Tego rodzaju sztuczki nie są rzadkie w programowaniu Integer.

ograniczenia w języku angielskim

b może przyjmować wartości od 1 do 5. b = {1..5}

iw zależności od wartości B, zmienna a powinna stać u[b]

Zmienne wskaźnika

Przedstawiamy 5 Y zmienne - Y1..Y5 (po jednym dla każdej możliwej wartości b)

Tylko jedna z nich może być prawdziwa w danym momencie.

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

Oto podstęp. Wprowadzamy jedno ograniczenie liniowe, aby upewnić się, że odpowiednia zmienna Y przyjmie wartość 1, tylko gdy b jest tą wartością.

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

(Na przykład, jeśli b wynosi 3, powyższe ograniczenie zmusi Y3 być 1.)

Teraz chcemy a wziąć na wartości u [b].

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

Ponieważ u [1] ... u [5] są znane wcześniej stałe, powyższe ograniczenie również jest liniowe.

Oto one reference na temat tego rodzaju warunków IF-THEN w programie Integer Programming. Wiele z tych sztuczek dotyczy Big-M, chociaż nie potrzebowaliśmy tego w tym przypadku.

Nadzieję, że pomoże Ci iść do przodu.

+0

Jeśli pytanie brzmi "jak sumować u, ale zlikwidować dodając do sumy, gdy indeks nie wynosi 5", dodawanie nowych zmiennych i ograniczeń to przesada. Ta odpowiedź dobrze ilustruje linearyzację, ale nie jestem przekonany, czy jest to właściwa odpowiedź na to pytanie. – raoulcousins

Powiązane problemy