0

Used cp.Maximize functionality of CVXPY to maximise the sumproduct of weight and score. Added constraint that w cannot be greater than zero, but it failed.

import cvxpy as cp
score = [0.5322351127,0.3196822284,0.5692263923,0.02034915925,0.2286454903,0.9427046072,0.348096277,0.9307845065,0.3239363128,0.7505620803,0.0594313546,0.3672346647,0.4161681319]
w = cp.Variable(13)
ret = score*w 
prob = cp.Problem(cp.Maximize(ret), [cp.sum(w) == 1, w >= 0])
prob.solve(verbose=True)
print(w.value)
print(sum(w.value))

Output Looks like :


-----------------------------------------------------------------
           OSQP v0.6.0  -  Operator Splitting QP Solver
              (c) Bartolomeo Stellato,  Goran Banjac
        University of Oxford  -  Stanford University 2019
-----------------------------------------------------------------
problem:  variables n = 13, constraints m = 14
          nnz(P) + nnz(A) = 26
settings: linear system solver = qdldl,
          eps_abs = 1.0e-05, eps_rel = 1.0e-05,
          eps_prim_inf = 1.0e-04, eps_dual_inf = 1.0e-04,
          rho = 1.00e-01 (adaptive),
          sigma = 1.00e-06, alpha = 1.60, max_iter = 10000
          check_termination: on (interval 25),
          scaling: on, scaled_termination: off
          warm start: on, polish: on, time_limit: off

iter   objective    pri res    dua res    rho        time
   1  -1.7357e+01   7.24e+00   9.45e+01   1.00e-01   1.51e-04s
 200  -9.4307e-01   5.73e-05   4.29e-05   1.29e+00   6.91e-04s
 300  -9.4280e-01   1.44e-05   1.61e-05   2.31e-01   9.48e-04s
plsh  -9.4270e-01   2.78e-23   5.23e-17   --------   1.12e-03s

status:               solved
solution polish:      successful
number of iterations: 300
optimal objective:    -0.9427
run time:             1.12e-03s
optimal rho estimate: 2.12e-01

[-1.71355380e-28 -1.71128890e-28 -1.71393898e-28 -1.70811497e-28
 -1.71033364e-28  1.00000000e+00 -1.71159705e-28  1.38776160e-23
 -1.71133513e-28  2.77554040e-23 -1.70853097e-28 -1.71179735e-28
 -1.71232120e-28]
1.0

Clearly weights are negative.

sascha
  • 32,238
  • 6
  • 68
  • 110

1 Answers1

1

The result is as good as it gets. The negative entries are near-zero -> scientific notation (with high accuracy).

Some (more advanced) hints:

  • your problem is very trivial and most of cvxpy's solvers will not be competitive in terms of accuracy compared to approaches with more assumptions!

    • your problem can be expressed as LP
      • a simplex-based lp-solver would give you a basic-feasible solution and your near-zeros would be real zeros
      • (there are even rational simplex implementations for the crazy ones)
  • while cvxpy probably recognized this problem as lp-compatible, it's basic-installation does not bring a simplex-based lp-solver
    • glpk and clp/cbc (the leading open source LP/MIP solvers) are usable from within cvxpy, but install will need some care (it's documented!)
    • some solvers within cvxpy (e.g. ECOS) are interior-point solvers (second-order), which:
      • are very very accurate
      • but: they approximate the solution (iterative) and will not provide a basic-feasible solution
        • without an additional simplex-based crossover there will be near-zeros
    • here cvxpy even selects an ADMM-based solver (first order!) which is even less accurate in general than interior-point solvers (and less robust); usually targeting performance
      • these are also iterative and will approximate solutions leading to near-zeros

This means for you:

  • either accept this behaviour and care about this in postprocessing (e.g. rounding)
  • install cvxpy with GLPK or CLP/CBC (or some of the commercials) and make sure one of those is used
  • don't use cvxpy; but something with less hidden-magic (disclaimer: cvxpy is great! but it's not a silver bullet)
sascha
  • 32,238
  • 6
  • 68
  • 110
  • Thanks. @sascha. I saw post talking about linear optimisation with https://www.cvxpy.org/examples/basic/linear_program.html. – Gautam Kakkar Dec 18 '19 at 12:54