2016-06-03 6 views
5

작은 부분에 방정식/불평등 시스템 최적화와 관련된 프로그램이 있습니다. 이상적으로, 나는 Modelica에서 할 수있는 것처럼하고 싶었을 것이고 방정식을 써서 솔버가 처리하도록 할 것입니다.Python - 불평등 시스템 최적화

솔버 및 선형 프로그래밍의 작업은 내 안락 영역에서 벗어나지 만 어쨌든 시도하기로 결정했습니다. 문제는 프로그램의 일반적인 디자인이 객체 지향적이며, 방정식을 형성하는 다양한 조합 가능성과 일부 비선형 성이 있으므로 선형 프로그래밍으로 변환 할 수 없었습니다 문제 (하지만 내가 잘못되었을 수도 있음).

일부 연구를 마친 후 솔버가 내가 원하는 것을 수행 한 것으로 나타났습니다. 이 작품 이제

from z3 import * 

a = Real('a') 
b = Real('b') 
c = Real('c') 
d = Real('d') 
e = Real('e') 
g = Real('g') 
f = Real('f') 
cost = Real('cost') 

opt = Optimize() 
opt.add(a + b - 350 == 0) 
opt.add(a - g == 0) 
opt.add(c - 400 == 0) 
opt.add(b - d * 0.45 == 0) 
opt.add(c - f - e - d == 0) 
opt.add(d <= 250) 
opt.add(e <= 250) 

opt.add(cost == If(f > 0, f * 50, f * 0.4) + e * 40 + d * 20 + 
    If(g > 0, g * 50, g * 0.54)) 

h = opt.minimize(cost) 
opt.check() 
opt.lower(h) 
opt.model() 

, 그것은 (I가 필요로 매우 빠른없는에도 불구하고, 나에게 내가 원하는 결과를 제공합니다 : I (이 내가 최적화 싶은 것이 전형적인 경우처럼 보인다)이 함께했다 그러한 시스템을 수천 번 해결하십시오.) 하지만 작업에 적합한 도구를 사용하고 있는지 확실하지 않습니다 (Z3은 "정리 증명자"임).

API는 기본적으로 정확하게 필요하지만 다른 패키지에서 비슷한 구문을 사용할 수 있는지 궁금합니다. 아니면 표준 LP 접근 방식을 허용하는 다른 방식으로 문제를 공식화해야합니까? (비록 내가 어떻게 알지는 못하지만)

+0

LP 솔버는 약 0 초 만에 이것을 해결할 수 있습니다. 실제로는 너무 작습니다. –

+0

네,하지만 함수의 여러 "if"조건을 어떻게 관리 할 수 ​​있습니까? 내가 본 솔루션은 다소 해킹 된 것처럼 보이고 제 경우에는 실제로 작동하지 않습니다. –

+2

변수 분할을 사용하여 구현할 수 있다고 생각합니다. 예. 음수가 아닌 변수'fplus, fmin'을 소개합니다. 'f = fplus-fmin' 제약 조건을 추가하십시오. 첫 번째'if'는'50fplus-0.4fmin'이됩니다. –

답변

1

Z3은 이러한 유연한 방정식 시스템에서 발견 한 가장 강력한 솔버입니다. Z3은 MIT 라이센스에 따라 출시되어 이제 탁월한 선택입니다.

겹치는 사용 사례가있는 여러 가지 유형의 도구가 많이 있습니다. 선형 프로 그래 밍에 대해 언급했는데 정리 정리기, SMT 해석기 및 기타 여러 유형의 도구가 있습니다. 정리 해설자로서의 마케팅 자체에도 불구하고 Z3은 종종 SMT 솔버로 판매됩니다. 현재 SMT 솔버는 불리언, 실수 및 정수에 대한 결합 대수 방정식 및 불평등의 유연하고 자동화 된 솔루션을 이끌고 있으며 SMT 솔버의 세계에서 Z3은 왕입니다. the results of the last SMT comp if you want evidence of this.을보십시오. 방정식이 모두 선형이라면 CVC4로 더 나은 성능을 얻을 수도 있습니다. 주변을 물색하지 않아도됩니다.

방정식의 형식이 매우 제한되어있는 경우 (예 : 일부 제약 조건에 따라 일부 기능이 최소화되는 경우) GSL 또는 NAG와 같은 수치 라이브러리를 사용하면 성능을 향상시킬 수 있습니다. 그러나 실제로 유연성이 필요하다면 Z3보다 나은 도구를 찾을 수 있을지 의심 스럽습니다.

1

아마도 가장 좋은 해결책은 ILP 솔버를 사용하는 것입니다. 문제는 정수 선형 프로그래밍 (ILP) 인스턴스로 공식화 할 수 있습니다. 많은 ILP 솔버가 있으며 일부는 Z3보다 성능이 좋습니다. 7 개의 변수 만 있으면 알맞은 ILP 솔버가 솔루션을 매우 빨리 찾아야합니다.

유일한 까다로운 비트는 조건식 (If(...))입니다. 그러나 @Erwin Kalvelagen suggests으로 변수 분할을 사용하여 조건을 처리 할 수 ​​있습니다. 예를 들어, 변수 fplusfminus을 입력하고 제약 조건은 f = fplus - fminusfplus >= 0fminus >= 0입니다. 이제 If(f > 0, f * 50, f * 0.4)50 * fplus - 0.4 * fminus으로 바꿀 수 있습니다. 이 경우에 해당됩니다.

가변 분할이 항상 작동하지 않습니다. 가짜 솔루션을 도입할지 여부를 고려해야합니다 (fplus > 0fminus > 0 모두). 이 경우, 가짜 솔루션이 절대로 최적이되지 않습니다. 최적 솔루션이 절대로 최적이 아님을 보여줄 수 있습니다.결과적으로 변수 분할은 여기서 잘 작동합니다.

조건문이 있지만 변수 분할이 작동하지 않는 상황에서는 https://cs.stackexchange.com/q/12102/755의 기술을 사용하여 문제를 ILP의 인스턴스로 공식화 할 수 있습니다.