Advertisement
Dmitrey15

knitro python example

Jun 28th, 2013
310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.76 KB | None | 0 0
  1. #*******************************************************
  2. #* Copyright (c) 2006-2011 by Ziena Optimization LLC   *
  3. #* All Rights Reserved                                 *
  4. #*******************************************************
  5.  
  6. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7. #  This executable invokes KNITRO to solve a simple nonlinear
  8. #  optimization test problem.  The purpose is to illustrate how to
  9. #  invoke KNITRO using the Python language API.
  10. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  11.  
  12.  
  13. from knitro import *
  14. import math
  15.  
  16.  ## Solve test problem 1 (Synthesis of processing system) in
  17.  #  M. Duran & I.E. Grossmann, "An outer approximation algorithm for
  18.  #  a class of mixed integer nonlinear programs", Mathematical
  19.  #  Programming 36, pp. 307-339, 1986.  The problem also appears as
  20.  #  problem synthes1 in the MacMINLP test set.
  21.  #
  22.  #  min   5 x4 + 6 x5 + 8 x6 + 10 x1 - 7 x3 -18 math.log(x2 + 1)
  23.  #       - 19.2 math.log(x1 - x2 + 1) + 10
  24.  #  s.t.  0.8 math.log(x2 + 1) + 0.96 math.log(x1 - x2 + 1) - 0.8 x3 >= 0
  25.  #        math.log(x2 + 1) + 1.2 math.log(x1 - x2 + 1) - x3 - 2 x6 >= -2
  26.  #        x2 - x1 <= 0
  27.  #        x2 - 2 x4 <= 0
  28.  #        x1 - x2 - 2 x5 <= 0
  29.  #        x4 + x5 <= 1
  30.  #        0 <= x1 <= 2
  31.  #        0 <= x2 <= 2
  32.  #        0 <= x3 <= 1
  33.  #        x1, x2, x3 continuous
  34.  #        x4, x5, x6 binary
  35.  #        
  36.  #
  37.  #  The solution is (1.30098, 0, 1, 0, 1, 0).
  38.  ##
  39.  
  40. #----------------------------------------------------------------
  41. #   METHOD evaluateFC
  42. #----------------------------------------------------------------
  43.  ## Compute the function and constraint values at x.
  44.  #
  45.  #  For more information about the arguments, refer to the KNITRO
  46.  #  manual, especially the section on the Callable Library.
  47.  ##
  48. def evaluateFC (x, c):
  49.     tmp1 = x[0] - x[1] + 1.0
  50.     tmp2 = x[1] + 1.0
  51.     obj  = 5.0*x[3] + 6.0*x[4] + 8.0*x[5] + 10.0*x[0] - 7.0*x[2] \
  52.         - 18.0*math.log(tmp2) - 19.2*math.log(tmp1) + 10.0;
  53.     c[0] = 0.8*math.log(tmp2) + 0.96*math.log(tmp1) - 0.8*x[2]
  54.     c[1] = math.log(tmp2) + 1.2*math.log(tmp1) - x[2] - 2*x[5]
  55.     c[2] = x[1] - x[0]
  56.     c[3] = x[1] - 2*x[3]
  57.     c[4] = x[0] - x[1] - 2*x[4]
  58.     c[5] = x[3] + x[4]
  59.     return obj
  60.  
  61.  
  62. #----------------------------------------------------------------
  63. #   METHOD evaluateGA
  64. #----------------------------------------------------------------
  65.  ## Compute the function and constraint first deriviatives at x.
  66.  #
  67.  #  For more information about the arguments, refer to the KNITRO
  68.  #  manual, especially the section on the Callable Library.
  69.  ##
  70. def evaluateGA (x, objGrad, jac):
  71.     tmp1 = x[0] - x[1] + 1.0
  72.     tmp2 = x[1] + 1.0
  73.     objGrad[0] = 10.0 - (19.2 / tmp1)
  74.     objGrad[1] = (-18.0 / tmp2) + (19.2 / tmp1)
  75.     objGrad[2] = -7.0
  76.     objGrad[3] = 5.0
  77.     objGrad[4] = 6.0
  78.     objGrad[5] = 8.0
  79.  
  80.     #---- GRADIENT OF CONSTRAINT 0.
  81.     jac[0] = 0.96 / tmp1
  82.     jac[1] = (-0.96 / tmp1) + (0.8 / tmp2)
  83.     jac[2] = -0.8
  84.     #---- GRADIENT OF CONSTRAINT 1.
  85.     jac[3] = 1.2 / tmp1
  86.     jac[4] = (-1.2 / tmp1) + (1.0 / tmp2)
  87.     jac[5] = -1.0
  88.     jac[6] = -2.0
  89.     #---- GRADIENT OF CONSTRAINT 2.
  90.     jac[7] = -1.0
  91.     jac[8] = 1.0
  92.     #---- GRADIENT OF CONSTRAINT 3.
  93.     jac[9] = 1.0
  94.     jac[10] = -2.0    
  95.     #---- GRADIENT OF CONSTRAINT 4.
  96.     jac[11] = 1.0
  97.     jac[12] = -1.0    
  98.     jac[13] = -2.0
  99.     #---- GRADIENT OF CONSTRAINT 5.
  100.     jac[14] = 1.0
  101.     jac[15] = 1.0
  102.  
  103.  
  104. #----------------------------------------------------------------
  105. #   METHOD evaluateH
  106. #----------------------------------------------------------------
  107.  ## Compute the Hessian of the Lagrangian at x and lambda.
  108.  #
  109.  #  For more information about the arguments, refer to the KNITRO
  110.  #  manual, especially the section on the Callable Library.
  111.  ##
  112. def evaluateH (x, lambda_, sigma, hess):
  113.     tmp1 = x[0] - x[1] + 1.0
  114.     tmp2 = x[1] + 1.0
  115.     hess[0] = sigma*(19.2 / (tmp1*tmp1))   \
  116.         + lambda_[0]*(-0.96 / (tmp1*tmp1)) \
  117.         + lambda_[1]*(-1.2 / (tmp1*tmp1))
  118.     hess[1] = sigma*(-19.2 / (tmp1*tmp1))  \
  119.         + lambda_[0]*(0.96 / (tmp1*tmp1))  \
  120.         + lambda_[1]*(1.2 / (tmp1*tmp1))
  121.     hess[2] = sigma*((19.2 / (tmp1*tmp1)) + (18.0 / (tmp2*tmp2)))  \
  122.         + lambda_[0]*((-0.96 / (tmp1*tmp1)) - (0.8 / (tmp2*tmp2))) \
  123.         + lambda_[1]*((-1.2 / (tmp1*tmp1)) - (1.0 / (tmp2*tmp2)))
  124.  
  125.  
  126. #----------------------------------------------------------------
  127. #   MAIN METHOD FOR TESTING
  128. #----------------------------------------------------------------
  129.  
  130. #---- DEFINE THE OPTIMIZATION TEST PROBLEM.
  131. #---- FOR MORE INFORMATION ABOUT THE PROBLEM DEFINITION, REFER
  132. #---- TO THE KNITRO MANUAL, ESPECIALLY THE SECTION ON THE
  133. #---- CALLABLE LIBRARY.
  134. n = 6
  135. objGoal   = KTR_OBJGOAL_MINIMIZE
  136. objType   = KTR_OBJTYPE_GENERAL
  137. objFnType = KTR_FNTYPE_CONVEX
  138. xLoBnds = [ 0.0 ] * n
  139. xUpBnds = [ 2.0 ] * 2 + [ 1.0 ] * 4
  140. xType  = [ KTR_VARTYPE_CONTINUOUS ] * 3 + [ KTR_VARTYPE_BINARY ] * 3
  141. m = 6
  142. cType = [ KTR_CONTYPE_GENERAL ] * 2 + [ KTR_CONTYPE_LINEAR ] * 4
  143. cLoBnds = [ 0.0, -2.0 ] + [ -KTR_INFBOUND ] * 4
  144. cUpBnds = [ KTR_INFBOUND ] * 2 + [ 0.0 ] * 3 + [ 1.0 ]
  145. cFnType = [ KTR_FNTYPE_CONVEX ] * 6
  146. jacIndexCons = [ 0 ] * 3 + [ 1 ] * 4 + [ 2 ] * 2 + [ 3 ] * 2 +[ 4 ] * 3 + [ 5 ] * 2
  147. jacIndexVars    = [ 0, 1, 2, 0, 1, 2, 5, 0, 1, 1, 3, 0, 1, 4, 3, 4 ]
  148. hessRows = [ 0, 0, 1 ]
  149. hessCols = [ 0, 1, 1 ]
  150.  
  151.  
  152. #---- SETUP AND RUN KNITRO TO SOLVE THE PROBLEM.
  153.  
  154. #---- CREATE A NEW KNITRO SOLVER INSTANCE.
  155. kc = KTR_new()
  156. if kc == None:
  157.     raise RuntimeError ("Failed to find a Ziena license.")
  158.  
  159. #---- DEMONSTRATE HOW TO SET KNITRO PARAMETERS.
  160. if KTR_set_int_param_by_name(kc, "mip_method", KTR_MIP_METHOD_BB):
  161.     raise RuntimeError ("Error setting parameter 'mip_method'")
  162. if KTR_set_int_param_by_name(kc, "algorithm", KTR_ALG_ACT_CG):
  163.     raise RuntimeError ("Error setting parameter 'algorithm'")
  164. if KTR_set_int_param_by_name(kc, "outmode", KTR_OUTMODE_SCREEN):
  165.     raise RuntimeError ("Error setting parameter 'outmode'")
  166. if KTR_set_int_param(kc, KTR_PARAM_OUTLEV, KTR_OUTLEV_ALL):
  167.     raise RuntimeError ("Error setting parameter KTR_PARAM_OUTLEV")
  168. if KTR_set_int_param(kc, KTR_PARAM_MIP_OUTINTERVAL, 1):
  169.     raise RuntimeError ("Error setting parameter KTR_PARAM_MIP_OUTINTERVAL")
  170. if KTR_set_int_param(kc, KTR_PARAM_MIP_MAXNODES, 10000):
  171.     raise RuntimeError ("Error setting parameter KTR_PARAM_MIP_MAXNODES")
  172.  
  173. #---- SPECIFY THAT THE USER IS ABLE TO PROVIDE EVALUATIONS
  174. #---- OF THE HESSIAN MATRIX WITHOUT THE OBJECTIVE COMPONENT.
  175. #---- TURNED OFF BY DEFAULT BUT SHOULD BE ENABLED IF POSSIBLE.
  176. if KTR_set_int_param (kc, KTR_PARAM_HESSIAN_NO_F, KTR_HESSIAN_NO_F_ALLOW):
  177.     raise RuntimeError ("Error setting parameter KTR_PARAM_HESSIAN_NO_F")
  178.  
  179. #---- INITIALIZE KNITRO WITH THE PROBLEM DEFINITION.
  180. ret = KTR_mip_init_problem (kc, n, objGoal, objType, objFnType,
  181.                                     xType, xLoBnds, xUpBnds,
  182.                                     cType, cFnType, cLoBnds, cUpBnds,
  183.                                     jacIndexVars, jacIndexCons,
  184.                                     hessRows, hessCols, None, None)
  185. if ret:
  186.     raise RuntimeError ("Error initializing the problem, KNITRO status = %d" % ret)
  187.  
  188. #------------------------------------------------------------------
  189. #     FUNCTION callbackEvalFC
  190. #------------------------------------------------------------------
  191.  ## The signature of this function matches KTR_callback in knitro.h.
  192.  #  Only "obj" and "c" are modified.
  193.  ##
  194. def callbackEvalFC (evalRequestCode, n, m, nnzJ, nnzH, x, lambda_, obj, c, objGrad, jac, hessian, hessVector, userParams):
  195.     if evalRequestCode == KTR_RC_EVALFC:
  196.         obj[0] = evaluateFC(x, c)
  197.         return 0
  198.     else:
  199.         return KTR_RC_CALLBACK_ERR
  200.  
  201. #------------------------------------------------------------------
  202. #     FUNCTION callbackEvalGA
  203. #------------------------------------------------------------------
  204.  ## The signature of this function matches KTR_callback in knitro.h.
  205.  #  Only "objGrad" and "jac" are modified.
  206.  ##
  207. def callbackEvalGA (evalRequestCode, n, m, nnzJ, nnzH, x, lambda_, obj, c, objGrad, jac, hessian, hessVector, userParams):
  208.     if evalRequestCode == KTR_RC_EVALGA:
  209.         evaluateGA(x, objGrad, jac)
  210.         return 0
  211.     else:
  212.         return KTR_RC_CALLBACK_ERR
  213.  
  214. #------------------------------------------------------------------
  215. #     FUNCTION callbackEvalH
  216. #------------------------------------------------------------------
  217.  ## The signature of this function matches KTR_callback in knitro.h.
  218.  #  Only "hessian" or "hessVector" is modified.
  219.  ##
  220. def callbackEvalH (evalRequestCode, n, m, nnzJ, nnzH, x, lambda_, obj, c, objGrad, jac, hessian, hessVector, userParams):
  221.     if evalRequestCode == KTR_RC_EVALH:
  222.         evaluateH(x, lambda_, 1.0, hessian)
  223.         return 0
  224.     elif evalRequestCode == KTR_RC_EVALH_NO_F:
  225.         evaluateH(x, lambda_, 0.0, hessian)
  226.         return 0
  227.     else:
  228.         return KTR_RC_CALLBACK_ERR
  229.  
  230. #---- REGISTER THE CALLBACK FUNCTIONS THAT PERFORM PROBLEM EVALUATION.
  231. #---- THE HESSIAN CALLBACK ONLY NEEDS TO BE REGISTERED FOR SPECIFIC
  232. #---- HESSIAN OPTIONS (E.G., IT IS NOT REGISTERED IF THE OPTION FOR
  233. #---- BFGS HESSIAN APPROXIMATIONS IS SELECTED).
  234. if KTR_set_func_callback(kc, callbackEvalFC):
  235.     raise RuntimeError ("Error registering function callback.")
  236. if KTR_set_grad_callback(kc, callbackEvalGA):
  237.     raise RuntimeError ("Error registering gradient callback.")
  238. if KTR_set_hess_callback(kc, callbackEvalH):
  239.     raise RuntimeError ("Error registering hessian callback.")
  240.  
  241. #------------------------------------------------------------------
  242. #     FUNCTION callbackProcessNode
  243. #------------------------------------------------------------------
  244.  ## The signature of this function matches KTR_callback in knitro.h.
  245.  ##
  246. def callbackProcessNode (evalRequestCode, n, m, nnzJ, nnzH, x, lambda_, obj, c, objGrad, jac, hessian, hessVector, userParams):
  247.     #---- THE KNITRO CONTEXT POINTER WAS PASSED IN THROUGH "userParams".
  248.     kc = userParams
  249.    
  250.     #---- PRINT INFO ABOUT THE STATUS OF THE MIP SOLUTION.
  251.     print "callbackProcessNode: "
  252.     print "    Node number    = %d" % KTR_get_mip_num_nodes (kc)
  253.     print "    Node objective = %e" % obj[0]
  254.     print "    Current relaxation bound = %e" % KTR_get_mip_relaxation_bnd (kc)
  255.     incumbentBound = KTR_get_mip_incumbent_obj (kc)
  256.     if abs(incumbentBound) >= KTR_INFBOUND:
  257.         print "    No integer feasible point found yet."
  258.     else:
  259.         print "    Current incumbent bound  = %e" % incumbentBound
  260.         print "    Absolute integrality gap = %e" % KTR_get_mip_abs_gap (kc)
  261.         print "    Relative integrality gap = %e" % KTR_get_mip_rel_gap (kc)
  262.  
  263.     #---- USER DEFINED TERMINATION EXAMPLE.
  264.     #---- UNCOMMENT BELOW TO FORCE TERMINATION AFTER 3 NODES.
  265.     #if KTR_get_mip_num_nodes (kc) == 3:
  266.     #    return KTR_RC_USER_TERMINATION
  267.    
  268.     return 0
  269.  
  270. #---- REGISTER THE CALLBACK FUNCTION THAT PERFORMS SOME TASK AFTER
  271. #---- EACH COMPLETION OF EACH NODE IN BRANCH-AND-BOUND TREE.
  272. if KTR_set_mip_node_callback (kc, callbackProcessNode):
  273.     raise RuntimeError ("Error registering node process callback.")
  274.  
  275. #---- SOLVE THE PROBLEM.
  276. #----
  277. #---- RETURN STATUS CODES ARE DEFINED IN "knitro.h" AND DESCRIBED
  278. #---- IN THE KNITRO MANUAL.
  279. x       = [0] * n
  280. lambda_ = [0] * (m + n)
  281. obj     = [0]
  282. nStatus = KTR_mip_solve (kc, x, lambda_, 0, obj,
  283.                          None, None, None, None, None, kc)
  284.  
  285. print
  286. print
  287. if nStatus != 0:
  288.     raise RuntimeError ("KNITRO failed to solve the problem, final status = %d" % nStatus)
  289. else:
  290.     #---- AN EXAMPLE OF OBTAINING SOLUTION INFORMATION.
  291.     print "KNITRO successful, integrality gap   = %e" % KTR_get_mip_abs_gap (kc)
  292.  
  293. #---- BE CERTAIN THE NATIVE OBJECT INSTANCE IS DESTROYED.
  294. KTR_free(kc)
  295.  
  296. #+++++++++++++++++++ End of source file +++++++++++++++++++++++++++++
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement