# Algorithm to find the best combination of values

We had a scenario for batch split where we have to select the Batch numbers based on quantity.

For e.g. we have

 batch quantity batch1 10 batch2 15 batch3 9

If the tolerance limit is 20 then the best combination is batch 1 and batch 3

If the tolerance limit is 15 then the best combination is batch 2

If the tolerance limit is 40 then the best combination is batch1, batch2 and batch 3

The following is the Function module which helps to identify the best combination to achieve the tolerance value.

The import parameters contains the counter and quantity value with tolerance value.

I_LFIMG = tolerance value

IT_CLABS contains counter with quantity value.

For e.g.

 batch counter quantity batch1 1 10 batch2 2 15 batch3 3 9

The import parameter table will have

 counter quantity 1 10 2 15 3 9

The Algorithm to achieve the best combination in written inside the Function module which in turn calculate the best combination

The output will be

Counter

1
2

Based upon the counter we can find the respected batch.

The logic is implemented using counter to make reuse of this algorithm for all scenarios not only specific to batch.

Function module logic:

FUNCTION ysd_fm_batch_split.
*”———————————————————————-
*”*”Local Interface:
*” IMPORTING
*” REFERENCE(I_LFIMG) TYPE KWMENG
*” REFERENCE(IT_CLABS) TYPE YSD_TTY_CLABS
*” CHANGING
*” REFERENCE(CT_FINAL) TYPE YSD_TTY_COUNT
*”———————————————————————-

DATA: ls_clabs TYPE ysd_s_batch_split,
lv_str TYPE char5.
DATA : lo_new_type TYPE REF TO cl_abap_structdescr,
lo_new_tab TYPE REF TO cl_abap_tabledescr,
lt_comp TYPE cl_abap_structdescr=>component_table,

lo_data TYPE REF TO data,
lo_data_s TYPE REF TO data,
la_comp LIKE LINE OF lt_comp.

FIELD-SYMBOLS: <lfs_tab> TYPE STANDARD TABLE,
<lfs_line1> TYPE any,
<lfs_field> TYPE i,
<lfs_field1> TYPE i,
<lfs_fieldn> TYPE i.

TYPES : BEGIN OF lty_field,
index TYPE i,
name TYPE char30,
value TYPE i,
END OF lty_field.

DATA:lv_ln TYPE i,
lv_weight TYPE i.

* variable for revert back logic******
DATA :lv_ln_row TYPE i,
lv_ln_col TYPE i,
lv_temp_idx TYPE i,
lv_temp1_idx TYPE i,
lv_temp2_idx TYPE i,
lv_temp_val TYPE i.

FIELD-SYMBOLS : <lfs_1> TYPE any,
<lfs_2> TYPE any.

DATA:ls_final TYPE ysd_s_count,
lv_total TYPE i.

DATA : lv_row_index TYPE i,
lv_col_index TYPE i,
lv_call_row_index TYPE i,
lv_call_col_index TYPE i,
lv_call_row_index1 TYPE i,
lv_call_col_index1 TYPE i,
lv_call_row_index2 TYPE i,
lv_call_col_index2 TYPE i,
lv_temp1 TYPE i,
lv_temp2 TYPE i,
lv_temp TYPE i,
lv_temp3 TYPE i,
lt_field TYPE STANDARD TABLE OF lty_field,
ls_field TYPE lty_field.
*sort gtab by qty ASCENDING.
lv_weight = i_lfimg.
lv_str = ‘0’.
CONCATENATE ‘wt_’ lv_str INTO la_comp-name.
CONDENSE la_comp-name .“no-gaps.
la_comp-type = cl_abap_elemdescr=>get_i( ).
APPEND la_comp TO lt_comp.
ls_field-index = 1.
ls_field-value = 0.
ls_field-name = la_comp-name.
APPEND ls_field TO lt_field.
CLEAR ls_field.
CLEAR: la_comp.
** Dynamic Column Generation
DO lv_weight TIMES.

CLEAR lv_str.
lv_str = sy-index.
CONDENSE lv_str.
CONCATENATE ‘wt_’ lv_str INTO la_comp-name.
CONDENSE la_comp-name.” no-gaps.
ls_field-index = 1 + sy-index.
ls_field-value = sy-index.
ls_field-name = la_comp-name.
APPEND ls_field TO lt_field.
la_comp-type = cl_abap_elemdescr=>get_i( ).
APPEND la_comp TO lt_comp.
CLEAR: la_comp.
ENDDO.
lo_new_type = cl_abap_structdescr=>create( lt_comp ).
* 4. New Table type
lo_new_tab = cl_abap_tabledescr=>create(
p_line_type = lo_new_type
p_table_kind = cl_abap_tabledescr=>tablekind_std
p_unique = abap_false ).
CREATE DATA lo_data TYPE HANDLE lo_new_tab.
CREATE DATA lo_data_s TYPE HANDLE lo_new_type.
ASSIGN lo_data->* TO <lfs_tab>. ““main table
ASSIGN lo_data_s->* TO <lfs_line1>.
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE <lfs_line1> TO <lfs_field>.
IF sy-subrc IS INITIAL.
<lfs_field> = 0.
ELSE.
EXIT.
ENDIF.
ENDDO.
** creating first row in dynamic table with zeros
INSERT <lfs_line1> INTO TABLE <lfs_tab>.
UNASSIGN : <lfs_field>, <lfs_line1>.

CLEAR : lv_row_index,
lv_col_index,
lv_call_row_index,
lv_call_col_index.
**creating record in dynamic table for
* possible combination of item
lv_ln = lines( it_clabs
).
DO lv_ln TIMES.
lv_row_index = sy-index + 1. ““{i}
READ TABLE it_clabs INTO ls_clabs INDEX sy-index.
LOOP AT lt_field INTO ls_field.
lv_col_index = sy-tabix.
IF ls_field-value < ls_clabs-quantity.
lv_call_row_index = lv_row_index – 1.
lv_call_col_index = lv_col_index.
READ TABLE <lfs_tab> ASSIGNING <lfs_line1> INDEX lv_call_row_index.
ASSIGN COMPONENT ls_field-name OF STRUCTURE <lfs_line1> TO <lfs_field>.
lv_temp = <lfs_field> .
ELSE.
lv_call_row_index1 = lv_row_index – 1.
lv_call_col_index1 = lv_col_index.
READ TABLE <lfs_tab> ASSIGNING <lfs_line1> INDEX lv_call_row_index1.
ASSIGN COMPONENT ls_field-name OF STRUCTURE <lfs_line1> TO <lfs_field>.
lv_temp1 = <lfs_field> .

lv_call_row_index2 = lv_row_index – 1.
lv_temp3 = ls_field-value – ls_clabs-quantity.
READ TABLE lt_field INTO ls_field WITH KEY value = lv_temp3.
IF sy-subrc IS INITIAL.
lv_call_col_index2 = ls_field-index.
ENDIF.
READ TABLE <lfs_tab> ASSIGNING <lfs_line1> INDEX lv_call_row_index2.
ASSIGN COMPONENT lv_call_col_index2 OF STRUCTURE <lfs_line1> TO <lfs_field1>.
lv_temp2 = <lfs_field1> + ls_clabs-quantity.
IF lv_temp2 > lv_temp1.
lv_temp = lv_temp2.
ELSE.
lv_temp = lv_temp1.
ENDIF.
ENDIF.
READ TABLE <lfs_tab> ASSIGNING <lfs_line1> INDEX lv_row_index.
IF sy-subrc IS INITIAL.
ASSIGN COMPONENT lv_col_index OF STRUCTURE <lfs_line1> TO <lfs_fieldn>.
<lfs_fieldn> = lv_temp.
ELSE.
ASSIGN COMPONENT lv_col_index OF STRUCTURE <lfs_line1> TO <lfs_fieldn>.
<lfs_fieldn> = lv_temp.
INSERT <lfs_line1> INTO TABLE <lfs_tab>.
ENDIF.
CLEAR ls_field.
ENDLOOP.
ENDDO.
*************traceback exact items from dynamic table********************
DESCRIBE TABLE <lfs_tab> LINES lv_ln_row.
DESCRIBE TABLE lt_field LINES lv_ln_col.
lv_row_index = lv_ln_row.
DO lv_ln_row TIMES.
lv_temp2_idx = lv_row_index.
DO lv_row_index TIMES.
lv_temp_idx = lv_temp2_idx – 1.
READ TABLE <lfs_tab> ASSIGNING <lfs_line1> INDEX lv_temp2_idx.

ASSIGN COMPONENT lv_ln_col OF STRUCTURE <lfs_line1> TO <lfs_1>.
READ TABLE <lfs_tab> ASSIGNING <lfs_line1> INDEX lv_temp_idx.
ASSIGN COMPONENT lv_ln_col OF STRUCTURE <lfs_line1> TO <lfs_2>.

IF <lfs_1> NE <lfs_2>.
lv_temp1_idx = lv_temp2_idx.
EXIT.
ENDIF.
lv_temp2_idx = lv_temp2_idx – 1.
ENDDO.
lv_row_index = lv_temp1_idx.
lv_temp1_idx = lv_temp1_idx – 1.

READ TABLE it_clabs INTO ls_clabs INDEX lv_temp1_idx.
IF sy-subrc IS INITIAL.
ls_final-item = ls_clabs-count.
APPEND ls_final TO ct_final.
READ TABLE lt_field INTO ls_field WITH KEY index = lv_ln_col.
IF sy-subrc IS INITIAL.
lv_temp_val = ls_field-value – ls_clabs-quantity.
ENDIF.
READ TABLE lt_field INTO ls_field WITH KEY value = lv_temp_val.
IF sy-subrc = 0.
lv_ln_col = ls_field-index.
ENDIF.
ENDIF.
lv_row_index = lv_row_index – 1.
IF lv_row_index = 0.
EXIT.
ENDIF.
IF lv_ln_col = 1.
EXIT.
ENDIF.
CLEAR lv_temp1_idx.
ENDDO.

LOOP AT ct_final INTO ls_final.
READ TABLE it_clabs INTO ls_clabs WITH KEY count = ls_final-item.
IF sy-subrc IS INITIAL.
lv_total = lv_total + ls_clabs-quantity.
ENDIF.
CLEAR ls_final.
ENDLOOP.

ENDFUNCTION.

Test scenario

Tolerance is 20.

Import parameter is

Output is 1 and 3 the value of the combination is 19