Not very sophisticated, and the first verb (wrapa) below doesn't even reproduce your answer for N=6 , but it might be a starting point for further work. The second verb (wrapb) does work for N=6, but apparently greatly overestimates the number for your larger 2000 node graph!

wrapa=: 1 : 0
:
g =. <: > >:@I.each <"1 m NB. unboxed list of bnodes for each anode, with _1 as filler
  p =. 1 1 $ y                NB. initial path matrix
  N =. x
while. N =.<: N do.
  from =. {:"1 p               NB. anodes of current path-ends
  to   =. from{g               NB. bnodes for each anode
  nto  =. +/"1 to >_1          NB. count number of bnodes for each anode
  p    =. nto#p                NB. expand rows of path matrix
  p    =. p,. _1 -.~,to        NB. append new path-ends
  p    =. ~.p                  NB. remove repeats
  p    =. (#~ {:@$ = #@~."1) p NB. exclude paths with repeated nodes
end.
p
)

   [w6=:I."1]6 graph wrap 0   NB. original
0 4  6 14 15 16
0 4  6 14 15 18
0 6  7 14 15 16
0 6  8 14 15 16
0 6 12 14 15 16
0 6 14 15 16 18
0 3  6 14 15 18

   [w6a=:/:~ 6 graph wrapa 0 NB. new
0 14 15 6 16  7
0 14 15 6 16  8
0 14 15 6 16 12
0 14 15 6 18  3

   w6 -. /:~"1 w6a  NB. paths missed by new approach
0 4  6 14 15 16
0 4  6 14 15 18
0 6 14 15 16 18

I don't see how these are "paths", and so I'm probably missing something that you require.

However, this verb does yield the same results for N=6; the paths seem to be trees:

wrapb=: 1 : 0
:
g =. <: > >:@I.each <"1 m NB. unboxed list of bnodes for each anode, with _1 as filler
  p =. 1 1 $ y                NB. initial path matrix
  N =. x
while. N =.<: N do.
  from =. p                    NB. all anodes of current paths
  to   =. from{g               NB. bnodes for each anode
  nto  =. +/"1^:2 to >_1       NB. count number of bnodes for each anode
  p    =. nto#p                NB. expand rows of path matrix
  p    =. /:~"1 p,. _1 -.~,to  NB. append new bnodes and sort
  p    =. ~.p                  NB. remove repeats
  p    =. (#~ {:@$ = #@~."1) p NB. exclude paths with repeated nodes
end.
p
)

But now it produces too many "paths" in your larger example, albeit pretty fast:
   timer'#10 graph2 wrapb 0'  NB. apparently 12 times too many "paths"
+--------+-----+
|0.868896|72258|
+--------+-----+

("timer" is a variant of ts which shows time in seconds and the result)

wrapa is quicker but presumably wronger!

   timer'#10 graph2 wrapa 0'   NB. apparently 10 times too few "paths"
+---------+---+
|0.0170898|556|
+---------+---+

Anyway, I should think some variation on one of these verbs might scale better than the incidence matrix approach, and produce something like the results you need!

Mike

On 13/02/2013 9:38 PM, Raul Miller wrote:

Since I messed up the description, I'll just pose an example solution
and ask for improvements.

graph=: 1= ?.20 20$10

start=: ,:0=i.#graph

gather=: 1 :'[: ~.@; <@u'

wrap=: 1 :0
:
   graph=. m
   start=. ,:(i.#graph) e. y
   N=. x
   paths=. (+./ .* # (+."1 =@i.@#))&graph"1 gather^:(N-1) start
   (N=+/"1 paths)#paths
)

Here's a representation of the graph I'm using:
    #.graph
64 1536 4 72 3200 8224 296960 8225 65536 8192 32 524800 48 513 65 160
16416 32849 576 526466
    $#:#.graph
20 20

Here's a count of visitable sets of six nodes starting from node 0
    #6 graph wrap 0
17

In other words, wrap is an adverb which takes a graph and derives a
verb to generate the distinct visitable sets of length x starting from
the list of nodes indexed by the right argument.

Now, let's say that we wanted to scale this up to deal with a couple
thousand nodes (but with similar connectivity):
   graph2=: 1=?.2000 2000$1000

Here, the algorithm I implemented starts getting slow when I look for
paths of length 100 (it's just under 6000 paths).

    #10 graph2 wrap 0
5945

    ts '#10 graph2 wrap 0'
13.7496 4.34907e8

That's a bit slow. Now let's imagine that I'm interested in finding
this path count for paths of length 100, in a reasonable amount of
time (let's say "less than a minute" for the sake of argument).  In
this case, I believe that my reference implementation can only serve
as an example.

Better?

Thanks,

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

Reply via email to