C-Optを使ってGurobiモデルを解くためのwrapper
C-Optは中国製のGurobiもどきだ.ベンチマークでは2位が多い.マニュアルはここにあり,学生は無料で1年使える.日本からでもOK.
https://guide.coap.online/copt/en-doc/index.html#
以下のコードをまずまわしておく.
#c-opt wrapper
import coptpy as cp
from coptpy import COPT, quicksum, tuplelist, multidict, tupledict
GRB = COPT
class Model():
def __init__(self, name=""):
env = cp.Envr()
self.ObjVal = None
self.model = env.createModel(name)
def addVar(self, *args, **kwargs):
return self.model.addVar(*args, **kwargs)
def addConstr(self, *args, **kwargs):
return self.model.addConstr(*args, **kwargs)
def setObjective(self, *args, **kwargs):
return self.model.setObjective(*args, **kwargs)
def getVars(self, *args, **kwargs):
return self.model.getVars(*args, **kwargs)
def getConstrs(self, *args, **kwargs):
return self.model.getConstrs(*args, **kwargs)
def getSOS(self, *args, **kwargs):
return self.model.SOS(*args, **kwargs)
def setParam(self, *args, **kwargs):
return self.model.setParam(*args, **kwargs)
def optimize(self):
ret = self.model.solve()
self.ObjVal = self.model.objval
self.status = self.model.status
return ret
例として多制約ナップサックの難しい問題例を作って,Gurobiモデルを書いて解く.
a = {}
b, v = [], []
m = 5
n = 100
for i in range(m):
sumA = 0.0
for j in range(n):
a[i, j] = 1.0 - math.log(random.random(), 2)
sumA += a[i, j]
b.append(0.25 * sumA)
for j in range(n):
sumA = 0.0
for i in range(m):
sumA += a[i, j]
v.append(10.0 * sumA / m + 10.0 * random.random())
J = list(range(n))
I = list(range(m))
model = Model("mkp")
x = {}
for j in J:
x[j] = model.addVar(vtype="B", name=f"x({j})")
#model.update()
constr = {}
for i in I:
for j in J:
constr[i,j] = model.addConstr(quicksum(a[i, j] * x[j] for j in J) <= b[i], f"Capacity({i},{j})")
model.setParam(GRB.Param.TimeLimit, 10.0)
model.setObjective(quicksum(v[j] * x[j] for j in J), GRB.MAXIMIZE)
model.optimize()
すると C-Optで解ける.
解の確認はこうする.
if model.status == GRB.OPTIMAL:
print("Objective value =", model.ObjVal)
print("Solution:")
for j in x:
print(f"x[{j}]={x[j].X}")
この記事が気に入ったらサポートをしてみませんか?