EDIT: mucho mejor de enfoque, consulte otra respuesta.
Confirmando sus valores (hasta 8) - con un enfoque diferente, que también debe permitir una más ingenioso método de conteo.
Siguiente programa de necesidades < 30 min (en un núcleo) para imprimir
(1,1)
(2,3)
(3,15)
(4,111)
(5,1119)
(6,14487)
(7,230943)
(8,4395855)
Podemos enumerar canónica de los representantes de estos Dag. Un representante es una lista de pares de números, por ejemplo, [(4,3),(3,2),(1,0),(1,1),(0,0)]
. Esto significa que el nodo superior (5) ha dejado niño 4, niño correcto 3, el nodo 4 tiene hijos (3,2), etc., hacia el nodo 1 con los niños (0,0).
El representante canónico si
- todas las parejas son diferentes
- cada nodo (excepto la primera) está vinculado de algún lugar por encima de
- para cada nivel (la distancia de la hoja), las parejas de este nivel son monótonas.
Por ejemplo, el nivel de asignación de es [(0,0),(1,1),(2,2),(3,2),(4,3),(5,4)
, lo [(1,0),(1,1)]
están en el mismo nivel, y esta lista es monótono.
Ahora, en lugar de generar-y-prueba (lo que hace el programa), se debe codificar estas condiciones en la lógica proposicional, y el uso de BDDs para contar.
(EDICIÓN de aquí, el programa original de abajo)
Con un poco de mejora de la representación interna, mi programa (ahora demasiado tiempo para publicar aquí, tal vez puedo jugar código de golf más tarde) dice a9 = 97608831
Me pregunto si podemos usar la siguiente: $a[x_k,..,x_0] =$ el número de dags con $x_h$ nodos en el nivel $h$. (E. g., $a[1,2,1,1]=6$). Aquí está la lista (por $\sum x_i=9$, le llaman a esto "8 nodos" ya que no se tienen en cuenta la hoja)
([1,1,1,1,1,1,1,1,1],2027025)
([1,1,1,1,1,2,1,1],424710)
([1,1,1,1,2,1,1,1],489060)
([1,1,1,1,3,1,1],9108)
([1,1,1,2,1,1,1,1],417690)
([1,1,1,2,2,1,1],208428)
([1,1,1,3,1,1,1],14400)
([1,1,2,1,1,1,1,1],279720)
([1,1,2,1,2,1,1],56844)
([1,1,2,2,1,1,1],188280)
([1,1,2,3,1,1],4764)
([1,1,3,1,1,1,1],6300)
([1,1,3,2,1,1],7200)
([1,2,1,1,1,1,1,1],103950)
([1,2,1,1,2,1,1],20520)
([1,2,1,2,1,1,1],22560)
([1,2,1,3,1,1],348)
([1,2,2,1,1,1,1],74340)
([1,2,2,2,1,1],37368)
([1,2,3,1,1,1],3240)
¿Hay alguna relación que permita calcular estos números, sin mirar ningún árboles, gráficos, dag? Algunas observaciones:
- $a[1,\dots,1]$ $(2k-1)!!$
- y los otros son aún (por lo que debe ser capaz de acelerar la enumeración 2)?
fuente original de código siguiente:
import qualified Data.Set as S
import qualified Data.Map.Strict as M
import Data.List ( sort )
import Control.Monad ( guard, when, forM_ )
import Control.Applicative
import System.IO
main = forM_ [1 .. ] $ \ n -> do
print (n, length $ filter dag_ok $ candidates n )
hFlush stdout
type DAG = [(Int,Int)]
dag_ok :: DAG -> Bool
dag_ok dag =
nodes_different dag && nodes_linked dag && levels_ok dag
nodes_different dag =
length dag == S.size (S.fromList dag)
nodes_linked dag =
S.fromList [0 .. length dag-1]
== S.fromList (do (x,y) <- dag ; [x, y] )
levels_ok dag =
let n = length dag ; m = levels dag
s = M.fromListWith S.union $ do (p,h) <- M.toList m ; return (h, S.singleton p)
in weakly_monotone ( map snd $ M.toAscList m )
&& and ( do
( h, ps ) <- M.toList s
return $ monotone $ do p <- S.toDescList ps ; return $ dag !! (n-p)
)
monotone xs = and $ zipWith (<) xs $ tail xs
weakly_monotone xs = and $ zipWith (<=) xs $ tail xs
levels [] = M.fromList [(0,0)]
levels ((x,y):d) =
let m = levels d
in M.insert (length d+1) (succ $ max ( m M.! x) (m M.! y)) m
candidates 0 = [ []]
candidates n = do
d <- candidates (n-1)
x <- [ 0 .. n-1] ; y <- [ 0 .. n-1]
return ((x,y):d)