Calcola il numero di topologie su {1,2,…, n}


9

Compito

Scrivi una funzione / programma che accetta ncome parametro / input e stampa / restituisce il numero di topologie (che è mostrato di seguito) sul set {1,2,...,n}.

Definizione di topologia

Sia X qualsiasi insieme finito, e supponiamo che T, che è un sottoinsieme del gruppo di potenza di X (cioè un insieme contenente sottoinsiemi di X), soddisfi queste condizioni :

  1. X e il set vuoto sono in T.

  2. Se due insiemi U e V sono in T, allora l' unione di questi due insiemi è in T.

  3. Se due insiemi U e V sono in T, allora l' intersezione di questi due insiemi è in T.

... quindi T viene chiamata topologia su X.

specificazioni

  1. Il tuo programma è:

    • una funzione che accetta ncome parametro
    • o un programma che inserisce n

    e stampa o restituisce il numero di topologie (distinte) sul set {1,2,...,n}.

  2. n è un numero intero non negativo che è inferiore a 11 (ovviamente non ci sono problemi se il programma gestisce n maggiore di 11) e l'output è un numero intero positivo.

  3. Il programma non deve utilizzare alcun tipo di funzioni di libreria o funzioni native che calcolano direttamente il numero di topologia.

Esempio di input (valore di n): 7

Esempio di output / return: 9535241

Puoi controllare il tuo valore di ritorno qui o qui .

Naturalmente vince il codice più corto.


Il vincitore è deciso, tuttavia, posso cambiare il vincitore se appare un codice più corto.


Deve dare risultati in questo secolo o una prova di correttezza è abbastanza buona?
Peter Taylor,

@Peter In effetti, non ho idea di quanto tempo ci vorrà. Pertanto la prova della correttezza del programma è abbastanza buona, ma il programma dovrebbe comunque dare un risultato in un tempo ragionevole se n è piccolo, come 4 ~ 5.
JiminP

@JiminP, sembra che calcolarlo per n = 12 sia valso un foglio indietro nel corso della giornata e non esiste una formula nota. Per 4 o 5 sospetto che sia fattibile in pochi minuti con la forza bruta.
Peter Taylor,

Anche il sottoinsieme improprio di 2 ^ X è una topologia?
FUZxxl,

@FUZxxl: Sì. Penso che si chiama topologia discreta .
JiminP

Risposte:


4

Haskell, 144 caratteri

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]

Quasi un'implementazione diretta delle specifiche, modulo qualche magia monade.

Estremamente lento per n > 4.


5

Python, 147 caratteri

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]))

Rapido per N <= 6, lento per N = 7, improbabile N> = 8 verrà mai completato.

I singoli insiemi sono rappresentati da maschere di bit intere e le topologie da insiemi di maschere di bit. S(i,K)calcola il numero di topologie distinte che è possibile formare iniziando con Ke aggiungendo set con maschere di bit> = i.


0

Zsh, 83 caratteri

Questa soluzione corrisponde alla lettera delle tue esigenze (ma non, ovviamente, allo spirito). C'è senza dubbio un modo per comprimere ancora di più i numeri.

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

-1

Python, 131 caratteri

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))

Versione estesa:

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

Ad esempio, supponiamo che n = 3. I possibili sottoinsiemi di [n] sono

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

dove il bit ith indica se sono nel sottoinsieme. Per codificare insiemi di sottoinsiemi, notiamo che ciascuno di questi sottoinsiemi appartiene o non appartiene all'insieme in questione. Pertanto, ad esempio,

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

indica che x contiene {}, {2} e {1,2,3}.


Potresti spiegare come funziona?
Ad Hoc Garf Hunter,

@AdHocGarfHunter Aggiunta una versione estesa.
user76284,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.