2016-08-15 7 views
0

私はむしろシンプルである目的関数を最小化したいと思いますが、私は何とか私はどのように見リニアおよびCPLEX目的関数における二次項

をCPLEXするためのPython APIからの正しい呼び出しを行う問題を抱えています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.を2回スローし、コマンドを無視するとPythonコードが続行されます。

私はerrorを検索しましたが、それはどちらも役に立ちませんでした。

私は変数を名前と下限で最初に書き直してから、set_linearset_quadraticを呼び出してみましたが、それでもどちらも役に立ちません。

私はここで何が欠けていますか?

答えて

0

最初に2次項を追加し、その係数を設定し、次に別の呼び出しで線形項を追加することで問題を解決しました。

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に対応します。不可分な二次目的関数を持つ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を印刷するこの手法を使用することは、より有用なデバッグ手法の1つです。

CPLEXに同梱されているPythonの例もチェックしてください。たとえば、qpex1.py、miqpex1.py、indefqpex1.pyなどです。

+0

ありがとうございます。しかし、あなたの解決策には2つの問題があります.test1は2次項を含まず、test3は実際には 'test2'の複製です。実際に' qmat'を 'set_quadratic'に渡すわけではないので、' qmat'を渡すと、私と同じエラーです。 しかし、私は既に問題を別の方法で解決しました。以下の解決策を参照してください。 – Constantine

+0

2次制約のないtest1.lpを目的にエクスポートしました。あなたは進歩を見ることができました。私の最後のミスについては申し訳ありません。私はそれを修正します。 – rkersh

+1

最後にqmatでエラーを修正しました。 – rkersh

関連する問題