2016-08-15 5 views
0

차라리 간단 목적 함수를 최소화하고 싶지만, 어떻게 든 제가하는 방법을 보았다 파이썬 API가선형 및 이차 용어는

을 CPLEX하는에서 올바른 호출을하는 데 문제가 set_quadraticset_quadratic_coefficientshere을 사용해도 내 문제가 해결되지 않았습니다.

내 목적 함수는 선형 변수 세트와

varCoefs = [1]*(numB + numQ) 
varLower = [0]*(numB + numQ) 
varNames = [(x,"b%s"%x) for x in range(numB)] 
varNames += [(len(varNames) + x,"q%s"%x) for x in range(numQ)] 

varCoefs += [10]*len(deltas) 
varLower += [1]*len(deltas) 
varNames += [(len(varNames) + x,"delta%s"%x) for x in range(len(deltas))] 

varCoefs += [0]*len(target.v) 
varLower += [0]*len(target.v) 

sContent = [(len(varNames) + x,"s%s"%x) for x in range(len(target.v))] 
varNames += sContent 

varCoefs += [-1] 
varLower += [0] 
varNames += [(len(varNames),'mu')] 


problem.variables.add(obj = varCoefs, lb = varLower) 
problem.variables.set_names(varNames) 

# problem.objective.set_quadratic_coefficients([[['s%s' % x], [1]] for x in range(len(target.v))]) 

problem.objective.set_quadratic(
    [cplex.SparsePair(ind=[sContent[x][0]], val=[1]) for x in range(len(target.v))] 
    ) 

모든 것이 차 조건을 추가하려면 마지막 통화까지 작동 차 변수 세트가 있습니다. 어느 시점에서 CPLEX는 다음 오류 CPLEX Error 1226: Array entry 13919 not ascending.을 두 번 던지고 명령을 무시하면 Python 코드가 계속됩니다.

나는 error을 찾아 보았지만, 저도 도움이되지 않았습니다.

나는 변수를 이름과 하한 우선으로 다시 쓰려고 시도한 다음 나중에 set_linearset_quadratic을 호출하지만 그 중 하나도 도움이되지 않습니다.

무엇이 여기에 있습니까?

답변

0

먼저 이차 항을 더하고 계수를 설정 한 다음 별도의 호출에서 선형 항을 더하여이 문제를 해결했습니다.

problem.objective.set_sense(problem.objective.sense.minimize) 

varLower = [0]*len(target.v) 
varNames = ["s%s"%x for x in range(len(target.v))] 

problem.variables.add(names=varNames, lb=varLower) 

problem.objective.set_quadratic(
    [[[x],[1]] for x in range(len(target.v))] 
    ) 

varCoefs = [-1] 
varLower = [0] 
varNames = ['mu'] 


varCoefs += [1]*(numB + numQ) 
varLower += [0]*(numB + numQ) 
varNames += ["b%s"%x for x in range(numB)] 
varNames += ["q%s"%x for x in range(numQ)] 

varCoefs += [10]*len(deltas) 
varLower += [1]*len(deltas) 
varNames += ["delta%s"%x for x in range(len(deltas))] 

problem.variables.add(names=varNames, lb=varLower, obj=varCoefs) 

그러나 나는 아직도 왜 이런 방식으로 작동하는지 알고 싶습니다.

+1

문서가'set_quadratic'에 대해 말한 것처럼, "문제의 변수의 수와 길이가 같은 목록으로"호출해야하기 때문에이 방법이 효과적이라고 생각합니다. – rkersh

+0

아아, 나는 그것을 놓쳤다. 다시 한번 감사드립니다. – Constantine

1

분리 가능한 2 차 목적 함수 인 set_quadratic을 호출하는 경우 CPXXcopyqpsep에 해당합니다. 분리 할 수없는 2 차 목적 함수가있는 set_quadratic을 호출하는 경우 CPXXcopyquad에 해당합니다. 난 당신이 받고있는 오류가 특히 유용하지 않다는 데 동의하지만, Callable C Library에서 어디서 오는 것인지 알면 좀 더 이해가됩니다. 차라리 지능형리스트를 사용하는 것보다 긴 형태로 그를 작성했습니다

import cplex 

class MockTarget(object): 
    pass 

# Dummy data for testing 

numB = 3 
numQ = 3 
deltas = [0.1, 0.1, 0.1] 
problem = cplex.Cplex() 

target = MockTarget() 
target.v = [1, 2, 3] 

# Build the problem 

varCoefs = [1]*(numB + numQ) 
varLower = [0]*(numB + numQ) 
varNames = [(x,"b%s"%x) for x in range(numB)] 
varNames += [(len(varNames) + x,"q%s"%x) for x in range(numQ)] 

varCoefs += [10]*len(deltas) 
varLower += [1]*len(deltas) 
varNames += [(len(varNames) + x,"delta%s"%x) for x in range(len(deltas))] 

varCoefs += [0]*len(target.v) 
varLower += [0]*len(target.v) 

sContent = [(len(varNames) + x,"s%s"%x) for x in range(len(target.v))] 
varNames += sContent 

varCoefs += [-1] 
varLower += [0] 
varNames += [(len(varNames),'mu')] 


problem.variables.add(obj = varCoefs, lb = varLower) 
problem.variables.set_names(varNames) 

# Print without quadratic terms so you can see the progression. 
problem.write('test1.lp') 

# Separable Q 

qsepvec = [] 
for tpl in varNames: 
    if tpl in sContent: 
     qsepvec.append(1.0) 
    else: 
     qsepvec.append(0.0) 
print qsepvec 

problem.objective.set_quadratic(qsepvec) 

problem.write('test2.lp') 

# Inseparable Q (overwrites previous Q) 

qmat = [] 
for tpl in varNames: 
    if tpl in sContent: 
     sp = cplex.SparsePair(ind=[tpl[0]], val=[1.0]) 
     qmat.append(sp) 
    else: 
     sp = cplex.SparsePair(ind=[], val=[]) 
     qmat.append(sp) 
print qmat 

problem.objective.set_quadratic(qmat) 

problem.write('test3.lp') 

이 좀 더 명확하게하기 위해 : 그와

는 여기에 몇 가지 더미 입력을, 당신의 조각을 사용하여 완벽한 예입니다 말했다 . 하여 LP 파일의 내용은 다음과 같습니다 :

test1.lp :

\ENCODING=ISO-8859-1 
\Problem name: 

Minimize 
obj: b0 + b1 + b2 + q0 + q1 + q2 + 10 delta0 + 10 delta1 + 10 delta2 + 0 s0 
     + 0 s1 + 0 s2 - mu 
Bounds 
     delta0 >= 1 
     delta1 >= 1 
     delta2 >= 1 
End 

test2.lp

\ENCODING=ISO-8859-1 
\Problem name: 

Minimize 
obj: b0 + b1 + b2 + q0 + q1 + q2 + 10 delta0 + 10 delta1 + 10 delta2 + 0 s0 
     + 0 s1 + 0 s2 - mu + [ s0 ^2 + s1 ^2 + s2 ^2 ]/2 
Bounds 
     delta0 >= 1 
     delta1 >= 1 
     delta2 >= 1 
End 

당신은 그 TEST2을 볼 수 있습니다

\ENCODING=ISO-8859-1 
\Problem name: 

Minimize 
obj: b0 + b1 + b2 + q0 + q1 + q2 + 10 delta0 + 10 delta1 + 10 delta2 + 0 s0 
     + 0 s1 + 0 s2 - mu + [ s0 ^2 + s1 ^2 + s2 ^2 ]/2 
Bounds 
     delta0 >= 1 
     delta1 >= 1 
     delta2 >= 1 
End 

test3.lp .lp와 test3.lp는 동일합니다 (나중에 앞의 내용을 덮어 쓰지만 같은 것을합니다). 잘하면 이해하기가 쉽습니다. 일반적으로 매우 간단한 문제에 대해 LP를 인쇄하는이 기술을 사용하면보다 유용한 디버깅 기술 중 하나입니다.

또한 CPLEX와 함께 제공되는 python 예제를 확인해야합니다. 예 : qpex1.py, miqpex1.py, indefqpex1.py.

+0

설명해 주셔서 감사합니다. 그러나 test1은 2 차항을 포함하고 있지 않습니다. test3은 실제로 test2의 복제물입니다. 왜냐하면 실제로'qmat'를'set_quadratic'에 전달하지 않았고'qmat'를 전달했다면 내가 가진 것과 같은 오류. 그러나 이미 문제를 다른 방식으로 해결했습니다. 아래의 솔루션을 참조하십시오. – Constantine

+0

목적에 2 차 제약이없는 test1.lp를 내 보냈습니다. 그래서 당신은 진보를 볼 수있었습니다. 거기에 내 실수에 대해 죄송합니다. 나는 그것을 바로 잡을 것이다. – rkersh

+1

끝에 qmat를 사용하여 오류를 수정했습니다. – rkersh