ApplicationError: pyomo solver не выходит нормально - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь решить многоцелевую задачу оптимизации с помощью 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?

...