Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

ABAP logic permutation combination

Former Member
0 Likes
1,955

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,

1 ACCEPTED SOLUTION
Read only

hendrik_brandes
Contributor
0 Likes
1,203

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

9 REPLIES 9
Read only

kakshat
Product and Topic Expert
Product and Topic Expert
0 Likes
1,203

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?

Read only

Former Member
0 Likes
1,203

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.

Read only

kakshat
Product and Topic Expert
Product and Topic Expert
0 Likes
1,203

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.

Read only

Former Member
0 Likes
1,203

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

Read only

0 Likes
1,203

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.

Read only

0 Likes
1,203

hi narendra

please write the elaborated combinations (more in numbers than above) for the desired output ,

regards

vaibhav

Read only

hendrik_brandes
Contributor
0 Likes
1,204

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

Read only

0 Likes
1,203

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.

Read only

0 Likes
1,203

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