find the longest increasing subsequence (LIS) - dynamic-programming

Given A= {1,4,2,9,7,5,8,2}, find the LIS. Show the filled dynamic programming table and how the solution is found.
My book doesnt cover LIS so im a bit lost on how to start. For the DP table, ive done something similar with Longest Common Subsequences. Any help on how to start this would be much appreciated.

Already plenty of answers on this topic but here's my walkthrough, I view this site as a repository of answers for future posterity and this is just to provide additional insight when I worked through it myself.
The longest Increasing Subsequence (LIS) problem is to find the length of the longest subsequence of a given sequence such that all elements of the
subsequence are sorted in increasing order. For example, length of LIS for
{ 10, 22, 9, 33, 21, 50, 41, 60, 80 } is 6 and LIS is {10, 22, 33, 50, 60, 80}.
Let S[pos] be defined as the smallest integer that ends an increasing sequence of length pos.
Now iterate through every integer X of the input set and do the following:
If X > last element in S, then append X to the end of S. This essentialy means we have found a new largest LIS.
Otherwise find the smallest element in S, which is >= than X, and change it to X. Because S is sorted at any time, the element can be found
using binary search in log(N).
Total runtime - N integers and a binary search for each of them - N * log(N) = O(N log N)
Now let's do a real example:
Set of integers: 2 6 3 4 1 2 9 5 8
Steps:
0. S = {} - Initialize S to the empty set
1. S = {2} - New largest LIS
2. S = {2, 6} - 6 > 2 so append that to S
3. S = {2, 3} - 6 is the smallest element > 3 so replace 6 with 3
4. S = {2, 3, 4} - 4 > 3 so append that to s
5. S = {1, 3, 4} - 2 is the smallest element > 1 so replace 2 with 1
6. S = {1, 2, 4} - 3 is the smallest element > 2 so replace 3 with 2
7. S = {1, 2, 4, 9} - 9 > 4 so append that to S
8. S = {1, 2, 4, 5} - 9 is the smallest element > 5 replace 9 with 5
9. S = {1, 2, 4, 5, 8} - 8 > 5 so append that to S
So the length of the LIS is 5 (the size of S).
Let's take some other sequences to see that this will cover all possible caveats, each presents its own issue
say we have 1,2,3,4,9,2,3,4,5,6,7,8,10
basically it builds out 12349 first, then 2 will replace 3, 3 will replace 4, 4 will replace 9, then append 5,6,7,8,10
so will look like 1,2,2,3,4,6,7,8,10
take the other case we have 1,2,3,4,5,9,2,10
this will give us 1,2,2,4,5,9,10
or take the case we have 1,2,3,4,5,9,6,7,8,10
this will give us 1,2,3,4,5,7,8,10
so that kind of illuminates what goes on, in the first case the critical juncture being what happens when you hit the 2 after the 9,
how do you deal with these. well the block of 2,3,4 won't do anything really, when you hit 5 you replace the 9 because the 5 and 9
are virtually indifferentiable 9 ends the block of the first 5 increasing elements, you replace 9 with 5 because 5 is smaller so there
is greater potential to hit something > 5 later on. but you only replace the smallest element > itself. for ex. in the last case,
if your 6 doesn't replace 9 but instead replaces 1 and 7 replaces 2 and 8 replaces 3, then we get a final array of 7 elements instead
of 9. So just do a couple of these and figure out the pattern, this logic isn't the easiest to translate to paper.

There's a very strong relation between LIS and LCS.
http://en.wikipedia.org/wiki/Longest_increasing_subsequence
This article explains it pretty well I think. Basically the idea is, you can reduce one problem to the other (this is the case in many situations involving Dynamic programming).

Related

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.

How to find 90th% value?

I have this list:
def grades = [5,4,3,2,1,1]
Where index is a grade, and value is an occurrence of the grade:
Grade
Occurrence
0
5
1
4
2
3
3
2
4
1
5
1
How can I calculate the 90th percentile for the grades?
This gets me a whole grade. I was hoping to find an exact value of 90th percentile, but this will do for me.
def grades = [5,4,3,2,1,1]
sum=grades.sum()
per_grade=0
per_value=sum*0.9
grades.eachWithIndex { grade_count, grade ->
per_value-=grade_count
if (per_value<0){per_grade=grade-1}
if (per_value==0){per_grade=grade}
}
out.write(per_grade)
A total of 16 grades have been given. 90% are 14.4 grades, so discard the lowest 14 grades and take the smallest remaining (in your example it will be 4).
How to code? There are some ways:
You may count through the array you have got. Subtract 5 from 14 (= 9), then 4, then 3, then 2. Once you reach zero, you’re at the index of the 90th percentile.
Maybe easier to understand, but will require a few more code lines: Put all 16 grades into an array (or list): [0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5]. Since the array is sorted, the median is found at index 14.

How can i pick the first value of repeatedly recorded numbers

I have a large data file containing some column of hours like shown below
0
0
0
0
0
1
1
1
1
2
2
3
3
...
....
This data continues like this until 23 then starts from zero again, so what i want to do here is to pick the first value from every group of same number so that i have output like
0
1
2
3
4
5
.
.
.
23
0
1
...
and so on, i'm not sure if my question is clear, this seem to be easy but i have been struggling to do it. Please note that an hour can be reapeted any often.
Unless I misunderstood the question something like below should do what you want.
# the function only appends a number to your `final list`,
# if the new number is different than the `final lists`s last element.
def appendIfNewNumber(unqNumbers, number):
if len(unqNumbers) == 0 or number != unqNumbers[-1]:
unqNumbers.append(number)
# instantiate some list
unqNumbers = []
someIterator = [1, 1, 1, 2, 3, 3, 4, 4, 2, 10] # for the sake of example.
# Assuming you are either reading numbers one by one from your file,
# or already have them stored in a list.
# `someIterator` below is practically assumed to contain the elements of
# your first list - the one you'd like to filter.
for number in someIterator: # or list.
appendIfNewNumber(unqNumbers, number)
print(unqNumbers) # --> [1, 2, 3, 4, 2, 10]

Excel: Parent Child tree view: Add dynamically node (parent) numbers

I am working on a keyword tree for some Digital Asset System. Basically I have to import it in this format (mandatory):
1,0,Top Level A
2,0,Top Level B
3,0,Top Level C
4,1,Sub Level A
5,1,Sub Level B
6,4,Deepest Level A
7,5,Deepest Level B
8,3,Sub Level from Top Level C
Which in my case looks like this (this is an excerpt and I added some blank spaces to make it more readable):
1, 0, Natural and Organic Cosmetic (NOC)
2, 1, bodycare
3, 1, facecare
4, 1, babycare
5, 1, pregnancy
6, 1, lipcare
7, 1, hair
8, 1, teeth
9, 1, wellness
10, 1, mencare (specific)
11, 0, Model
12, 11, application without product
13, 11, application with product
14, 11, adult
15, 14, man
16, 14, woman
But this list hast to be maintained and update regularly, and in order to ease the process I have created an Excel file where very column defines the level depth like this :
1 0 Natural and Organic Cosmetic (NOC)
2 1 bodycare
3 1 facecare
4 1 babycare
5 1 pregnancy
6 1 lipcare
7 1 hair
8 1 teeth
9 1 wellness
10 1 mencare (specific)
11 0 Model
12 11 application without product
13 11 application with product
14 11 adult
15 14 man
16 14 woman
Now my problem is that I would like to add much more sub-level items let's say under "body-care". As a result I have to manually update all parents id number which are unfortunately abased on the unique and sequential identifier in the first row.
How can I dynamically update the parent node ID number when I add a new row?
This solution will only work with a fixed depth of the tree. So if you want to add a level 3 node you will have to expand the formula accordingly...
Also you will have to drag/copy the formulas in columns A and B down whenever you insert a new row. Unless you can use tables (Excel 2007 and more recent versions) where formulas will be automatically added if they are the same for the whole column.
OK. The idea is to check what level of depth we are in and finding the first (upward looking) entry in the parent level. Not very elegant but it works.
In column A you simply use the formula =ROW()-1 to get the "unique sequential node numbers".
For column B (Parent Node Number) you can use LOOKUP like this:
=IF(C2<>"",0,IF(D2<>"",LOOKUP(2,1/(C$2:C2<>""),A$2:A2),IF(E2<>"",LOOKUP(2,1/(D$2:D2<>""),A$2:A2))))
The condition (C$2:C7<>"") will return an array like the following with 1 for a match and 0 for no match:
{0;0;1;0;0;0;1;0}
Dividing 1 by that array will result in an array like this:
{#DIV/0!;#DIV/0!;1#DIV/0!;#DIV/0!;#DIV/0!;1#DIV/0!}
If you use LOOKUP with a lookup value greater than any of the values in the range it will return the last numerical value which in this case is the last 1 of the last match.

Dynamic Programming: Finding the number of ways in which a order-dependant sum of numbers is less than or equal to a number

Given a number N, and a set S of numbers, find the number of ways in which a order-dependant sum of numbers of S is less than or equal to N. The numbers in S can occur more than once. For example, when N = 3 and S={1, 2}, the answer is 6. In this example, 1, 1+1, 2, 1+1+1, 1+2, 2+1 are less than or equal to 3.
When S = {1, 2}, the answers for N = 0, 1, 2... are 0, 1, 3, 6, 11, 19, 32.... Think about why these numbers might be the same as the Fibonacci sequence with 2 subtracted.
When S={n1, n2, …, nk}, you have f(N)=f(N-n1)+f(N-n2)+…+f(N-nk). So you just have to compute f(i) for i < nk and then you can easily compute f(n) with the formula (f(n),f(n+1),…,f(n+nk))=(f(0),f(1),…,f(nk))*A^n where A is the companion matrix of the sequence.

Resources