Software Design
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming Languages - MoreSoftware Design

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old October 10th, 2003, 08:46 PM
akak1997 akak1997 is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2003
Posts: 7 akak1997 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Question Closest Sum

This is NOT a school problem, just some program I'm writing to help me organize my files (putting them on CDRs)

Problem: Given a set of integers (eg filesizes in a directory), a target number (eg max size a CDR can hold), and the given set of integers’ sum is always greater than or equal to the target number. Find a subset of the given integers such that their sum equals to or is closest to the target number. However, it Cannot be greater than the target number (overburn isn't good for your burner). If there is a tie, in another word, there are two or more subsets of integers that give the same sum which is either closest to, or equal to the target number, display just one of those sets.

Example 1:
Input
Integers: 240, 593, 539, 23, 687, 43, 80
Target Number: 2059

Output
240, 593, 539, 687

Example 2:
Input:
Integers: 320, 594, 339
Target Number: 680

Output
320, 339


Can this be solved without using a brute force method?

Thanks in advance!

Reply With Quote
  #2  
Old October 11th, 2003, 08:02 AM
akak1997 akak1997 is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2003
Posts: 7 akak1997 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
nevermind this.... I just found out there's no known algorithm for this... it's a NP-complete problem LOL! anyone who can solve this can get a nobel price or something :P

Reply With Quote
  #3  
Old October 13th, 2003, 01:45 AM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Click here for more information.
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,717 Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 3 Days 12 h 42 m 30 sec
Reputation Power: 1179
How about using this method:
1. Let's call the max capacity as A
2. Arrange the size of the files in descending order and note down the smallest element size.
3. Pick the first element in the array (i.e.) the largest size. Let's call this number B
4a. If (A - B) > (size of smallest element), then pick B, subtract B from A and repeat step 3 for the next element in the array.
4b. If (A - B) < (size of smallest element) AND (sum of smaller elements) > B, then reject B and go to the next element in the array.
4c. If (A - B) < (size of smallest element) AND (sum of smaller elements) <= B, then pick B, subtract B from A and repeat step 3 for the next element.
4d. If A < B, then reject B and repeat step 3 for the next element
5 Continue step 3 until there are no more elements in the array.

To see how this works, lets consider both cases:
Example 1.
Target Number = 2059
Therefore, A = 2059 originally
Array is 687, 593, 539, 240, 80, 43, 23 from step 2 and smallest element is 23
B = 687 (from step 3)
A - B = 2059 - 687 = 1372, which is > 23, so we pick B = 687 from rule 4a.
Now A = 1372 and we repeat step 3 and get B = 593
Now A - B = 1372 - 593 = 779, which is > 23, so we again pick B = 593, by rule 4a.
Now A = 779 and B = 539 from repeating step 3
A - B = 779 - 539 = 240, which is > 23, so we pick B = 539
Now A = 240 and B = 240 from step 3.
A - B = 240 - 240 = 0 which is < 23. So we compute the sum of smaller elements (23 + 43 + 80 = 146) and find that it is less than B (240). Hence, by rule 4c, we accept B and subtract B from A. Now A is 0.
Now for 80, 43 and 23, we reject them all by rule 4d
Thus we picked 687, 593, 539 and 240

Example 2.
A = 680
Array is 594, 339, 320 from step 2 and 320 is smallest element.
Now B = 594 initially
A - B = 86, which is < 320. So we compute sum of smaller elements (339 + 320 = 659). Now (sum of smaller elements) > B, hence by rule 4b, we reject B and go to the next element.
Now A = 680 and B = 339 from step 3.
A - B = 341, which is > 320. Hence, by rule 4a, we pick B and set A = 341
Now A = 341 and B = 320 from step 3.
A - B = 21, which is > 320. Now (sum of smaller elements = 0) is < B (320) So we pick B by rule 4c.
Now A = 21 and we have no more elements, so we quit searching by rule 5.
Numbers picked are 339 and 320

I'll take that (Ig)Nobel prize by Express Mail please .
__________________
Up the Irons
What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
"Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
Down with Sharon Osbourne

Puzzle of the Month solved by Keath and KevinADC, superior perl programmers of the month

Last edited by Scorpions4ever : October 13th, 2003 at 01:48 AM.

Reply With Quote
  #4  
Old October 13th, 2003, 04:34 PM
akak1997 akak1997 is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2003
Posts: 7 akak1997 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Talking Close but no cigar....

yeah you got it to work with the 2 simple examples I gave... but, if you try this:

267,493,869,961,1000,1153,1246,1598,1766,1922. Target=5842

then your method doesn't work...

they don't pay $1M for something you can figure out over a weekend

thanks for trying tho

Reply With Quote
  #5  
Old October 13th, 2003, 04:54 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Click here for more information.
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,717 Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 3 Days 12 h 42 m 30 sec
Reputation Power: 1179
Good call There goes my chance at making $1M

Reply With Quote
  #6  
Old October 13th, 2003, 05:38 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Click here for more information.
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,717 Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 3 Days 12 h 42 m 30 sec
Reputation Power: 1179
When the going gets tough, the tough use brute force, so here's my brute force technique .

1. Build an array of all possible sizes.
2. Scan the above array to generate all possible combinations and their sums into two separate arrays.
3. Go thru the array of sums and compute the difference between max size and each of the sums and pick the one which is >= 0 and is the least difference.
4. From step 3, you've found the combination which comes closest to to the total. So print out the results.

I went ahead and coded the whole thing in python (the program ends up 37 lines long, including whitespace and comments!):
Code:
#!/usr/bin/env python

# Adjust globarray and max_sum as needed.
globarray = [267,493,869,961,1000,1153,1246,1598,1766,1922]
max_sum = 5842
globsum = []
globcombo = []

# Function to generate all combinations
def generate_combos(prefix, start, sum):
    global globarray
    global globsum
    global globcombo

    for i in range(start, len(globarray)):
        string = prefix + str(globarray[i]) + ' '
        newsum = sum + globarray[i]
        # Add new entry to global arrays and recurse further
        globsum.append(newsum)
        globcombo.append(string)
        generate_combos(string, i+1, newsum)

# Generate all combinations of globarray
generate_combos('', 0, 0)

# Now find the minimum difference and its position
max_diff = max_sum
ind = -1
for i in range(0, len(globsum)):
    diff = max_sum - globsum[i]
    if (diff >= 0 and diff < max_diff):
        max_diff = diff
        ind = i

# Now print the winning combo
print "The best combo is ", globcombo[ind], "= ", globsum[ind]
print "Done\n";

This code seems to work for all 3 cases that you presented. Of course, it is a brute force technique rather than an elegant algorithm, but I'd love to see a list that it doesn't work with

Last edited by Scorpions4ever : October 13th, 2003 at 05:41 PM.

Reply With Quote
  #7  
Old October 14th, 2003, 01:39 AM
akak1997 akak1997 is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2003
Posts: 7 akak1997 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Yeah... that's like the only way to solve this problem. but as we all know... combination get HUGE when n gets big... it'll work for all list...the question is How LONG it would take to scan a list of 100 numbers (eg 100C50, it'll take forever).

I've a good class for combination, which will return the combination indexes, so I can use it for many problems that I can't come up with a good algorightm.... I use it alot coz I can't really think of good algorithms hehehe However, since this app that I'm planning to build will usually involves a lot of Directory Size (ie the integers in the list) maybe > 100 directories.... so brute force isn't an option...



.... well.... thanks for your time for trying to help me solve an unsolveable problem

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming Languages - MoreSoftware Design > Closest Sum


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 1 hosted by Hostway
Stay green...Green IT