Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
Stoad
Freaky Yak Linguist
1983 Posts |
Posted - 2003-11-02 : 18:04:20
|
You are given say a pricelist of books. And you have to find outall possible sets of books, each of them having total sum of bookprices equal to a given number.set nocount onif object_id('tempdb..#t')>0 drop table #tif object_id('tempdb..#tt')>0 drop table #ttcreate table #t (n int, price int)insert into #t -- note asc order of book pricesselect 1, 1 union allselect 2, 3 union allselect 3, 4 union allselect 4, 5 union allselect 5, 7 union allselect 6, 7 union allselect 7, 11 union allselect 8, 15 union allselect 9, 20 union allselect 10, 20 union allselect 11, 22 union allselect 12, 28 union allselect 13, 33 union allselect 14, 40 union allselect 15, 43 union allselect 16, 47 union allselect 17, 50 union allselect 18, 55 union allselect 19, 56 union allselect 20, 63gocreate table #tt (n int, price int)godeclare @rows int, @p int, @sum int set @sum=16delete from #t where price>@sumset @p=(select sum(price) from #t)if @p>=@sumbeginset @rows=(select max(n) from #t)declare @n int, @s intset @n=@rows+1 set @s=0while 0=0beginwhile @n>1beginset @n=@n-1if @s+(select price from #t where n=@n)<=@sumand @s+(select sum(price) from #t where n<=@n)>=@sumbeginset @s=@s+(select price from #t where n=@n)insert into #tt select n, price from #t where n=@nif @s=@sum select * from #tt --- outputtingendendset @n=(select min(n) from #tt)set @s=@s-(select price from #tt where n=@n)delete from #tt where n=@nif @s=0 and (select sum(price) from #t where n<@n)<@sum breakendenddrop table #ttdrop table #tResult for @sum=16 (for e.g. @sum=76 number of different sets = 196):n price ----------- ----------- 8 151 1n price ----------- ----------- 7 114 5n price ----------- ----------- 7 113 41 1n price ----------- ----------- 6 74 53 4n price ----------- ----------- 6 74 52 31 1n price ----------- ----------- 5 74 53 4n price ----------- ----------- 5 74 52 31 1 EDIT: added one more condition (in blue) into an IF statement.Now it works incredibly fast. |
|
Arnold Fribble
Yak-finder General
1961 Posts |
Posted - 2003-11-03 : 08:46:25
|
Isn't that the subset sum problem? |
|
|
Stoad
Freaky Yak Linguist
1983 Posts |
Posted - 2003-11-03 : 08:59:19
|
Exactly, Arnold. LOL :) And what then?? |
|
|
Arnold Fribble
Yak-finder General
1961 Posts |
Posted - 2003-11-03 : 11:54:29
|
quote: And what then??
Don't know, really. I was just pointing out that it's a well-known (and named) problem. And in the general case, it's NP-complete.Apparently, there's a dynamic-programming solution that's tractable if the problem size is small enough, and other solutions for 'low-density' situations, and other special cases, but I didn't really understand any of it |
|
|
Stoad
Freaky Yak Linguist
1983 Posts |
Posted - 2003-11-03 : 14:51:06
|
quote: I didn't really understand any of it
LOL, exactly my case!! Plus, I have never even tried to understand them(as I can remember I was able to understand only the bubble sortingalgorithm, but today I am not sure how exactly it works).As to my solution, of course it is a simple backtracking. BTW, if we needto find only one (any) required subset then the code produces it in a fewseconds. Today I tested it against 200 rows with random numbers from 1to about 900. Got the first subset in 1-5 seconds (depends on the soughtsum)... It is terribly hard to think up such test data that could increasesignificantly the time of first finding. |
|
|
|
|
|
|
|