2013 Jan 22 11:19 AM
Hi Experts,
I have below two table's values.
1st Table values.
51
82
143
2nd Tables value is
1007
I want to consume the full value 1007 based on multiple combinations of 1st table's values.
I want the set of combinations results as below:
Combination 1. 51 x 19 = 969(consume), 38 (Balance)
Combination 2. 51 x 18 + 82 x 1 = 1000(Consume), 7 (Balance)
Combination 3. 51 x 16 + 81 x 2 = 980(Consume), 27 (Balance)
Combination 4. 51 x 16 + 143 x 1 = 959(Consume), 48 (Balance)
Combination 5. 51 x 15 + 82 x 1 + 143 x 1 = 990(Consume), 17 (Balance)
and so on.....
Is there any logic to get the above results.
thanks,
2013 Jan 22 12:12 PM
Hello Narendra,
your problem seems to be some kind of optimization problem. Perhaps this blog will help you, it discuss the usage of a standard framework for optimization problems.
Look here: http://scn.sap.com/community/abap/blog/2011/10/04/operations-research-abap
Kind regards
Hendrik
2013 Jan 22 11:41 AM
Interesting! Curious to know what are you actually trying to do?
I was just thinking about the logic to achieve this and am wondering why didn't you consider the combination 51 * 17 + 82 * 1. Is that not a valid combination? If not, why?
2013 Jan 22 11:49 AM
Dear Akshat,
Yes you are right it is a valid combination.
I am developing a software to consume the width of an object using multiple width parts. and reduce the width balance.
how can i develop the logic I am trying but not achieved yet.
Plz. help.
2013 Jan 22 11:59 AM
Hi Narendra,
I had a look at the code suggested by Vaibhav and it looks good. The only thing I think which is missing is a check whether the calculated value is less than the value in table2. I think you should try that logic.
2013 Jan 22 11:43 AM
Hi Narendra
try this :
data : d type i,
b type i,
result type i.
a = 1.
n = 0.
loop at table1.
b = sy-tabix.
b = b + 1.
read table table1 into wa_table1 index b.
read table table2 index a.
d = table2-field / table1-field.
while d ne 0.
result = table1-field * d + wa_table1-field * n.
append result *append it the desired table
d = d - 1.
n = n + 1.
wa_table1-field = wa_table1-field - 1.
endwhile.
a = a + 1.
endloop.
regards
vaibhav
2013 Jan 22 12:21 PM
Hi,
This logic work for any two combinations from table 1. but in the combinations it may be 3 or 4 or five or more.
2013 Jan 23 4:02 AM
hi narendra
please write the elaborated combinations (more in numbers than above) for the desired output ,
regards
vaibhav
2013 Jan 22 12:12 PM
Hello Narendra,
your problem seems to be some kind of optimization problem. Perhaps this blog will help you, it discuss the usage of a standard framework for optimization problems.
Look here: http://scn.sap.com/community/abap/blog/2011/10/04/operations-research-abap
Kind regards
Hendrik
2013 Jan 22 1:26 PM
Hi Hendrik,
Thanks for reply, but I am not able to understand this programming.
I want logic to get the result as I desire.
Plz. help.
2013 Jan 23 5:14 AM
Hi Narenda,
I couldn't resist a little recursive fun so I came up with a little sample program that should give you what you are looking for. It writes a list of possible combinations that are less than the total. For the purposes of keeping it simple I used the exact data that you had with 51, 82 & 143 with a sample size of 1007. Here is the code:
DATA: BEGIN OF ty_factors OCCURS 0,
qty TYPE i,
num TYPE i,
END OF ty_factors.
TYPES: BEGIN OF ty_fact,
qty TYPE i,
num TYPE i,
END OF ty_fact.
TYPES: BEGIN OF ty_quants,
qty TYPE i,
END OF ty_quants.
DATA: gt_tmp TYPE TABLE OF ty_fact,
wa_tmp TYPE ty_fact,
gt_quants TYPE TABLE OF ty_quants,
gv_quant TYPE ty_quants,
gt_left TYPE TABLE OF ty_quants,
gv_tabix TYPE sy-tabix.
CONSTANTS: gc_total TYPE i VALUE '1007'.
gv_quant-qty = 51.
APPEND gv_quant TO gt_quants.
gv_quant-qty = 82.
APPEND gv_quant TO gt_quants.
gv_quant-qty = 143.
APPEND gv_quant TO gt_quants.
LOOP AT gt_quants INTO gv_quant.
* Ensure quantity is not greater than total
IF gv_quant-qty < gc_total.
REFRESH gt_tmp.
* For anything greater than sy-tabix 1 then remove
* previous entries because those combinations have already
* been checked
IF sy-tabix > 1.
gv_tabix = sy-tabix - 1.
gt_left[] = gt_quants[].
DELETE gt_left FROM 1 TO gv_tabix.
ELSE.
gt_left[] = gt_quants[].
ENDIF.
* Intialize table and make recursive call for addition
CLEAR wa_tmp.
wa_tmp-qty = gv_quant-qty.
wa_tmp-num = 1.
APPEND wa_tmp TO gt_tmp.
PERFORM remainder TABLES gt_left gt_tmp USING gv_quant.
ENDIF.
ENDLOOP.
*&---------------------------------------------------------------------*
*& Form REMAINDER
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_GT_LEFT text
* -->P_GT_TMP text
* -->P_GV_QUANT text
* -->P_GV_QUANT text
* <--P_GV_SUBRC text
*----------------------------------------------------------------------*
FORM remainder TABLES p_quants
p_tmp STRUCTURE ty_factors
USING p_tot TYPE ty_quants.
DATA: lt_ntmp TYPE TABLE OF ty_fact,
lt_ntmp2 TYPE TABLE OF ty_fact,
wa_quant TYPE ty_quants,
wa_quant2 TYPE ty_quants,
lv_newtot TYPE ty_quants,
lv_newtot2 TYPE ty_quants,
lv_squ TYPE string,
lv_sfa TYPE string,
lv_stot TYPE string,
lv_str TYPE string,
lt_left TYPE TABLE OF ty_quants,
lv_mod TYPE i.
FIELD-SYMBOLS: <wa> TYPE ty_fact,
<wa2> TYPE ty_fact.
* Initialize local table
lt_ntmp[] = p_tmp[].
* Continue with index 1 until limit is reached
READ TABLE p_quants INTO wa_quant INDEX 1.
IF sy-subrc = 0.
READ TABLE lt_ntmp ASSIGNING <wa> WITH KEY qty = wa_quant-qty.
IF sy-subrc = 0.
lv_newtot-qty = p_tot-qty + wa_quant-qty.
<wa>-num = <wa>-num + 1.
* Check value of new total
IF lv_newtot-qty > gc_total.
* Because some paths may already have been traversed then ensure
* output only when remainder is smaller than any possible quantity
* values
lv_mod = gc_total - p_tot-qty.
LOOP AT gt_quants TRANSPORTING NO FIELDS WHERE qty < lv_mod.
ENDLOOP.
IF sy-subrc <> 0.
* Output unique combination
CLEAR lv_str.
LOOP AT p_tmp ASSIGNING <wa2>.
lv_squ = <wa2>-qty.
lv_sfa = <wa2>-num.
lv_stot = p_tot-qty.
IF sy-tabix > 1.
CONCATENATE lv_str '+' lv_squ '*' lv_sfa INTO lv_str SEPARATED BY space.
ELSE.
CONCATENATE lv_squ '*' lv_sfa INTO lv_str SEPARATED BY space.
ENDIF.
ENDLOOP.
CONCATENATE lv_str '=' lv_stot INTO lv_str SEPARATED BY space.
WRITE: / lv_str.
ENDIF.
EXIT.
ELSE.
* Recursive call to next entry to find limit
PERFORM remainder TABLES p_quants lt_ntmp USING lv_newtot.
* Limit already reached so branch to remaining quantity values
lt_left[] = p_quants[].
lt_ntmp2[] = lt_ntmp[].
DELETE lt_left INDEX 1.
LOOP AT lt_left INTO wa_quant2.
lv_mod = gc_total - lv_newtot-qty.
IF lv_mod > wa_quant2-qty.
lv_newtot2-qty = lv_newtot-qty + wa_quant2-qty.
CLEAR wa_tmp.
wa_tmp-qty = wa_quant2-qty.
wa_tmp-num = 1.
APPEND wa_tmp TO lt_ntmp2.
PERFORM remainder TABLES lt_left lt_ntmp2 USING lv_newtot2.
ENDIF.
* Always remove current quantity when exhausted - on next loop pass new quantity
* will be tallied for current stack
DELETE lt_left INDEX 1.
ENDLOOP.
ENDIF.
ENDIF.
ENDIF.
ENDFORM. " REMAINDER
P.S. - One thing I forgot to mention is that the internal table gt_quants should be sorted in ascending order before any of the computational logic is performed to ensure that it works as expected.
Regards,
Ryan Crosby