Selective addition problem

G

GD

I have a challenge for all you Sir Accessalots out there!

Let's say I have a list of 30 numbers. I also have another number, larger
than the rest. What I need is something that will:

(My first preference) provide me with all possible combinations of numbers
in the list of 30 that add up to the larger number;

(My second preference) provide me with at least one combination of numbers
in the list of 30 that add up to the larger number;

Or (my third preference) tell me that at least one combination exists.

Can Access (or any other app you know of) do this?
 
T

Tom van Stiphout

On Fri, 19 Dec 2008 06:13:09 -0800, GD <[email protected]>
wrote:

Interesting VBA challenge. The kind some teachers would ask their
students to complete. This is certainly possible. First you design the
algorithm. That's the challenging and rewarding part. Then you
implement it. That should be straightforward.

-Tom.
Microsoft Access MVP
 
D

Dorian

VBA or in fact almost any programming language could solve that. The question
is, is your PC powerful enough to run the algorithm - because depending on
the number of values, the number of combinations to attempt could be huge.

-- Dorian
"Give someone a fish and they eat for a day; teach someone to fish and they
eat for a lifetime".
 
A

Al Campagna

GD,
When you say
"all possible combinations of numbers ... that add up to the larger
number..."
do you mean any combination of 2 numbers, or any combination of 3 numbers,
or 4, or 5, etc..
If more than 2 numbers can combine to create the sum, the calculation
becomes astronomical!!
--
hth
Al Campagna
Microsoft Access MVP
http://home.comcast.net/~cccsolutions/index.html

"Find a job that you love... and you'll never work a day in your life."
 
C

Clifford Bass

Hi,

You could create several cartesian product queries to do that.

tblTheNumbers
TheNumber

A query for two numbers:

SELECT A.TheNumber, B.TheNumber, [A].[TheNumber]+.[TheNumber] AS
TheNumberTotal
FROM tblTheNumbers AS A, tblTheNumbers AS B
WHERE (((B.TheNumber)>[A].[TheNumber]) AND
(([A].[TheNumber]+.[TheNumber])=[Desired Sum:]));

A query for three numbers:

SELECT A.TheNumber, B.TheNumber, C.TheNumber,
[A].[TheNumber]+.[TheNumber]+[C].[TheNumber] AS TheNumberTotal
FROM tblTheNumbers AS A, tblTheNumbers AS B, tblTheNumbers AS C
WHERE (((B.TheNumber)>[A].[TheNumber]) AND ((C.TheNumber)>.[TheNumber])
AND (([A].[TheNumber]+.[TheNumber]+[C].[TheNumber])=[Desired Sum:]));

And so forth.... It may conk out above a certain number.

Clifford Bass
 
A

Albert D. Kallal

Hum, these numbers are quite high. likely *just* within the ability
of a VBA to solve this.

With your question as posted, all 30 numbers could add up to equal that ONE
test number.

That means we have (combinations here, NOT permeations, as

12 + 15

and

15 + 12

are the SAME result. so, distinct means combinations...

The total possible number with 30 different numbers are:

30 chose 30 = (one number) = 1
+
30 choose 29 = 30 possible numbers
+
30 choose 28 = 435 possible numbers
+
30 choose 27 = 4060
+
30 choose 26 = 27405

etc.

Firing up excel, using the "format painter" makes finding that answer a snap
for the total numbers.

A few drags + drops, and we get a total of:

1,073,741,823

Ok, so, that is billion possible numbers.

Assuming our computer can test about 10 million per second, we get:

107.3741823 seconds

Hum, that's about 2 minutes of processing. (likely it would take longer).

So, one just needs to write out the a routine to take that list of 30
numbers and gen the possible list of numbers (totals) in a loop and compare
this to our "check number".

Hum, I don't recall writing a "list" gen program (that code will be a bit
tricky). I don't know if vba will run fast enough for 30 numbers. However,
for smaller lists, even vba should be in the performance range to solve this
problem in a reasonable amount of time.

I will later tonight perhaps look around for a list gen routine (or write
one) and see if I ..and then see how fast this can run under ms-access....
 
J

James A. Fortune

GD said:
I have a challenge for all you Sir Accessalots out there!

Let's say I have a list of 30 numbers. I also have another number, larger
than the rest. What I need is something that will:

(My first preference) provide me with all possible combinations of numbers
in the list of 30 that add up to the larger number;

(My second preference) provide me with at least one combination of numbers
in the list of 30 that add up to the larger number;

Or (my third preference) tell me that at least one combination exists.

Can Access (or any other app you know of) do this?

Here are some thoughts toward a possible VBA solution:

A brute force method could involve counting in binary from 1 to 2 ^ 30 -
1 and adding the kth number when the corresponding bit is 1, then
checking the sum against the given number -- a tad gauche.

This problem is related to:

Weisstein, Eric W. "Greedy Algorithm." From MathWorld--A Wolfram Web
Resource. http://mathworld.wolfram.com/GreedyAlgorithm.html

Search the same site under "Partition" to show that the Mathematica
program has some functions for partitioning.

A restatement of the problem:

Find the number of partitions of N where each partition is exactly one
of the positive integers A1, A2, ..., Ak where k = 30.

Note that the Ai values are not necessarily distinct and that for a
well-posed problem, each Ai should be < N.

When binary bits are used in a loop, every possibility is checked. Once
your sum gets above N no more terms should get attempted so potentially
many less combinations, depending on the particular data, need to be
evaluated.

Plan: Get strings of 0's and 1's indicating which Ai's are used in the sum.

A(Val(Mid(strAnswerBits, I, 1)) * I) can be used to generate an answer
string from strAnswerBits. Something like (air code):

Const LISTMAX = 30
....
If Mid(strAnswerBits, I, 1) <> "0" Then
strAnswer = strAnswer & A(Val(Mid(strAnswerBits, I, 1)) * I)
If I <> LISTMAX Then
strAnswer = strAnswer & " + "
End If
End If

"1001000...1" => A1 + A4 + ... + A30

There might be several answer strings or one or none that satisfy the
condition.

Suppose your substring is '101'. Let the Residue for that substring be
N - A1 - A3. That is, the amount left over after those choices. (Did
someone mention the possibility of a recursive solution?)

Maybe look at traversing a binary tree where left branches indicate a 0
value and right branches indicate a 1 value for each Ai. All the nodes
along a given tier correspond to the same Ai. Once the Residue is zero
or less, there's no need to visit any sibling nodes of that node. If
the Residue is zero, then the string is padded with 0's as necessary and
a solution has been found. If the residue is less than zero you've
reached a cul-de-sac and no solution will be forthcoming through that
node. Alternatively, when a candidate substring doesn't pan out, you
can calculate how many numbers start with that substring and skip them
in the binary loop. Although much computation can usually be skipped,
there is no guarantee that the data will not be so pernicious that you
have to check every node. I hope the following displays the way I'd like:

"101" =>

x A1
\
\
x x A2
/
/
x x x x A3
\
\
x x x x x x x x

A SQL solution might start with the ideas from the following thread:

http://groups.google.com/group/microsoft.public.access/browse_frm/thread/228ad5285b0ebbd2

The Christmas combinatorics problem is also related but it's a bit
abstract :):

http://groups.google.com/group/comp.databases.ms-access/msg/905de7b0e1696857

The disclaimer goes double for this problem :).

James A. Fortune
[email protected]
 
Top