Calcule el número de topologías en {1,2, ..., n}


9

Tarea

Escriba una función / programa que tome ncomo parámetro / entrada e imprima / devuelva el número de topologías (que se muestra a continuación) en el conjunto {1,2,...,n}.

Definición de topología

Sea X un conjunto finito y suponga que T, que es un subconjunto del conjunto de potencia de X (es decir, un conjunto que contiene subconjuntos de X), cumple estas condiciones :

  1. X y el conjunto vacío están en T.

  2. Si dos conjuntos U y V están en T, entonces la unión de esos dos conjuntos está en T.

  3. Si dos conjuntos U y V están en T, entonces la intersección de esos dos conjuntos está en T.

... entonces T se llama topología en X.

Especificaciones

  1. Tu programa es:

    • una función que toma ncomo parámetro
    • o un programa que ingresa n

    e imprime o devuelve el número de topologías (distintas) en el conjunto {1,2,...,n}.

  2. n es cualquier número entero no negativo que sea menor que 11 (por supuesto, no hay problema si su programa maneja n mayor que 11), y la salida es un número entero positivo.

  3. Su programa no debe usar ningún tipo de funciones de biblioteca o funciones nativas que calculen directamente el número de topología.

Entrada de ejemplo (valor de n): 7

Ejemplo de salida / retorno: 9535241

Puede verificar su valor de devolución aquí o aquí .

Por supuesto, el código más corto gana.


El ganador se decide, sin embargo, puedo cambiarlo si aparece un código más corto.


¿Tiene que dar resultados este siglo, o es una prueba de corrección lo suficientemente buena?
Peter Taylor

@ Peter De hecho, no tengo idea de cuánto tiempo llevará. Por lo tanto, la prueba de la corrección del programa es lo suficientemente buena, pero aún así el programa debería dar un resultado en un tiempo razonable si n es pequeño, como 4 ~ 5.
JiminP

@JiminP, parece que calcularlo para n = 12 valió la pena un trabajo en el pasado, y no hay una fórmula conocida. Para 4 o 5 sospecho que es factible en pocos minutos por la fuerza bruta.
Peter Taylor

¿El subconjunto incorrecto de 2 ^ X también es una topología?
FUZxxl

@FUZxxl: Sí. Creo que eso se llama topología discreta .
JiminP

Respuestas:


4

Haskell, 144 caracteres

import List
import Monad
p=filterM$const[True,False]
f n=sum[1|t<-p$p[1..n],let e=(`elem`t).sort,e[],e[1..n],all e$[union,intersect]`ap`t`ap`t]

Casi una implementación directa de la especificación, modulo algo de magia mónada.

Extremadamente lento para n > 4.


5

Python, 147 caracteres

N=input()
S=lambda i,K:1+sum(0if len(set(j&k for k in K)-K)-1 else S(j+1,K|set(j|k for k in K))for j in range(i,2**N))
print S(1,set([0,2**N-1]))

Rápido para N <= 6, lento para N = 7, improbable N> = 8 alguna vez se completará.

Los conjuntos individuales están representados por máscaras de bits enteras y las topologías por conjuntos de máscaras de bits. S(i,K)calcula el número de topologías distintas que puede formar al comenzar Ky agregar conjuntos con máscaras de bits> = i.


0

Zsh, 83 caracteres

Esta solución coincide con la letra de sus requisitos (pero no, por supuesto, el espíritu). Sin duda, hay una manera de comprimir los números aún más.

a=(0 3 S 9U 5CT 4HO6 5ODFS AMOZQ1 T27JJPQ 36K023FKI HW0NJPW01R);echo $[1+36#$a[$1]]

-1

Python, 131 caracteres

lambda n:sum(x&(x>>2**n-1)&all((~(x>>i&x>>j)|x>>(i|j)&x>>(i&j))&1 for i in range(2**n)for j in range(2**n))for x in range(2**2**n))

Versión ampliada:

def f(n):
    count = 0
    for x in range(2**2**n): # for every set x of subsets of [n] = {1,...,n}
        try:
            assert x & 1 # {} is in x
            assert (x >> 2 ** n - 1) & 1 # [n] is in x
            for i in range(2**n): # for every subset i of [n]...
                if x >> i & 1: # ...in x
                    for j in range(2**n): # for every subset j of [n]...
                        if x >> j & 1: # ...in x
                            assert (x >> (i | j)) & 1 # their union is in x
                            assert (x >> (i & j)) & 1 # their intersection is in x
            count += 1
        except AssertionError:
            pass
    return count

Por ejemplo, supongamos que n = 3. Los subconjuntos posibles de [n] son

0b000
0b001
0b010
0b011
0b100
0b101
0b110
0b111

donde el bit iésimo indica si estoy en el subconjunto. Para codificar conjuntos de subconjuntos, notamos que cada uno de estos subconjuntos pertenece o no al conjunto en cuestión. Así, por ejemplo,

x = 0b10100001
0b000 # 1
0b001 # 0
0b010 # 1
0b011 # 0
0b100 # 0
0b101 # 0
0b110 # 0
0b111 # 1

indica que x contiene {}, {2} y {1,2,3}.


¿Podría explicar cómo funciona esto?
Ad Hoc Garf Hunter

@AdHocGarfHunter Se agregó una versión ampliada.
user76284
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.