Exemplo n.º 1
0
def maximize_fapx_cvxopt( node, problem, scoop=False):
    '''
    Finds the value of y solving maximize sum(fapx(x)) subject to:
                       constr
                       l <= x <= u
    fapx is calculated by approximating the functions given in fs
    as the concave envelope of the function that is tight, 
    for each coordinate i, at the points in tight[i]
    fs should be a list of tuples containing the function and its derivative
    corresponding to each coordinate of the vector x.
  
    Returns a dict containing the optimal variable y as a list, 
    the optimal value of the approximate objective,
    and the value of sum(f(x)) at x.
    
    scoop = True optionally dumps all problem parameters into a file
    which can be parsed and solved using the scoop second order cone 
    modeling language
    '''
    n = len(node.l);
    l = matrix(node.l); u = matrix(node.u)

    x = problem.variable
    constr = problem.constr
        
    # add box constraints
    box = [x[i]<=u[i] for i in xrange(n)] + [x[i]>=l[i] for i in xrange(n)]

    # find approximation to concave envelope of each function
    (fapx,slopes,offsets,fapxs) = utilities.get_fapx(node.tight,problem.fs,l,u,y=x)
    
    if problem.check_z:
        utilities.check_z(problem,node,fapx,x)
        
    if scoop:
        utilities.scoop(p,node,slopes,offsets)
    
    obj = sum( fapx )
    o = op(obj,constr + box)
    try:
        o.solve(solver = 'glpk')
    except:
        o.solve()
    if not o.status == 'optimal':
        if o.status == 'unknown':
            raise ImportError('Unable to solve subproblem. Please try again after installing cvxopt with glpk binding.')
        else:
            # This node is dead, since the problem is infeasible
            return False
    else:
        # find the difference between the fapx and f for each coordinate i
        fi = numpy.array([problem.fs[i][0](x.value[i]) for i in range(n)])
        fapxi = numpy.array([list(-fun.value())[0] for fun in fapx])
        #if verbose: print 'fi',fi,'fapxi',fapxi
        maxdiff_index = numpy.argmax( fapxi - fi )
        results = {'x': list(x.value), 'fapx': -list(obj.value())[0], 'f': float(sum(fi)), 'maxdiff_index': maxdiff_index}
        return results
Exemplo n.º 2
0
def maximize_fapx_glpk( node, problem, verbose = False ):
    '''
    Finds the value of y solving maximize sum(fapx(x)) subject to:
                       constr
                       l <= x <= u
    fapx is calculated by approximating the functions given in fs
    as the concave envelope of the function that is tight, 
    for each coordinate i, at the points in tight[i]
    fs should be a list of tuples containing the function and its derivative
    corresponding to each coordinate of the vector x.
  
    Returns a dict containing the optimal variable y as a list, 
    the optimal value of the approximate objective,
    and the value of sum(f(x)) at x.
    '''
    n = len(node.l);
    l = node.l; u = node.u
    
    # find approximation to concave envelope of each function
    (slopes,offsets,fapxs) = utilities.get_fapx(node.tight,problem.fs,l,u)
    
    # verify correctness of concave envelope
    if problem.check_z:
        utilities.check_z(problem,node,fapxs,x)
    
    # formulate concave problem as lp and solve    
    lp = sigopt2pyglpk(slopes = slopes,offsets=offsets,l=l,u=u,**problem.constr)
    lp.simplex()

    # find the difference between the fapx and f for each coordinate i
    xstar = [c.primal for c in lp.cols[:n]]
    fi = numpy.array([problem.fs[i][0](xstar[i]) for i in range(n)])
    fapxi = numpy.array([c.primal for c in lp.cols[n:]])
    maxdiff_index = numpy.argmax( fapxi - fi )
    results = {'x': xstar, 'fapx': lp.obj.value, 'f': float(sum(fi)), 'maxdiff_index': maxdiff_index}
    if verbose: print 'fi',fi,'fapxi',fapxi,results
    return results