[Jprogramming] Greatest Increasing Subsequence
'Mike Day' via Programming
programming at jsoftware.com
Wed Sep 14 21:27:05 UTC 2016
I suspect it's pretty near optimal. The wikipedia article points at
Fredman's paper:
http://www.sciencedirect.com/science/article/pii/0012365X7590103X
analysing an algorithm of Knuth's. He shows that it performs better than
n log2(n) - n log2 log2 (n) + O(n)
rather than the O(n logn) cited for the function we've been looking at.
I might have a play at tacit for the algorithm already discussed.
Mike
On 14/09/2016 14:57, Erling Hellenäs wrote:
> Any ideas about how you could make a substantially faster tacit
> solution to this problem or how you could make this solution
> substantially faster? /Erling
>
>
> On 2016-09-13 18:17, Erling Hellenäs wrote:
>> Hi all !
>>
>> My first idea only took me down to 1 second for 10 000 numbers, 25
>> times longer than longscseq. I then made a tacit version of
>> longascseq. It still takes about 4 times longer than longascseq.
>>
>> See these two versions below.
>>
>> I included the full project of the tacit version.
>>
>> Cheers,
>>
>> Erling
>>
>> NB. Find the longest stricty increasing subsequence
>>
>> NB. Values are the lowest last values yet found for each subsequence
>> length.
>>
>> NB. Indices are the indices of these values in the original sequence.
>>
>> NB. Predecessors are indices to the end of the next lower subsequence
>>
>> NB. for each value in the original sequence.
>>
>> NB. The longest sequence is found by index lookup in predecessors
>> from the index
>>
>> NB. of the highest found value.
>>
>>
>> Amend=:([:>[:{.[)`([:>[:{:[)`] }
>>
>> PickPower=: {~^:([`([:>[:{.])`([:>[:{:]))
>>
>> ValuesIndicesPredecessorsIndexInitialState=: [: < a:"_ , a:"_ , (([:
>> # ]) $2:) ;0:
>>
>> PackValues=: <@+
>>
>> Values=: [: > 0 { ]
>>
>> Indices=: [: > 1 { ]
>>
>> Predecessors=: [: > 2 { ]
>>
>> Index=: [: > 3 { ]
>>
>> AdjustLength=: ((1 + [) >. [: # ]) {. ]
>>
>> AmendValues=: (([: {. [) ; [: {: [) Amend ([: {: [) AdjustLength Values
>>
>> AmendIndices=: (Index ; [: {: [) Amend ([: {: [) AdjustLength Indices
>>
>> AmendPredecessors=: ((([: <: [: {: [){Indices);Index ) Amend
>> Predecessors
>>
>> DoBetweenElementsInFold=: ([,(Values I. [ )) ( [
>> (Values;Indices;AmendPredecessors;1+Index)
>> AmendValues;AmendIndices;Predecessors;Index) ]
>>
>> Reconstruct=: [: (Predecessors PickPower ([: i. [: - [: # Indices);[:
>> {: Indices) [: > ]
>>
>> LongestIncreasingSubsequenceIndices=: [: Reconstruct [:
>> DoBetweenElementsInFold&.:>/ ([: |. PackValues) ,
>> ValuesIndicesPredecessorsIndexInitialState
>>
>> LongestIncreasingSubsequence=: ([:
>> LongestIncreasingSubsequenceIndices ]){ ]
>>
>> LongestIncreasingSubsequence=: LongestIncreasingSubsequence f.
>>
>> NB. This is a solution to the problem of finding the longest strictly
>> increasing subsequence.
>>
>> NB. Draws numbers from the end of the sequence. Selects groups with
>> its first element larger
>>
>> NB. than the drawn element. Selects one of the longest of these
>> groups if one exists and prepends
>>
>> NB. the drawn number. If no such group exists create a new group
>> containing the drawn number.
>>
>> NB. Removes groups which are both shorter than the new group or of
>> equal length and which starts
>>
>> NB. with a number which is smaller or equal to the number which
>> starts the new group.
>>
>> NB. Append the new group to the remaining groups.
>>
>> NB. When all numbers are drawn one of the longest remaining groups is
>> selected.
>>
>>
>> GroupOfEmptyGroupInitialState=: [: < a:"_
>>
>> PackElements=: <@+
>>
>> StartsWithLonger=: ([: {.@> [) < [: {.@> ]
>>
>> Longer=:([: #@> [) < [: #@> ]
>>
>> SelectLongerOrStartsWithLonger=: (Longer +. StartsWithLonger ) # ]
>>
>> SelectGroupsWithLeftLessThanFirstElement=: ([ < [: {.@> ]) # ]
>>
>> SelectFirstGroupOfMaxLength=: ((1 <. [: # ]) {. [: I. [: (] = [: >./
>> ]) #@>) { ]
>>
>> PrependLeftInGroups=: ([: < [) ,&.> ]
>>
>> AddGroupWithLeftIfNoGroups=: ((0 = [: # ]) {. [: < [) , ]
>>
>> DoBetweenElementsInFold=: ([: {. [ AddGroupWithLeftIfNoGroups [
>> PrependLeftInGroups [: SelectFirstGroupOfMaxLength
>> SelectGroupsWithLeftLessThanFirstElement ) ([ ,
>> SelectLongerOrStartsWithLonger) ]
>>
>> LongestIncreasingSubsequence=: [: ; [: SelectFirstGroupOfMaxLength [:
>> > [: DoBetweenElementsInFold&.:>/ PackElements ,
>> GroupOfEmptyGroupInitialState
>>
>> LongestIncreasingSubsequence=: LongestIncreasingSubsequence f.
>>
>>
>> Full project of tacit version
>>
>> =======================
>>
>>
>> NB. Find the longest stricty increasing subsequence
>>
>> NB. Values are the lowest last values yet found for each subsequence
>> length.
>>
>> NB. Indices are the indices of these values in the original sequence.
>>
>> NB. Predecessors are indices to the end of the next lower subsequence
>>
>> NB. for each value in the original sequence.
>>
>> NB. The longest sequence is found by index lookup in predecessors
>> from the index
>>
>> NB. of the highest found value.
>>
>>
>> ts=: 6!:2 , 7!:2@] NB. Time and space
>>
>> Amend=:([:>[:{.[)`([:>[:{:[)`] }
>>
>> (1;0) Amend 3 4 5
>>
>> PickPower=: {~^:([`([:>[:{.])`([:>[:{:]))
>>
>> 2 3 4 PickPower 1;1
>>
>> ValuesIndicesPredecessorsIndexInitialState=: [: < a:"_ , a:"_ , (([:
>> # ]) $2:) ;0:
>>
>> ValuesIndicesPredecessorsIndexInitialState 7 1 2 3
>>
>> PackValues=: <@+
>>
>> PackValues 7 1 2 3
>>
>> Values=: [: > 0 { ]
>>
>> Values 1 2 3;0 1 2;2 2 2;0
>>
>> Indices=: [: > 1 { ]
>>
>> Indices 1 2 3;0 1 2;2 2 2;0
>>
>> Predecessors=: [: > 2 { ]
>>
>> Predecessors 1 2 3;0 1 2;2 2 2;0
>>
>> Index=: [: > 3 { ]
>>
>> Index 1 2 3;0 1 2;2 2 2;0
>>
>> AdjustLength=: ((1 + [) >. [: # ]) {. ]
>>
>> 3 AdjustLength 1 2 3
>>
>> 2 AdjustLength 1 2 3
>>
>> AmendValues=: (([: {. [) ; [: {: [) Amend ([: {: [) AdjustLength Values
>>
>> (7,3) AmendValues 1 2 3;0 1 2;2 2 2;0
>>
>> AmendIndices=: (Index ; [: {: [) Amend ([: {: [) AdjustLength Indices
>>
>> (7,3) AmendIndices 1 2 3;0 1 2;2 2 2;0
>>
>> AmendPredecessors=: ((([: <: [: {: [){Indices);Index ) Amend
>> Predecessors
>>
>> (7,3) AmendPredecessors 1 2 3;0 1 2;2 2 2;0
>>
>> DoBetweenElementsInFold=: ([,(Values I. [ )) ( [
>> (Values;Indices;AmendPredecessors;1+Index)
>> AmendValues;AmendIndices;Predecessors;Index) ]
>>
>> 3 DoBetweenElementsInFold 1 2;1 2;0 1 1 2;3
>>
>> Reconstruct=: [: (Predecessors PickPower ([: i. [: - [: # Indices);[:
>> {: Indices) [: > ]
>>
>> Reconstruct < 1 2 3;1 2 3;0 1 1 2;4
>>
>> LongestIncreasingSubsequenceIndices=: [: Reconstruct [:
>> DoBetweenElementsInFold&.:>/ ([: |. PackValues) ,
>> ValuesIndicesPredecessorsIndexInitialState
>>
>> ( 7 DoBetweenElementsInFold [: >
>> ValuesIndicesPredecessorsIndexInitialState)7 1 2 3
>>
>> ( 1 DoBetweenElementsInFold (7 DoBetweenElementsInFold [: >
>> ValuesIndicesPredecessorsIndexInitialState))7 1 2 3
>>
>> ( 2 DoBetweenElementsInFold (1 DoBetweenElementsInFold (7
>> DoBetweenElementsInFold [: >
>> ValuesIndicesPredecessorsIndexInitialState)))7 1 2 3
>>
>> ( 3 DoBetweenElementsInFold (2 DoBetweenElementsInFold (1
>> DoBetweenElementsInFold (7 DoBetweenElementsInFold [: >
>> ValuesIndicesPredecessorsIndexInitialState))))7 1 2 3
>>
>> Reconstruct < (3 DoBetweenElementsInFold ( 2 DoBetweenElementsInFold
>> ( 1 DoBetweenElementsInFold ( 7 DoBetweenElementsInFold [: >
>> ValuesIndicesPredecessorsIndexInitialState))))7 1 2 3
>>
>> LongestIncreasingSubsequence=: ([:
>> LongestIncreasingSubsequenceIndices ]){ ]
>>
>> LongestIncreasingSubsequence=: LongestIncreasingSubsequence f.
>>
>> LongestIncreasingSubsequence 7 1 2 3
>>
>> LongestIncreasingSubsequence i.0
>>
>> LongestIncreasingSubsequence 6 1 3 4 2 8
>>
>> l =: 7 4 4 5 2 7 1 8 13 2 10 4 9 1 4 5 5 4 3 10 3 4 5 8 15 7 11 19
>>
>> LongestIncreasingSubsequence l
>>
>> 9!:1 [16807
>>
>> [a=:LongestIncreasingSubsequence 1000?1000
>>
>> #a
>>
>> 9!:1 [16807
>>
>> [a=:LongestIncreasingSubsequence ?1000$1000
>>
>> #a
>>
>> ts=: 6!:2 , 7!:2@] NB. Time and space
>>
>> ts'LongestIncreasingSubsequence 10000?10000'
>>
>> ts'LongestIncreasingSubsequence ?10000$10000'
>>
>>
>> ----------------------------------------------------------------------
>> For information about J forums see http://www.jsoftware.com/forums.htm
>
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
More information about the Programming
mailing list