如何解决cvxpy和gurobi的优化对比
有许多作业要分配给许多资源,每个作业都有一个分数(性能指标)和成本。资源分配问题 (RAP) 的目标是在考虑预算的情况下最大化分配分数。 限制条件:每个资源最多只能处理一项工作,并且每项工作如果被填充应由一个资源完成。此外,预算有限。 我通过两种方式解决了这个问题:CVXPY 使用 gurobi 求解器和 gurobi 包。我的挑战是我无法使用 cvxpy 以节省内存的方式对其进行编程。有数百个约束列表推导式!如何提高 cvxpy 中代码的效率? 比如在cvxpy中有没有更好的方法来定义类似于gurobi的字典变量?
ms 是格式为 {('firstName lastName','job'),score_value}
的字典
cst 是格式为 {('firstName lastName',cost_value}
的字典
job 是一组工作
res 是一组资源 {'firstName lastName'}
G(或 gurobi 实现中的 g )是一个字典,以工作为键,值为 0 或 1如果没有)
谢谢 github link including codes and memory profiling comparison
gurobi 实施:
m = gp.Model("RAP")
assign = m.addVars(ms.keys(),vtype=GRB.BINARY,name="assign")
g = m.addVars(job,name="gap")
m.addConstrs((assign.sum("*",j) + g[j] == 1 for j in job),name="demand")
m.addConstrs((assign.sum(r,"*") <= 1 for r in res),name="supply")
m.addConstr(assign.prod(cst) <= budget,name="Budget")
job_gap_penalty = 101 # penatly of not filling a job
m.setobjective(assign.prod(ms) -job_gap_penalty*g.sum(),GRB.MAXIMIZE)
m.optimize()
cvxpy 实现:
X = {}
for a in ms.keys():
X[a] = cp.Variable(boolean=True,name="assign")
G = {}
for g in job:
G[g] = cp.Variable(boolean=True,name="gap")
constraints = []
for j in job:
X_r = 0
for r in res:
X_r += X[r,j]
constraints += [
X_r + G[j] == 1
]
for r in res:
X_j = 0
for j in job:
X_j += X[r,j]
constraints += [
X_j <= 1
]
constraints += [
np.array(list(cst.values())) @ np.array(list(X.values())) <= budget,]
obj = cp.Maximize(np.array(list(ms.values())) @ np.array(list(X.values()))
- job_gap_penalty * cp.sum(list(G.values())))
prob = cp.Problem(obj,constraints)
prob.solve(solver=cp.GUROBI,verbose=False)
这是内存分析比较:
解决方法
以前,我试图通过定义类似于 gurobi 的字典变量来解决,但是 at 在 cvxpy 中不可用,代码在扩展时效率不高。但是现在我通过矩阵变量解决了它,然后转换为超快的字典变量!
assign_scores = np.array(list(ms.values())).reshape(len(res),len(job))
assign_cost = np.array(list(cst.values())).reshape(len(res),len(job))
# make a bool matrix variable with the shape of number of resources and jobs
x = cp.Variable(shape=(len(res),len(job)),boolean=True,name="assign")
# make a bool vector variable with the shape of number of jobs
g = cp.Variable(shape=(len(job),),name="gap")
constraints = []
# each job can be assigned to at most one resource or remains unfilled due to budget cap
constraints += [cp.sum(x[:,j]) + g[j] == 1 for j in range(len(job))]
# each resource can be assigned to at most one job
constraints += [cp.sum(x[r,:]) <= 1 for r in range(len(res))]
# budget cap
constraints += [cp.sum(cp.multiply(assign_cost,x)) <= budget]
# pentalty if a job is not filled
job_gap_penalty=101
# objective is to maiximize performance score
obj = cp.Maximize(cp.sum(cp.multiply(assign_scores,x) - job_gap_penalty * cp.sum(g)))
prob = cp.Problem(obj,constraints)
prob.solve(solver=cp.GUROBI,verbose=True)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。