After some research, below is a modified version of the subset_sum recursion I found on SO. The modified version attempts to not only return the exact sum if there is one, but also returns the closest set of integers if an exact sum cannot be found. Furthermore, there is a list size requirement that determines how many numbers must be added up to determine the final sum
def findFourPlus(itemCount, seq, goal):
goalDifference = float("inf")
closestPartial = []
subset_sum(itemCount, seq, goal, goalDifference, closestPartial, partial=[])
print(closestPartial)
def subset_sum(itemCount, seq, goal, goalDifference, closestPartial, partial):
s = sum(partial)
# check if the partial sum is equals to target
if(len(partial) == itemCount):
if s == goal:
print(partial)
else:
if( abs(goal - s) < goalDifference):
goalDifference = abs(goal - s)
closestPartial = partial
for i in range(len(seq)):
n = seq[i]
remaining = seq[i+1:]
subset_sum(itemCount, remaining, goal, goalDifference, closestPartial, partial + [n])
The problem I am facing right now is that closesetPartial will always be an empty list, because each call of subset_sum() will refresh cloestPartial back to an empty list. I tried to move goalDifference and cloestPartial initialization outside of subset_sum function, but I am return with local variable 'goalDifference' referenced before assignment error.
What can I do to both preserve the recursive algorithm while keeping track of the closest-sum so far? and is there a better way of approaching this problem?
Initialize closestPartial and goalDifference outside of the call to subset_sum and pass them in as parameters. Either maintain a single closestPartial that is passed by reference to every subset_sum call, or else pass a copy of closestPartial to each subset_sum call - the former will likely be more efficient, while the latter will be easier to implement / reason about because it will be free of side-effects.
Related
I understand recursion and what the advantages it brings to writing code efficiently. While I can code recursive functions, I cannot seem to wrap my head around how they work. I would like someone to explain me recursion instinctively.
For example, this code:
int fact(int n)
{ if n<0:
return -1
elif n==0:
return 1
else
return n*fact(n-1)
}
These are some of my questions:
Let's say n=5. On entering the function,the control goes to the last return statement since none of the previous conditions are satisfied.
Now, roughly, the computer 'writes' something like this: 5*(fact(4))
Again, the fact() function is called and the same process gets repeated except now we have n=4.
So, how exactly does the compiler multiply 5*4 and so on until 2 since its not exactly 5*4 but 5*fact(4). How does it 'remember' that it has to multiply two integers and where does it store the temporary value since we haven't provided any explicit data structure?
Again let's say n=5. The same process goes on and eventually n gets decremented to 0. My question is why/how doesn't the function simply return 1 as stated in the return statement. Similar to my previous question, how does the compiler 'remember' that it also has 180 stored for displaying?
I'd be really thankful if someone explains this to me completely so that can understand recursion better and intuitively.
Yeah, for beginners recursion can be quite confusing. But, you are already on the right track with your explanation under "1.".
The function will be called recursively until a break condition is satisfied. In this case, the break condition is satisfied when n equals 0. At this point, no recursive calls will be made anymore. The result of each recursive call is returned to the caller. The callers always "wait" until they get a result. That's how the algorithm "knows" the receiver of the results. The flow of this procedure is handled by the so called stack.
Hence, in your informal notation (in this example n equals 3):
3*(fact(2)) = 3*(2*fact(1)) = 3*(2*(1*fact(0))).
Now, n equals 0. The inner fact(0) therefore returns 1:
3*(2*(1*(1)))) = 3*(2*(1)) = 3*(2) = 6
You can see a bit like this
The function fact(int n) is like a class and every time you call fact(int n) you create an instance of that class. By creating them (calling them) from the same function, you are creating a chain of instances. Once you reach break condition, those functions start returning one by one and the value they returned to calculate a new value in the return statement return n*fact(n-1) e.g. return 3*fact(2);
I'm trying to use Matlab to implement the MDO algorithm, which requires me to sort an array of objects of a custom-defined mdoVertex class by their degree, and then delete the one with the smallest degree value. My first attempt was this:
for i = 1:m
if graph(i).degree < minDegree
minDegree = graph(i).degree;
elimObject = graph(i);
end
end
Matlab is complaining that elimObject, or the object to be eliminated after the loop executes, is an undefined function or variable. How, then, can I keep track of not only the current smallest degree the loop has encountered, but also which object it corresponded to? 'graph' is the name of the array holding all of my vertex objects.
I suspect that you're somehow trying to call clear on the object returned from your function. Or is it just a few lines of code in a script? I'm guessing here. In any event, calling clear won't work. As you've noticed, clear expects to be given a variable name.
But in this case, you're not trying to delete a variable, you're trying to remove an element from an array. For that, you do arrayname(indextodelete) = [];
So I think that you want...
minDegree = inf; % See what I did there? I defined the variable, and I did it in such a way that I KNOW that the first vertex will satisfy the condition.
for i = 1:length(graph) % Properly loop over the entire graph
if graph(i).degree < minDegree % The first vertex will definitely satisfy this. Maybe another one (or more) will later!
minDegree = graph(i).degree;
minDegreeIndex = i; % Don't record the value, just remember WHERE it is in the array.
end
end
graph(minDegreeIndex) = []; % Now, remove the element that you identified from the array!
(By the way, you never showed us how you tried to eliminate elimObject. I assume that you called clear (the object that you identified)? You shouldn't make us guess; show us.)
Given an array of complex objects, an algorithm for mapping each to Comparable values, and the desire to find the minimum such value, is there a built-in library method that will do this in a single pass?
Effective but not perfectly efficient solutions:
# Iterates through the array twice
min = objects.map{ |o| make_number o }.min
# Calls make_number one time more than is necessary
min = make_number( objects.min_by{ |o| make_number o } )
Efficient, but verbose solution:
min = nil
objects.each{ |o| n=make_number(o); min=n if !min || n<min }
No, no such library method already exists.
I don't really see an issue with either of your two original solutions. The enumerator code is written in C and is generally very fast. You can always just benchmark it and see what is fastest for your specific dataset and code (try https://github.com/acangiano/ruby-benchmark-suite)
However, if you really do want one pass, you can simplify your #each version by using #reduce:
min = objects.reduce(Float::INFINITY){ |min, o|
n = make_number(o)
min > n ? n : min
}
If your objects are already numbers of some form, you can omit the Float::INFINITY. Otherwise, in order to make sure we are only comparing number values, you will need to add it.
When you want to flatten an array all the way, where the maximum depth of the array is known, is it better in terms of performance to always pass that maximum depth as an argument to Array#flatten? For example, is it better to do the former than the latter in the following?
[[:foo], [:bar], [:baz], ...].flatten(1)
[[:foo], [:bar], [:baz], ...].flatten
Not on MRI, because the check whether an element is an array happens whether you set a level or not. It essentially does this (psuedo-Ruby, if you want the original C it starts here)
array.each do |value|
if !value.is_array? || current_depth >= max_depth
result << value
else
current_depth += 1
recurse ...
end
end
The actual implementation is not explicitly recursive and there's no is_array? method, but hey, you get the point.
The take-home message is that your use case will always hit the !value.is_array? condition, and will never use the argument you passed, so you don't gain anything by passing it.
I am trying to keep the last n elements from a changing list of x elements (where x >> n)
I found out about the deque method, with a fixed length, in other programming languages. I was wondering if there is something similar for VB6
Create a Class that extends an encapsulated Collection.
Add at the end (anonymous), retrieve & remove from the beginning (index 1). As part of adding check your MaxDepth property setting (or hard code it if you like) and if Collection.Count exceeds it remove the extra item.
Or just hard code it all inline if a Class is a stumper for you.
This is pretty routine.
The only thing I can think of is possibly looping through the last 5 values of the dynamic array using something like:
For UBound(Array) - 5 To UBound(Array)
'Code to store or do the desired with these values
Loop
Sorry I don't have a definite answer, but hopefully that might help.
Here's my simplest solution to this:
For i = n - 1 To 1 Step -1
arrayX(i) = arrayX(i - 1)
Next i
arrayX(0) = latestX
Where:
arrayX = array of values
n = # of array elements
latestX = latest value of interest (assumes entire code block is also
within another loop)