主要内容来自Operations Research & ABAP ,结合我遇到的需求,做了一些修改。
需求:有BOX1和BOX2两种箱子,分别能包装不同数量的A物料和B物料,给出若干数量的A, B物料,怎样包装可以使箱子数最少?
线性规划有助于解决类似问题。
以下是一个示例程序,包含必要的注释,- *&---------------------------------------------------------------------*
- *& Report YTEST_LP1
- *&---------------------------------------------------------------------*
- *&
- *&---------------------------------------------------------------------*
- REPORT ytest_lp1.
- *BOX1 箱子可以装2个A物料 1个B物料, BOX2箱子可以装1个A物料 3个B物料, 现有10A 11B, 如何包装箱子最少?
- *假设最终结果用到了X个 BOX1箱子, Y个BOX2箱子,问题可以写成如下形式
- * minimize X + Y
- * subject to : 2X + 1Y >= 10
- * X + 3Y >= 11
- * X >= 0
- * Y >= 0
- DATA:
- lr_model TYPE REF TO cl_genios_model, "problem instance
- lr_objective TYPE REF TO cl_genios_objective, "objective function
- lr_environment TYPE REF TO cl_genios_environment,
- lr_x TYPE REF TO cl_genios_variable, "variables
- lr_y TYPE REF TO cl_genios_variable,
- lr_constraint TYPE REF TO cl_genios_linearconstraint,
- lr_solver TYPE REF TO cl_genios_solver,
- ls_result TYPE genioss_solver_result,
- ls_variable TYPE genioss_variable,
- lt_variables TYPE geniost_variable,
- lv_value TYPE genios_float,
- lv_name TYPE string. "变量名
- lr_environment = cl_genios_environment=>get_environment( ).
- lr_model = lr_environment->create_model( 'PRIORIZATION' ).
- *定义离散变量,因为箱子是离散的定义连续变量,因为SIMP只支持连续变量
- lr_x = lr_model->create_variable( iv_name = 'X'
- iv_type = if_genios_model_c=>gc_var_continuous ).
- lr_y = lr_model->create_variable( iv_name = 'Y'
- iv_type = if_genios_model_c=>gc_var_continuous ).
- "下面设置目标函数,取满足条件的(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 ).
- lr_objective->add_monom( io_variable = lr_y iv_coefficient = 1 ).
- * 定义线性约束c1: 2X + 1Y >= 10
- lr_constraint = lr_model->create_linearconstraint( iv_name = 'c1'
- iv_type = if_genios_model_c=>gc_con_greaterorequal iv_righthandside = 10 ).
- lr_constraint->add_monom( io_variable = lr_x iv_coefficient = 2 ).
- lr_constraint->add_monom( io_variable = lr_y iv_coefficient = 1 ).
- * 定义线性约束c2: 1X + 3Y >= 11
- lr_constraint = lr_model->create_linearconstraint( iv_name = 'c2'
- iv_type = if_genios_model_c=>gc_con_greaterorequal iv_righthandside = 11 ).
- lr_constraint->add_monom( io_variable = lr_x iv_coefficient = 1 ).
- lr_constraint->add_monom( io_variable = lr_y iv_coefficient = 3 ).
- * 定义线性约束c3: X >= 0
- lr_constraint = lr_model->create_linearconstraint( iv_name = 'c3'
- iv_type = if_genios_model_c=>gc_con_greaterorequal iv_righthandside = 0 ).
- lr_constraint->add_monom( io_variable = lr_x iv_coefficient = 1 ).
- * 定义线性约束c4: Y >= 0
- lr_constraint = lr_model->create_linearconstraint( iv_name = 'c4'
- iv_type = if_genios_model_c=>gc_con_greaterorequal iv_righthandside = 0 ).
- lr_constraint->add_monom( io_variable = lr_y iv_coefficient = 1 ).
- lr_solver = lr_environment->create_solver( 'SIMP' ).
- lr_solver->load_model( lr_model ).
- ls_result = lr_solver->solve( ).
- * Get the result
- IF ls_result-solution_status = if_genios_solver_result_c=>gc_optimal OR
- ls_result-solution_status = if_genios_solver_result_c=>gc_abortfeasible.
- lt_variables = lr_model->get_variables( ).
- LOOP AT lt_variables INTO ls_variable.
- lv_name = ls_variable-variable_ref->gv_name.
- lv_value = ls_variable-variable_ref->get_primalvalue( ).
- DATA: lv_int TYPE P LENGTH 10 DECIMALS 2.
- lv_int = lv_value.
- WRITE: /,lv_name,' = ',lv_int.
- ENDLOOP.
- ENDIF.
- lr_environment->destroy_solver( 'SIMP' ).
- lr_environment->destroy_model( 'PRIORIZATION' ).
复制代码
运行程序,可以看到结果
X = 3.80
Y = 2.40
示例中的Solver SIMP 仅支持连续变量,对这个需求显然不合适,因为箱子不应该为小数。如果想使用离散变量,就需要换成其他Solver比如MILP,可惜我的系统无法使用MILP,所以不能测试。据说SAP APO或SAP SCM Optimizer可以满足更复杂的需求。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |