recurrence relation of the dynamic programming to get the maximum credits - dynamic-programming

My problem is I have a fixed time and I must get the highest profit.
How can I write recurrence relation for a dynamic program?
An example for my problem:
The times are [3, 2, 4, 2, 1]
The profits are [20, 15, 20, 25, 20]
The requested hours are 6
The answer should be 65 by picking the times with indices 0,3,4 that have profit 20 + 25 + 20 = 65.

Lets define the function f(i,h) that gives the maximum profit for exactly h hours from the profits with indices(0,1,2...,i), then the result for your case is f(size_of_the_array , number_of_hours) = f(5,6).
The main recurrence formula will be like this:
f(i,h) = max(w1,w2);
w1 = f(i-1,h); //don't consider the i-th profit in the sum
w2 = f(i-1,h-time[i]) + profit[i]; : h>=time[i] //consider the i-th profit in the sum
This is similar to a standard problem in dynamic programming called 0-1Knapsack
you can study it first, then your question will be easy to solve.

Related

Sum of elementwise product of subsets' min of two arrays

As the title suggests, writing the question explicitly could create some confusion. So, I start by an example.
Let's say we have two arrays: a = [1,3,2] and [5,4,3]. What I would like compute in a brute-force way is to first compute the minimum of each of the subset as:
aa = [1, 3, 2, min(1,3), min(1,2), min(3,2), min(1,3,2)]
bb = [5, 4, 6, min(5,4), min(5,6), min(4,6), min(5,4,6)]
and then finally the sum of the product aa ** bb:
1*5 + 3*4 + 2*6 + min(1,3)*min(5,4) + min(1,2) * min(5,6) + min(3,2)*min(4,6) + min(1,3,2)*min(5,4,6)
Obviously, the brute-force calculation is not efficient, and the memory and time complexity increase exponentially with respect to the number of elements in the arrays.
To give a bit more context, the arrays could be of real numbers (positive and negatives), and each element in the first array corresponds to the element with the same index in the second array.
I have already seen some similar problems, like:
Sum of OR of smallest and largest elements of each subset of a set
Sum of products of elements of all subarrays of length k
But they are mainly focused on sum of the min of subsets for one array only.

What are handy Haskell concepts to generate numbers of the form 2^m*3^n*5^l [duplicate]

This question already has answers here:
New state of the art in unlimited generation of Hamming sequence
(3 answers)
Closed 10 months ago.
I am trying generate numbers of the form 2^m*3^n*5^l where m, n, and l are natural numbers including 0.
The sequence follows: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, .....
I am testing it by getting the one millionth number. I implemented it using list comprehension and sorting, but it takes too long. I want a faster solution. I have been spending days trying to do this to no avail.
I do not want a complete solution. I just want to know what Haskell concepts are necessary in accomplishing it.
Here's an approach that doesn't need any Haskell concepts, just some math and computer science.
Grab a library that offers priority queues.
Initialize a priority queue containing only the number 1.
Loop the following indefinitely: extract the minimum value from the queue. Put it next in the output list. Insert that number times 2, 3, and 5 as three individual entries in the queue. Make sure the queue insert function merges duplicates, because there will be a lot of them thanks to commutativity of multiplication.
If you have a maximum you're working up to, you can use it to prune insertions to the queue as a minor optimization. Alternatively, you could take advantage of actual Haskell properties and just return an infinite list using laziness.
First, write a function of type Int -> Bool that dermines if a given integer is in the sequence you defined. It would divide the number by 2 as many times as possible (without creating a fraction), then divide it by 3 as many times as possible, and finally divide it by 5 as many times as possible. After all of this, if the number is larger than 1, then it cannot be expressed as a products of twos, threes, and fives, so the function would return false. Otherwise, the number is in your sequence, so the function returns true.
Then take the infinite sequence of integers greater than 0, and use the function above to filter out all numbers that are not in the sequence.
Carl's approach can be improved by inserting less elements when removing the minimal element x: As 2<3<4<5<6 you can just
append 3*x/2 if x is even but not divisible by 4
append 4*x/3 if x is divisible by 3
append 5*x/4 if x is divisible by 4
append 6*x/5 if x is divisible by 5
In code it looks like this:
g2 x | mod x 4 == 0 = [5*div x 4]
| even x = [3*div x 2]
| otherwise = []
g3 x | mod x 3 == 0 = [4*div x 3]
| otherwise = []
g5 x | mod x 5 == 0 = [6*div x 5]
| otherwise = []
g x = concatMap ($ x) [g2, g3, g5]
So you if your remove the minimal element x from the priority queue, you have to insert the elements of g x into the priority queue. On my laptop I get the millionth element after about 8 min, even if I use just a list instead of the better priority queue, as the list grows only to a bit more than 10000 elements.

fast access to a matrix by row and column key

I have such a matrix
id = (123, 979, 234)
matrix:
123 979 234
123 0 30 45
979 30 0 60
234 15 45 0
My problem is, I want to access a matrix in a fast and easy way. Something like this:
matrix[id][id]
example:
print(matrix[123][979])
output 30
For now I'm using a list including a list. So I can access the data by knowing the position. This is not very comfortable, because I don't know the position, I just know the id. For now I am using a function which gives me the right number. This is very slow and I need this for a calculation with many iterations.
Does anybody has an idea to solve this in a fast way?
The function to calculate the matrix for now is this below, but it is just zero or 30*60 seconds. I want to create a new matrix with individual times, but before coding it, I want to figure out, in which way I can store the data to have fast and easy access.
def get_matrix(permutation):
criteria = [django_model1.objects.filter(id=id).get().django_model2.format for id in permutation]
# and to speed up: an ugly combination of 2 list comprehensions and a lambda function.
return [[(lambda c1, c2: timedelta(seconds = 0 ) if c1==c2 else timedelta(seconds = 30*60 )) (c1,c2) for c2 in criteria] for c1 in criteria ]
Using pandas:
data = [[0, 30, 45], [30, 0, 60], [15, 45, 0]]
ids = [123, 979, 234]
df = pd.DataFrame(data, columns = ids, index = ids)
data can be constructed in a lot of ways: depends on how you're constructing your matrix. Refer to the docs for more info.
Now, refer by id:
>>> df[979][123]
30
Note: The order of ids is reversed since pandas takes the column id as the first index.

np.percentile not equal to quartiles

I'm trying to calculate the quartiles for an array of values in python using numpy.
X = [1, 1, 1, 3, 4, 5, 5, 7, 8, 9, 10, 1000]
I would do the following:
quartiles = np.percentile(X, range(0, 100, 25))
quartiles
# array([1. , 2.5 , 5. , 8.25])
But this is incorrect, as the 1st and 3rd quartiles should be 2 and 8.5, respectively.
This can be shown as the following:
Q1 = np.median(X[:len(X)/2])
Q3 = np.median(X[len(X):])
Q1, Q3
# (2.0, 8.5)
I can't get my heads round what np.percentile is doing to give a different answer. Any light shed on this, I'd be very grateful for.
There is no right or wrong, but simply different ways of calculating percentiles The percentile is a well defined concept in the continuous case, less so for discrete samples: different methods would not make a difference for a very big number of observations (compared to the number of duplicates), but can actually matter for small samples and you need to figure out what makes more sense case by case.
To obtain you desired output, you should specify interpolation = 'midpoint' in the percentile function:
quartiles = np.percentile(X, range(0, 100, 25), interpolation = 'midpoint')
quartiles # array([ 1. , 2. , 5. , 8.5])
I'd suggest you to have a look at the docs http://docs.scipy.org/doc/numpy/reference/generated/numpy.percentile.html

random numbers from geometric distribution such that their sum equals SUM

I want to draw k random numbers i_1,...,i_k with min <= i <= max from an exponentially shaped distribution of values with m,std being median and standard of the population's values. The sum(i1,..,ik) should equal a given parameter SUM.
Example:
Given:
k = 9 SUM = 175 min = 8 max = 40 m = 14
Desired:
[9, 10, 11, 12, 14, 17, 23, 30, 39]
I don't know if this is actually possible without depending on luck to draw a combination satisfying the SUM rule. I'd appreciate any kind of help or comment. Thank you.
EDIT: In a former version I wrote about exponentional distributions where an exact solution is impossible, rather I meant an exponentially shaped distribution with discrete values like a geometric distribution for instance.
EDIT2: Corrected the number k in the example.

Resources