|
我正在寻找您的专家的指导,以找出一种将数字与数字子集的总和进行比较的方法
% 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 |
|