回答

收藏

将数字与数字子集的总和进行比较

技术问答 技术问答 246 人阅读 | 0 人回复 | 2023-09-14

我正在寻找您的专家的指导,以找出一种将数字与数字子集的总和进行比较的方法
% E5 N! P' h( ]1 f8 ~4 Y$ \/ WDECLARE
9 G) L7 ?! }0 R* Q    L_NUM_TO_COMPARE NUMBER := 0;- @3 R! P0 ]/ f; G! t) E7 v
    L_NUM_SUBSET     NUMBER := 0;- P" K, Z- Z: V5 W
BEGIN( x$ V; R) x! C: w' {* u
    FOR MAIN_REC IN (
: V1 L) K( e) A6 S. O  |! a, L           SELECT 1 ID, 25150  ASSIGN_AMT FROM DUAL
) a7 P. |9 T- v# _& |5 S        UNION ALL( r4 |  W$ U1 o, l
           SELECT 2 ID, 19800  ASSIGN_AMT FROM DUAL1 |( k. F+ ~  @! S( M# |/ Z) l
        UNION ALL8 h$ ?, u2 U) x" q% x1 k
           SELECT 3 ID, 27511  ASSIGN_AMT FROM DUAL
1 ^; n; g' F3 l/ _    ) LOOP1 @5 D: k' D, M0 q2 `: G: t, V/ [
        L_NUM_TO_COMPARE := MAIN_REC.ASSIGN_AMT;
: e8 Z. B+ N- u( I% R% E2 `        DBMS_OUTPUT.PUT_LINE( L_NUM_TO_COMPARE);
  C4 e: b+ [! J9 ?# u% U        FOR C IN ($ v2 @% g/ }" y& ~
                      SELECT 1  ID, 7120  WORK_AMT FROM DUAL * V! l3 |' t( a1 [+ e+ A
            UNION ALL SELECT 2  ID, 8150  WORK_AMT FROM DUAL+ i: [$ U; D9 E" L7 M
            UNION ALL SELECT 3  ID, 8255  WORK_AMT FROM DUAL
: d  @" \, l5 k) W            UNION ALL SELECT 4  ID, 9051  WORK_AMT FROM DUAL
6 @% P/ v  }& Q0 T4 D! R8 U* l) c. O; ~            UNION ALL SELECT 5  ID, 1220  WORK_AMT FROM DUAL# i/ a- s. S, U6 M- M/ `2 T
            UNION ALL SELECT 6  ID, 12515 WORK_AMT FROM DUAL
- S6 {+ y! O* M3 O% J            UNION ALL SELECT 7  ID, 13555 WORK_AMT FROM DUAL) s- X5 d: z! f9 D1 A! ~8 }3 ~; r
            UNION ALL SELECT 8  ID, 5221  WORK_AMT FROM DUAL
0 S. t. j# W, F; N) D            UNION ALL SELECT 9  ID, 812   WORK_AMT FROM DUAL
+ [8 J/ l+ B- N, f            UNION ALL SELECT 10 ID, 6562  WORK_AMT FROM DUAL! K0 `+ Z+ J) j6 M6 `/ H
                    ORDER BY 2 DESC
$ h' \( S% {: E- Q        ) LOOP) H% {3 r  o, e. j5 V$ k
            L_NUM_SUBSET := NVL(L_NUM_SUBSET,0) + C.WORK_AMT;
( o7 @6 J% `( y" H0 ~# M3 j            DBMS_OUTPUT.PUT_LINE( L_NUM_SUBSET);
+ C% x. Z) b" z0 D( G            /*  ! }& c- x6 n* W
                I NEED TO PUT SOME LOGIC HOW CAN I FIND NEAREST SUM OF SUBSET0 F, u2 W/ T, D# r* t7 ~
            */
- K* ~5 A& {6 K3 U: e# d            IF MAIN_REC.ASSIGN_AMT = L_NUM_SUBSET THEN( X: D7 \8 D6 L' b2 \) K( u; Y
                DBMS_OUTPUT.PUT_LINE( L_NUM_SUBSET);9 N. b& |6 K5 r4 \& a8 z
            END IF;
& h! Y2 G2 X/ l# `( T' v        END LOOP;
: ?( ?/ }  A+ l2 s6 \    END LOOP;               - n( V! C9 e% Y0 Z( L+ I$ W% o
END;
* K8 j9 X1 ?7 f  [' O/ R  o* N! v我一直在寻找这个论坛,发现一个问题, 子组数字的总和  |9 ?( e9 S1 F0 P) R/ G
这几乎是我的相同要求,我所需要的可以指出一点,如何在我拥有的PL / SQL中做到这一点(Oracle DB 11g R2)( I- d0 `9 A! p5 h/ v
               
/ a/ I$ t; x% F) _3 q" h* B$ Q解决方案:
( P  n& N2 a+ p$ }5 l2 ]7 n; o               
7 \" J+ i- ?: z2 |5 B& x' L5 e) N/ m) l; j! z  q
- _5 C9 r2 d3 L& U8 c7 i+ f
                提出问题的方式是,我假设您并不是真正在解决子集和问题,而是一个比较简单的问题,您想将数字与非常有限的子集进行比较,即子集的排序WORK_AMT不断提升,没有差距。7 i1 ?3 U$ c) z: C3 o4 X8 _
简化的问题
1 I. l, D) U7 j) _0 M可以单独使用Oracle SQL来解决:: n' a) l5 k: E( F. Q
WITH; e" a- Y( R8 x. U2 r5 K/ ^) W% k
    ASSIGN(ID, ASSIGN_AMT) AS (/ W. R3 N9 c$ M' L- I- g9 D
                  SELECT 1, 25150 FROM DUAL / |. P; |3 `' U/ f* r3 P( \* W8 C
        UNION ALL SELECT 2, 19800 FROM DUAL
0 k( U' y0 Z. y1 y$ [. o( r$ H3 [; q        UNION ALL SELECT 3, 27511 FROM DUAL% a$ K& n7 P) [( S9 Z7 P
    ),& P2 `, m- [# b3 [/ ^, z; @6 u
    VALS (ID, WORK_AMT) AS (
  _" U2 W! }9 z9 k7 e                  SELECT 1 , 7120  FROM DUAL 4 L$ ^, W7 {3 }: n( t, J2 c
        UNION ALL SELECT 2 , 8150  FROM DUAL
( x% i5 r% }; ^1 s        UNION ALL SELECT 3 , 8255  FROM DUAL
4 y3 `" U! R. K        UNION ALL SELECT 4 , 9051  FROM DUAL4 _5 b# q! x2 b% _
        UNION ALL SELECT 5 , 1220  FROM DUAL
: i: H7 G# p# \" F        UNION ALL SELECT 6 , 12515 FROM DUAL# U3 ^& o! H& S; M8 a
        UNION ALL SELECT 7 , 13555 FROM DUAL
" v4 L: g& R; \, W( t        UNION ALL SELECT 8 , 5221  FROM DUAL) l# H, W+ ?3 R$ q- f
        UNION ALL SELECT 9 , 812   FROM DUAL4 w9 S/ v+ M* D3 y
        UNION ALL SELECT 10, 6562  FROM DUAL
& ]6 Z8 D, D8 i# ]( ^    ),
; g/ {$ z! g. C8 l; M/ t# @    SUMS (ID, WORK_AMT, SUBSET_SUM) AS (
2 @- c3 _' ^" O% t        SELECT VALS.*, SUM (WORK_AMT) OVER (ORDER BY ID); z! Q/ _; P8 q! Q7 |& o/ I. ~
        FROM VALS. ?: H7 B% ]" D; B. T$ q1 S, v
    )$ w' U, Q/ b$ J2 F
SELECT
5 H6 }3 {. @9 N4 ?6 `8 R    ASSIGN.ID,
  W6 q' p+ o0 M7 `# s+ v    ASSIGN.ASSIGN_AMT, / u# I; O9 m% c* f! R0 r" o
    MIN (SUBSET_SUM) KEEP (6 A5 K& I" ^' u% T4 a- e  o; b
        DENSE_RANK FIRST* E3 ~& A2 K7 f' `7 ]1 ?/ v
        ORDER BY ABS (ASSIGN_AMT - SUBSET_SUM)
6 W. g6 v8 g( s8 s& k4 t: d" p    ) AS CLOSEST_SUM
8 E# w4 P& Z8 MFROM! v# m5 b# y" ^( V, V- u6 Q
    ASSIGN2 A0 C" W: ?2 ?, R
CROSS JOIN
2 j' s" }: x$ T- Q; P' i    SUMS' Z9 L+ q' X% L* `6 f" i1 ?
GROUP BY( y+ h3 B5 p0 C
    ASSIGN.ID, ASSIGN.ASSIGN_AMT: W( d, Y8 N+ j: U3 ]2 A
以上收益:; ^; V/ C0 |2 x* D% k2 b0 @
ID  ASSIGN_AMT  CLOSEST_SUM
3 {+ A  N0 X2 E$ _  D---------------------------3 T  T- ^. b3 Y: H. R4 e" _( h
1   25150       29085
) h: g4 \4 H; a, r0 ]3 `) c* c; K2   19800       209350 [6 E+ |. U9 l. F* O* z* m
3   27511       29085
9 B6 K# v- M9 `6 [7 m  ^1 `实际子集总和问题0 k  T5 \  N4 |& X& ~" t. P' J
请注意,此问题在时间和空间上具有指数级的复杂性。对于WORK表中的少量值,只能合理地解决它!' n2 }6 @2 v- g1 t0 M! Z" b! {4 Q
WITH  S" M1 q. i$ r3 z4 q) r
    ASSIGN (ID, ASSIGN_AMT) AS (
+ U6 Z- v1 ~- t3 {, y- X- n7 P                  SELECT 1, 25150 FROM DUAL
! \+ k( a- e- _1 ~: g        UNION ALL SELECT 2, 19800 FROM DUAL
' V+ g# f' l2 D3 p8 _3 W( z        UNION ALL SELECT 3, 27511 FROM DUAL
# I1 y5 X$ l5 F. U8 r    ),
7 B' H& F" @: I7 G; U- _    WORK (ID, WORK_AMT) AS (2 M  V- d5 B2 T- d9 p% `0 |
                  SELECT 1 , 7120  FROM DUAL
' @5 Z- E  d6 e" M# E/ K        UNION ALL SELECT 2 , 8150  FROM DUAL( h8 k% Y3 ^3 Y  T5 A- f
        UNION ALL SELECT 3 , 8255  FROM DUAL
0 m6 }8 ?- x3 J5 a        UNION ALL SELECT 4 , 9051  FROM DUAL
, _( I! a6 ^0 |6 }, O' J        UNION ALL SELECT 5 , 1220  FROM DUAL) b! ^- t" R& O6 e; b
        UNION ALL SELECT 6 , 12515 FROM DUAL
; R! j2 `; f# ~* D2 \- N        UNION ALL SELECT 7 , 13555 FROM DUAL5 b" @7 R; U2 H  E# U; ?
        UNION ALL SELECT 8 , 5221  FROM DUAL* Y& n# C- ?6 n1 u0 S1 }& o
        UNION ALL SELECT 9 , 812   FROM DUAL' W' w) q. M1 a8 b5 Y8 T
        UNION ALL SELECT 10, 6562  FROM DUAL
- L3 B! s& X# L) e$ X% }3 [    ),
0 T6 d- u' Q  U    SUMS (SUBSET_SUM, MAX_ID) AS (+ Q& B4 I7 J% a  r% ]
        SELECT WORK_AMT, ID FROM WORK
( t( r( H: k7 Q) u! ]; a        UNION ALL& w( L/ Y3 T; M
        SELECT WORK_AMT + SUBSET_SUM, GREATEST (MAX_ID, WORK.ID)
+ z5 t$ `3 S- ]% i# R) V        FROM SUMS JOIN WORK
, x. ]$ K; R9 g* Z& I2 A        ON SUMS.MAX_ID 现在产生:
! N! `. t8 r4 ?1 EID  ASSIGN_AMT  CLOSEST_SUM
1 f8 X( T% W4 H$ {5 P# k---------------------------4 q7 g. Y" E7 K$ N5 W. y
1   25150       25133
# l4 [" I/ }, y2   19800       19768' n$ x$ b4 c1 H8 j
3   27511       27488
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则