我最近遇到了一个有趣的程序包/文件,称为dmcp(有规则的多凸编程)。您可以找到link to the repo here和link to the paper here。
我想用它来解决我一直在研究中的模型中的平衡问题(问题实际上是凸的,但是我一直在努力将其转换成DCP形式,所以我觉得拥有它会很不错作为备份)。
我们已经证明了平衡总是存在的,并且我已经在我手工解决的一个玩具示例中测试了以下代码,但是由于某些原因,由于CVX变量之一值变大,DMCP在几次迭代后失败了。无类型(我认为)。
查看DMCP存储库的代码后,我相信当他们使用CVXPy时该错误发生在某个地方,但我不知道该错误是在DMCP还是在CVXPy中。
我要使用的代码具有参数:
num_agents = 2
num_goods = 2
adjacency_matrix = np.eye(2)
endowment = np.eye(2)
utilities = np.abs(np.eye(2)-1)
resale = np.ones(num_agents)
变量:
prices = cp.Variable((num_agents,num_goods), nonneg=True)
consumption = cp.Variable((num_agents*num_agents,num_goods), nonneg=True)
resale = cp.Variable((num_agents*num_agents,num_goods), nonneg=True)
sum_x_ij = cp.Variable((num_agents,num_goods), nonneg=True)
sum_x_ji = cp.Variable((num_agents,num_goods), nonneg=True)
sum_y_ij = cp.Variable((num_agents,num_goods), nonneg=True)
sum_y_ji = cp.Variable((num_agents,num_goods), nonneg=True)
初始值:
prices.value = np.random.uniform(low=.1,high=1.1,size=(num_agents,num_goods))
consumption.value = np.ones((num_agents*num_agents,num_goods))
resale.value = np.ones((num_agents*num_agents,num_goods))
辅助功能:
def map_to_idx(agent,neighbor):
return (agent*num_agents)+neighbor
目标:
obj = 0#cp.sum(cp.multiply(utilities[:,:-1],sum_x_ij)) #+ cp.sum(cp.sum(cp.multiply(prices,sum_y_ij),axis=1))
for agent in range(num_agents):
if utilities[agent,-1] != 1:
obj += cp.pnorm(cp.multiply(cp.power(utilities[agent,:-1],1.0/utilities[agent,-1]),sum_x_ij[agent,:]),utilities[agent,-1])
else:
obj += utilities[agent,:-1]*sum_x_ij[agent,:]
obj += prices[agent,:]*sum_y_ij[agent,:]
for neighbor in range(num_agents):
obj -= prices[neighbor,:]*resale[map_to_idx(agent,neighbor),:]
约束:
constraints = [prices >= 0.1, consumption >= 0, resale >= 0, sum_x_ij >= 0, sum_x_ji >= 0, sum_y_ij >= 0, sum_y_ji >= 0]
for agent in range(num_agents):
constraints += [sum_x_ji[agent,:] + sum_y_ji[agent,:] == endowments[agent,:] + sum_y_ij[agent,:]]
constraints += [cp.sum(sum_y_ij[agent,:]) <= resale_vect[agent]]
lhs_budget_const = 0
rhs_budget_const = prices[agent,:]*endowments[agent,:] + prices[agent,:]*sum_y_ij[agent,:]
lhs_sum_xij = 0
lhs_sum_yij = 0
lhs_sum_xji = 0
lhs_sum_yji = 0
for neighbor in range(num_agents):
lhs_budget_const += prices[neighbor,:]*consumption[map_to_idx(agent,neighbor),:]
rhs_budget_const -= prices[neighbor,:]*resale[map_to_idx(agent,neighbor),:]
if adjacency_matrix[agent,neighbor] == 0:
constraints += [consumption[map_to_idx(agent,neighbor),:] == 0]
constraints += [resale[map_to_idx(agent,neighbor),:] == 0]
lhs_sum_xij += consumption[map_to_idx(agent,neighbor),:]
lhs_sum_yij += resale[map_to_idx(agent,neighbor),:]
lhs_sum_xji += consumption[map_to_idx(neighbor,agent),:]
lhs_sum_yji += resale[map_to_idx(neighbor,agent),:]
constraints += [lhs_budget_const == rhs_budget_const]
constraints += [lhs_sum_xij == sum_x_ij[agent,:]]
constraints += [lhs_sum_xji == sum_x_ji[agent,:]]
constraints += [lhs_sum_yij == sum_y_ij[agent,:]]
constraints += [lhs_sum_yji == sum_y_ji[agent,:]]
constraints += [resale[map_to_idx(agent,agent),:] == 0]
constraints += [cp.sum(prices) == 1]
constraints += [cp.sum(consumption,axis=0) == cp.sum(endowments,axis=0)]
最后:
prob = cp.Problem(cp.Maximize(obj), constraints)
print()
print("minimal sets:", dmcp.find_minimal_sets(prob))
print("problem is DMCP:", dmcp.is_dmcp(prob))
print()
result = prob.solve(method='bcd',max_iter = 100)
print(result)
print()
print("p = " + str(prices.value))
print("x = " + str(sum_x_ij.value))
print("y = " + str(sum_y_ij.value))
我知道该程序有解决方案。当我注释掉我将价格乘以sum_y_ij并转售的目标部分时,我的运行会很顺利。当目标中存在该错误时,我将得到以下输出/错误:
Defining variables
Setting some initial guesses
Defining objective
Defining constraints
minimal sets: [[0], [1, 2, 5]]
problem is DMCP: True
max abs slack = 11.257764306622317 mu = 0.005 original objective value = 41.569236735359254 fixed objective value = 20.693015614921645 status= optimal
max abs slack = 21.155476427136296 mu = 0.005 original objective value = 81.25842921844962 fixed objective value = 60.55171440353868 status= optimal
max abs slack = 30.996381672274627 mu = 0.0075 original objective value = 120.77145211345528 fixed objective value = 99.41459375605088 status= optimal
max abs slack = 40.85265643546646 mu = 0.0075 original objective value = 160.97795623707566 fixed objective value = 138.83652995015788 status= optimal
max abs slack = 50.630481600263245 mu = 0.01125 original objective value = 200.88955474035853 fixed objective value = 177.10923936689406 status= optimal
max abs slack = 200.65501019663174 mu = 0.01125 original objective value = 442.07817550005626 fixed objective value = 319.96444147471675 status= optimal
max abs slack = 388.4237602479294 mu = 0.016875 original objective value = 671.3475469742531 fixed objective value = 540.2441656255529 status= optimal
max abs slack = 53335.2974424018 mu = 0.016875 original objective value = 54331.04746214825 fixed objective value = 35106.94351475132 status= optimal_inaccurate
max abs slack = 215936.17724686957 mu = 0.0253125 original objective value = 219254.45219690344 fixed objective value = 40873.564352143076 status= optimal_inaccurate
max abs slack = 27527746.923883904 mu = 0.0253125 original objective value = 23405815.216764793 fixed objective value = 7009847.781686075 status= optimal_inaccurate
Traceback (most recent call last):
File "driver.py", line 64, in <module>
solv.find_multi_convex_equilibrium(num_agents, num_goods, adjacency_matrix, endowments, utilities, resale_vect, initial_guess=None, verbose=True)
File "/home/gabe/Graphical_Econs_with_Resale/Jain_Convex_Program/solver.py", line 123, in find_multi_convex_equilibrium
result = prob.solve(method='bcd',max_iter = 100)
File "/usr/local/lib/python3.5/dist-packages/cvxpy/problems/problem.py", line 289, in solve
return solve_func(self, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/dmcp-1.0.0-py3.5.egg/dmcp/bcd.py", line 72, in bcd
result = _bcd(prob, fix_sets, max_iter, solver, mu, rho, mu_max, ep, lambd, linearize, proximal)
File "/usr/local/lib/python3.5/dist-packages/dmcp-1.0.0-py3.5.egg/dmcp/bcd.py", line 119, in _bcd
max_slack = np.max([np.max(np.abs(var.value)) for var in var_slack])
File "/usr/local/lib/python3.5/dist-packages/dmcp-1.0.0-py3.5.egg/dmcp/bcd.py", line 119, in <listcomp>
max_slack = np.max([np.max(np.abs(var.value)) for var in var_slack])
TypeError: bad operand type for abs(): 'NoneType'
如果我在目标中甚至包含单个价格[0,0] *转售[0,0],甚至会发生此错误。
任何建议都会很有帮助!谢谢!