SAP ABAP 使用GENIOS求解线性规划问题的简单例子

打印 上一主题 下一主题

主题 887|帖子 887|积分 2661

主要内容来自Operations Research & ABAP ,结合我遇到的需求,做了一些修改。
需求:有BOX1和BOX2两种箱子,分别能包装不同数量的A物料和B物料,给出若干数量的A, B物料,怎样包装可以使箱子数最少?
线性规划有助于解决类似问题。
以下是一个示例程序,包含必要的注释,
  1. *&---------------------------------------------------------------------*
  2. *& Report YTEST_LP1
  3. *&---------------------------------------------------------------------*
  4. *&
  5. *&---------------------------------------------------------------------*
  6. REPORT ytest_lp1.
  7. *BOX1 箱子可以装2个A物料 1个B物料, BOX2箱子可以装1个A物料 3个B物料, 现有10A 11B, 如何包装箱子最少?
  8. *假设最终结果用到了X个 BOX1箱子, Y个BOX2箱子,问题可以写成如下形式
  9. * minimize X + Y
  10. * subject to : 2X + 1Y >= 10
  11. *              X + 3Y >= 11
  12. *              X >= 0
  13. *              Y >= 0
  14. DATA:
  15.   lr_model       TYPE REF TO cl_genios_model, "problem instance
  16.   lr_objective   TYPE REF TO cl_genios_objective, "objective function
  17.   lr_environment TYPE REF TO cl_genios_environment,
  18.   lr_x           TYPE REF TO cl_genios_variable, "variables
  19.   lr_y           TYPE REF TO cl_genios_variable,
  20.   lr_constraint  TYPE REF TO cl_genios_linearconstraint,
  21.   lr_solver      TYPE REF TO cl_genios_solver,
  22.   ls_result      TYPE genioss_solver_result,
  23.   ls_variable    TYPE genioss_variable,
  24.   lt_variables   TYPE geniost_variable,
  25.   lv_value       TYPE genios_float,
  26.   lv_name        TYPE string. "变量名
  27. lr_environment = cl_genios_environment=>get_environment( ).
  28. lr_model = lr_environment->create_model( 'PRIORIZATION' ).
  29. *定义离散变量,因为箱子是离散的定义连续变量,因为SIMP只支持连续变量
  30. lr_x = lr_model->create_variable( iv_name = 'X'
  31.   iv_type = if_genios_model_c=>gc_var_continuous ).
  32. lr_y = lr_model->create_variable( iv_name = 'Y'
  33.   iv_type = if_genios_model_c=>gc_var_continuous ).
  34. "下面设置目标函数,取满足条件的(X+Y)最小值,现实中也可能有不同的系数,比如X的价格是2,Y是1,那么在这里做相应调整<br>lr_objective = lr_model->create_objective( if_genios_model_c=>gc_obj_minimization ).<br>lr_objective->add_monom( io_variable = lr_x iv_coefficient = 1 ).
  35. lr_objective->add_monom( io_variable = lr_y iv_coefficient = 1 ).
  36. * 定义线性约束c1: 2X + 1Y >= 10
  37. lr_constraint = lr_model->create_linearconstraint( iv_name = 'c1'
  38.   iv_type = if_genios_model_c=>gc_con_greaterorequal iv_righthandside = 10 ).
  39. lr_constraint->add_monom( io_variable = lr_x iv_coefficient = 2 ).
  40. lr_constraint->add_monom( io_variable = lr_y iv_coefficient = 1 ).
  41. * 定义线性约束c2: 1X + 3Y >= 11
  42. lr_constraint = lr_model->create_linearconstraint( iv_name = 'c2'
  43.   iv_type = if_genios_model_c=>gc_con_greaterorequal iv_righthandside = 11 ).
  44. lr_constraint->add_monom( io_variable = lr_x iv_coefficient = 1 ).
  45. lr_constraint->add_monom( io_variable = lr_y iv_coefficient = 3 ).
  46. * 定义线性约束c3: X >= 0
  47. lr_constraint = lr_model->create_linearconstraint( iv_name = 'c3'
  48.   iv_type = if_genios_model_c=>gc_con_greaterorequal iv_righthandside = 0 ).
  49. lr_constraint->add_monom( io_variable = lr_x iv_coefficient = 1 ).
  50. * 定义线性约束c4: Y >= 0
  51. lr_constraint = lr_model->create_linearconstraint( iv_name = 'c4'
  52.   iv_type = if_genios_model_c=>gc_con_greaterorequal iv_righthandside = 0 ).
  53. lr_constraint->add_monom( io_variable = lr_y iv_coefficient = 1 ).
  54. lr_solver = lr_environment->create_solver( 'SIMP' ).
  55. lr_solver->load_model( lr_model ).
  56. ls_result = lr_solver->solve( ).
  57. * Get the result
  58. IF ls_result-solution_status = if_genios_solver_result_c=>gc_optimal OR
  59.    ls_result-solution_status = if_genios_solver_result_c=>gc_abortfeasible.
  60.   lt_variables = lr_model->get_variables( ).
  61.   LOOP AT lt_variables INTO ls_variable.
  62.     lv_name  = ls_variable-variable_ref->gv_name.
  63.     lv_value = ls_variable-variable_ref->get_primalvalue( ).
  64.     DATA: lv_int TYPE P LENGTH 10 DECIMALS 2.
  65.     lv_int = lv_value.
  66.     WRITE: /,lv_name,' = ',lv_int.
  67.   ENDLOOP.
  68. ENDIF.
  69. lr_environment->destroy_solver( 'SIMP' ).
  70. lr_environment->destroy_model( 'PRIORIZATION' ).
复制代码
 
运行程序,可以看到结果
X = 3.80
Y = 2.40

示例中的Solver SIMP 仅支持连续变量,对这个需求显然不合适,因为箱子不应该为小数。如果想使用离散变量,就需要换成其他Solver比如MILP,可惜我的系统无法使用MILP,所以不能测试。据说SAP APO或SAP SCM Optimizer可以满足更复杂的需求。
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

熊熊出没

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表