Minimax optimization in PICOS

梦想与她 提交于 2019-12-10 12:06:37

问题


I have a generic question on how to solve optimization problems of the Min-Max type, using the PICOS package in Python. I found little information in this context while searching the PICOS documentation and on the web as well.

I can imagine a simple example of the below form.

Given a matrix M, find x* = argmin_x [ max_y x^T M y ], where x > 0, y > 0, sum(x) = 1 and sum(y) = 1.

I have tried a few methods, starting with the most straightforward idea of having minimax, minmax keywords in the objective function of PICOS Problem class. It turns out that none of these keywords are valid, see the package documentation for objective functions. Furthermore, having nested objective functions also turns out to be invalid.

In the last of my naive attempts, I have two functions, Max() and Min() which are both solving a linear optimization problem. The outer function, Min(), should minimize the inner function Max(). So, I have used Max() in the objective function of the outer optimization problem.

import numpy as np
import picos as pic
import cvxopt as cvx

def MinMax(mat):
    ## Perform a simple min-max SDP formulated as:
    ## Given a matrix M, find x* = argmin_x [ max_y x^T M y ], where x > 0, y > 0, sum(x) = sum(y) = 1.

    prob = pic.Problem()

    ## Constant parameters
    M = pic.new_param('M', cvx.matrix(mat))
    v1 = pic.new_param('v1', cvx.matrix(np.ones((mat.shape[0], 1))))

    ## Variables
    x = prob.add_variable('x', (mat.shape[0], 1), 'nonnegative')

    ## Setting the objective function
    prob.set_objective('min', Max(x, M))

    ## Constraints
    prob.add_constraint(x > 0)
    prob.add_constraint((v1 | x) == 1)

    ## Print the problem
    print("The optimization problem is formulated as follows.")
    print prob

    ## Solve the problem
    prob.solve(verbose = 0)

    objVal = prob.obj_value()
    solution = np.array(x.value)

    return (objVal, solution)

def Max(xVar, M):
    ## Given a vector l, find y* such that l y* = max_y l y, where y > 0, sum(y) = 1.

    prob = pic.Problem()

    # Variables
    y = prob.add_variable('y', (M.size[1], 1), 'nonnegative')
    v2 = pic.new_param('v1', cvx.matrix(np.ones((M.size[1], 1))))

    # Setting the objective function
    prob.set_objective('max', ((xVar.H * M) * y))

    # Constraints
    prob.add_constraint(y > 0)
    prob.add_constraint((v2 | y) == 1)

    # Solve the problem
    prob.solve(verbose = 0)

    sol = prob.obj_value()

    return sol


def print2Darray(arr):
    # print a 2D array in a readable (matrix like) format on the standard output
    for ridx in range(arr.shape[0]):
        for cidx in range(arr.shape[1]):
            print("%.2e \t" % arr[ridx,cidx]),

        print("")

    print("========")

    return None


if __name__ == '__main__':
    ## Testing the Simple min-max SDP
    mat = np.random.rand(4,4)
    print("## Given a matrix M, find x* = argmin_x [ max_y x^T M y ], where x > 0, y > 0, sum(x) = sum(y) = 1.")
    print("M = ")
    print2Darray(mat)
    (optval, solution) = MinMax(mat)
    print("Optimal value of the function is %.2e and it is attained by x = %s and that of y = %.2e." % (optval, np.array_str(solution)))

When I run the above code, it gives me the following error message.

10:stackoverflow pavithran$ python minmaxSDP.py 
## Given a matrix M, find x* = argmin_x [ max_y x^T M y ], where x > 0, y > 0, sum(x) = sum(y) = 1.
M = 
1.46e-01    9.23e-01    6.50e-01    7.30e-01    
6.13e-01    6.80e-01    8.35e-01    4.32e-02    
5.19e-01    5.99e-01    1.45e-01    6.91e-01    
6.68e-01    8.46e-01    3.67e-01    3.43e-01    
========
Traceback (most recent call last):
  File "minmaxSDP.py", line 80, in <module>
    (optval, solution) = MinMax(mat)
  File "minmaxSDP.py", line 19, in MinMax
    prob.set_objective('min', Max(x, M))
  File "minmaxSDP.py", line 54, in Max
    prob.solve(verbose = 0)
  File "/Library/Python/2.7/site-packages/picos/problem.py", line 4135, in solve
    self.solver_selection()
  File "/Library/Python/2.7/site-packages/picos/problem.py", line 6102, in solver_selection
    raise NotAppropriateSolverError('no solver available for problem of type {0}'.format(tp))
picos.tools.NotAppropriateSolverError: no solver available for problem of type MIQP
10:stackoverflow pavithran$ 

At this point, I am stuck and unable to fix this problem.

Is it just that PICOS does not natively support min-max problem or is my way of encoding the problem, incorrect?

Please note: The reason I am insisting on using PICOS is that ideally, I would like to know the answer to my question in the context of solving a min-max semidefinite program (SDP). But I think the addition of semidefinite constraints is not hard, once I can figure out how to do a simple min-max problem using PICOS.


回答1:


The first answer is that min-max problems are not natively supported in PICOS. However, whenever the inner maximization problem is a convex optimization problem, you can reformulate it as a minimization problem (by taking the Lagrangian dual), and so you get a min-min problem.

Your particular problem is a standard zero-sum game, and can be reformulated as: (assuming M is of dimension n x m):

min_x max_{i=1...m} [M^T x]_i = min_x,t  t  s.t. [M^T x]_i <= t (for i=1...m)

In Picos:

import picos as pic
import cvxopt as cvx

n=3
m=4
M = cvx.normal(n,m) #generate a random matrix

P = pic.Problem()
x = P.add_variable('x',n,lower=0)
t = P.add_variable('t',1)
P.add_constraint(M.T*x <= t)
P.add_constraint( (1|x) == 1)
P.minimize(t)
print 'the solution is x='
print x

If you also need the optimal y, then you can show that it corresponds to the optimal value of the constraint M'x <= t:

print 'the solution of the inner max-problem is y='
print P.constraints[0].dual

Best, Guillaume.



来源:https://stackoverflow.com/questions/35675269/minimax-optimization-in-picos

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!