Thanks Jon

lisM isn't really "my" version - I was just translating the pseudo-code...
I expect -without checking! - that its advantage over lisl resides in avoiding 
the do-it-yourself binary search by using J's built-in dyadic I. , albeit at 
the expense of an explicit sorted array, which I called mx .   I tried limiting 
the I. search to only the first L items of mx,  but with no benefit,  at least 
for the sizes I tried.  
The time taken to recover the result is fairly trivial,  so I don't suppose my 
use of 
|. x{~(p{~])^:(i.L) L{m 
is particularly interesting,  but it avoided that explicit while loop.

Mike

Please reply to mike_liz....@tiscali.co.uk.      
Sent from my iPad

> On 5 Sep 2016, at 08:07, 'Jon Hough' via Programming 
> <programm...@jsoftware.com> wrote:
> 
> Just out of interest, I compared the various results. 
> I wrote a fully imperative version, which uses in-place modification of the 
> results array.
> 
> I also wrote a version that avoids any while / for loops (because I wanted to 
> avoid using them), and ended up putting
> most of the logic in anonymous verbs. Which is probably a big mistake because 
> that gets very slow. Also barely readable.
> 
> NB.===========================================================================
> 
> NB. Jon - bizarre version. Uses anonymous verbs for most of the logic. 
> NB. Slow and, uses huge amounts of memory.
> appendOrInsert=:(3 : 'insert max' [ 3 : 
> '(max=:<:#lst)[(min=:0)[val=:i{r[i=:y')`(3 : '(lst=:lst,y)[prev=:(_1{lst) y} 
> prev')@.(3 : '(val>({:lst){r)[val=:y{r')
> insert=:(3 : '(prev=: ((y-1){lst)i}prev)[(lst=: i y }lst)' ] ])@:(3 : 
> 'mid'`(3 : 'min=: mid+1')@.(3 : 
> '(val>(mid{lst){r)[(mid=:<.(min+y)%2)')^:(0&<)^:_)
> 
> lisJ =: 3 : 0
> r=:y              NB. array
> [val=:0[max=:0[mid=:0[min=:0  NB. useful numbers
> lst=:0            NB. list of indices
> prev=: (#y)#0        NB. previous indices
> i=:0            NB. current index
> 
> appendOrInsert"0 >: i.<: # y    NB. append the items, or insert them, into 
> lst (and update prev)
> res=:''
> ptr=: _1{lst
> (ptr&buildEx)^:(#lst) res
> |. res
> )
> 
> buildEx =: 4 : 0
> res=:y,ptr{r
> ptr=: ptr{prev
> res
> )
> 
> 
> NB.===========================================================================
> 
> 
> NB. Imperative version. just for benchmarking
> lisI =: 3 : 0
> lst =: 0
> r=: y
> parent=: (#y)#0
> for_i.>:i.<:# r do.
> if.((i{r) > ({: lst){r )  do.
> parent=:(_1{lst) i}parent
> lst =: lst, i
> else.
> min=: 0
> max =: <:#lst
> while. min < max do.
> mid =: <. (min + max) % 2
> if. (i{r) > ((mid { lst{r)) do. min =: mid + 1
> else. max =: mid end.
> end.
> lst=: (i) max} lst
> parent=: ((max-1){lst)(i}) parent
> end.
> end.
> res=: ''
> ptr=: _1{lst
> while. (# res) < # lst do.
> res=:res,ptr{r
> ptr=:ptr{parent
> end.
> I. res
> )
> 
> 
> 
> NB.===========================================================================
> 
> 
> NB. Mike's version. 
> 
> lisM =: 3 : 0
> n       =. #x   =. y
> if. 2>#x do. x return. end.       NB. special case empty or singleton array
> if. (-:/:~)x do. ~.x return. end. NB. special case sorted arrays
> if. (-:\:~)x do. {.x return. end.
> p       =. n#0
> NB. seed m with trailing _1 so that final L (as in wiki algorithm) can be 
> found
> m       =. n 0 } _1#~>:n
> NB. set up sorted mx, with just the first element of x, so that I. works
> mx      =. ({.x) 1 } (<:<./x), n#>:>./x
> for_i. i.n do.
>   xi    =. i{x
>   lo    =. mx I. xi
>   p     =. (m{~<:lo) i } p NB. better than appending to short p for larger x
>   m     =. i  lo } m
>   mx    =. xi lo } mx
> end.
> |. x{~(p{~])^:(i.L) m{~ L =. <: m i. _1
> )
> 
> NB.===========================================================================
> 
> NB. Louis' version.
> p=: ] , [ ,&.> ] #~ (< {.&>) (= >./)@:* #&>@]
> e=: }:@>@(#~ (= >./)@:(#&>))@>
> 
> s=: [: e (<<_) p&.>/@,~ <"0
> pi=: ] , [ ,&.> ] {~ (< {.&>) (i. >./)@:* #&>@]
> lisL =: [: e (<<_) pi&.>/@,~ <"0                                      NB. 
> <------------- this one.
> 
> f=: ((] >: (-~ >./)) #&>) # ]
> 
> P=: ] , [ ,&.> ] #~ (< {.&>) (,@[ #^:_1 (= >./)@#) #&>@]
> sp=: [: e (<<_) ({:@[ f {.@[ P ])&.>/@,~ (,&.> i.@#)
> 
> 
> 
> NB.===========================================================================
> 
> 
> NB. Xiao's version with Raul's modifications. Renamed verbs to avoid clashing.
> 
> NB. dyads
>   exr=:  (1 + {:@[ < ]) {. [ ; ,
>   hxr=:  [: ; exr&.>
> 
> NB. monads
>   gxr=: (}.@] ;~ {.@] ; (hxr {.))&>/
>   cxr=: ({::~ [: (i. >./) #@>)@>@{.
>   dxr=: (<_) ; ]
>   lisXR=: ([: cxr gxr^:(#@(>@{:)))@dxr
> 
> NB.===========================================================================
> 
> a=: 25 ? 25
> timespacex 'lisI a'
> timespacex 'lisJ a'
> timespacex 'lisM a'
> timespacex 'lisL a'
> timespacex 'lisXR a' NB. comment out for larger arrays,a.
> 
> Playing around with various arrays, it seems lisM is the most efficient in 
> time and space (more than the imperative version).
> lisM and lisI can handle array larger than 10000. The others struggle or give 
> up with them. 
> 
> 
> --------------------------------------------
> On Sun, 9/4/16, 'Mike Day' via Programming <programm...@jsoftware.com> wrote:
> 
> Subject: Re: [Jprogramming] Greatest Increasing Subsequence
> To: programm...@jsoftware.com
> Date: Sunday, September 4, 2016, 4:30 AM
> 
> This version of
> "lis" is a bit more J-like,  especially in using
> dyadic I.
> instead of the diy binary search,
> at the expense of a slightly more
> complicated set-up for the m and mx arrays.
> 
> lis =: 3 : 0
> n       =. #x   =. y
> if. 2>#x do. x return. end.   
>    NB. special case empty or singleton array
> if. (-:/:~)x do. ~.x return. end. NB. special
> case sorted arrays
> if. (-:\:~)x do. {.x
> return. end.
> p       =. n#0
> NB. seed m with trailing _1 so that final L (as
> in wiki algorithm) can 
> be found
> m       =. n 0 } _1#~>:n
> NB. set up sorted mx, with just the first
> element of x, so that I. works
> mx      =.
> ({.x) 1 } (<:<./x), n#>:>./x
> for_i. i.n do.
>     xi    =.
> i{x
>     lo    =. mx I. xi
>     p     =. (m{~<:lo) i } p
> NB. better than appending to short p for 
> larger x
>     m 
>    =. i  lo } m
>     mx    =.
> xi lo } mx
> end.
> |.
> x{~(p{~])^:(i.L) m{~ L =. <: m i. _1
> )
> 
> Mike
> 
> 
> On 02/09/2016 20:45, 'Mike
> Day' via Programming wrote:
>> Well,
> assuming for now that it does work,  here's an attempt
> at a J 
>> version of
> the pseudo-code listed at
>> https://en.wikipedia.org/wiki/Longest_increasing_subsequence#Efficient_algorithms
> 
>> 
>> 
>> lis =: 3 : 0   NB. longest
> increasing subsequence
>> m   
>    =. 0#~>:n   =.
> #x   =. y
>> L   
>    =. #p       =. ''
>> mx      =. m{x NB. added this vector
> for better look-up of x{~mid{m
>> for_i.
> i.n do.
>>    'lo hi' =.
> 1, L
>>     xi     =. i{x
>>     while. lo <: hi do.
>>        mid    =. >.@-: lo + hi
> NB.       if. xi > x{~ mid{m do. NB. next
> line a bit better
>    if. xi > mid{mx do.
>         lo =. >: mid
>    else.
>>           hi =.
> <: mid
>>        end.
>>     end.
>>     p 
>    =. p, m{~<:lo
>>     m 
>    =. i  lo } m
>>     mx 
>   =. xi lo } mx    NB. update my additional array
>>     L     =. L >. lo
>> NB. smoutput i; (x{.~ >:i);
> L{.m   NB. diagnostic
> end.
>> |. x{~(p{~])^:(i.L) L{m
>> )
>> 
>> It's reasonably fast on ?10000#5000 -
> but possibly wrong!It does
>> fail on an
> empty array.
> Mike
>> 
>> 
>>> On 02/09/2016 17:30, Raul Miller wrote:
>>> It seems to me that the
> "efficient algorithm" documented on the
>>> wikipedia page would have an analogous
> flaw. It is performing binary
> searches on unsorted lists. That said, it does perform
> correctly for
>>> this example.
>>> 
>>> Thanks,
>> 
>> 
>> ---
>> This email has been checked for viruses by
> Avast antivirus software.
>> https://www.avast.com/antivirus
> ----------------------------------------------------------------------
>> 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
> 
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to