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
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