我正在尝试使用pyomo解决多目标优化问题。我有一个投资数据框架,其中有三个要最大化的因素,我想确定有两个约束的最佳投资组合权重。第一个约束条件是权重的总和必须等于100%,第二个约束条件是每次持股的权重都在0.5%和10%之间。
这是我的代码:
import pandas as pd
import numpy as np
from pyomo.environ import *
# load dataframe, set index, drop null values
df = pd.read_csv('etf-ranks.csv')
df = df.set_index('ticker')
df = df.dropna()
# select a random sample of 20 ETFs
df_s1 = df.sample(20)
# Initialize an instance of a Pyomo ConcreteModel
model = ConcreteModel()
# Use ETF tickers as the index
tickers = list(df_s1.index.values)
model.i = Set(initialize=tickers, doc='ETFs')
# Create dictionaries of factors so they can be passed to
# ConcreteModel initialize kwarg
factor1_dict = {}
factor2_dict = {}
factor3_dict = {}
weight_dict = {}
for tick in tickers:
factor1_dict[tick] = df_s1.loc[tick, 'factor1']
factor2_dict[tick] = df_s1.loc[tick, 'factor2']
factor3_dict[tick] = df_s1.loc[tick, 'factor3']
# Initial weight = 5%
weight_dict[tick] = .05
# Load factors into ConcreteModel Params
model.a = Param(model.i, initialize=factor1_dict, doc='Factor1')
model.b = Param(model.i, initialize=factor2_dict, doc='Factor2')
model.c = Param(model.i, initialize=factor3_dict, doc='Factor3')
# Designate weights as a Var with min/max of .5%/10%
model.weight = Var(model.i, initialize=weight_dict, bounds=(0.005, 0.1),
doc='Portfolio Weight')
# Start with naive assumption that all three factors are equally important
# I think this might be where my problem starts
# I am trying to tell pyomo to put the most weight on the ETFs
# with the greatest sum of all three factors
def ObjRule(model):
return (summation(model.a, model.b, model.c, index=model.i) *
summation(model.weight, index=model.i))
model.Obj = Objective(rule=ObjRule, sense=maximize)
# Set constraint that weights must sum to 100%
def WeightRule(model):
return summation(model.weight) == 1.0
model.WeightConstraint = Constraint(rule=WeightRule)
def pyomo_postprocess(options=None, instance=None, results=None):
model.weight.display()
opt = SolverFactory("glpk", executable='/path/to/glpk.py', validate=False)
results = opt.solve(model)
# When I run opt.solve(model) I get the following error:
ApplicationError Traceback (most recent call last)
in <module>()
1 opt = SolverFactory("glpk", executable='/path/to/glpk.py', validate=False)
----> 2 results = opt.solve(model)
/path/to/solvers.py in solve(self, *args, **kwds)
624 logger.error("Solver log:\n" + str(_status.log))
625 raise pyutilib.common.ApplicationError(
--> 626 "Solver (%s) did not exit normally" % self.name)
627 solve_completion_time = time.time()
628 if self._report_timing:
ApplicationError: Solver (glpk) did not exit normally
如何设计模型以避免ApplicationError?