Calculer le nombre de topologies sur {1,2,…, n}

9

Tâche

Écrivez une fonction / un programme qui prend ncomme paramètre / entrée et imprime / renvoie le nombre de topologies (qui est illustré ci-dessous) sur l'ensemble {1,2,...,n}.

Définition de la topologie

Soit X tout ensemble fini, et supposons que T, qui est un sous-ensemble de l'ensemble de puissance de X (c'est-à-dire un ensemble contenant des sous-ensembles de X), remplit ces conditions :

  1. X et l' ensemble vide sont en T.

  2. Si deux ensembles U et V sont en T, alors l' union de ces deux ensembles est en T.

  3. Si deux ensembles U et V sont en T, alors l' intersection de ces deux ensembles est en T.

... alors T est appelé la topologie sur X.

Caractéristiques

  1. Votre programme est soit:

    • une fonction qui prend ncomme paramètre
    • ou un programme qui saisit n

    et imprime ou renvoie le nombre de topologies (distinctes) sur l'ensemble {1,2,...,n}.

  2. n est un entier non négatif inférieur à 11 (bien sûr, il n'y a pas de problème si votre programme gère n supérieur à 11), et la sortie est un entier positif.

  3. Votre programme ne doit utiliser aucun type de fonctions de bibliothèque ou de fonctions natives qui calcule directement le nombre de topologies.

Exemple d'entrée (valeur de n): 7

Exemple de sortie / retour: 9535241

Vous pouvez vérifier votre valeur de retour ici ou ici .

Bien sûr, le code le plus court gagne.


Le gagnant est décidé, cependant, je peux le changer si un code plus court apparaît.

JiminP
la source
Doit-elle donner des résultats ce siècle, ou une preuve de correction est-elle suffisante?
Peter Taylor
@Peter En fait, je n'ai aucune idée du temps que cela prendra. Par conséquent, la preuve de l'exactitude du programme est assez bonne, mais le programme devrait quand même donner un résultat dans un délai raisonnable si n est petit, comme 4 ~ 5.
JiminP
@JiminP, il semble que le calculer pour n = 12 valait un papier dans la journée, et il n'y a pas de formule connue. Pour 4 ou 5 je soupçonne que c'est faisable en quelques minutes par la force brute.
Peter Taylor
Le sous-ensemble incorrect de 2 ^ X est-il également une topologie?
FUZxxl
@FUZxxl: Oui. Je pense que cela s'appelle la topologie discrète .
JiminP

Réponses:

4

Haskell, 144 caractères

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]

Presque une implémentation directe de la spécification, modulo un peu de magie monade.

Extrêmement lent pour n > 4.

hammar
la source
5

Python, 147 caractères

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

Rapide pour N <= 6, lent pour N = 7, improbable N> = 8 ne sera jamais terminé.

Les ensembles individuels sont représentés par des masques de bits entiers et les topologies par des ensembles de masques de bits. S(i,K)calcule le nombre de topologies distinctes que vous pouvez former en commençant par Ket en ajoutant des ensembles avec des masques de bits> = i.

Keith Randall
la source
0

Zsh, 83 caractères

Cette solution correspond à la lettre de vos besoins (mais pas, bien sûr, à l'esprit). Il existe sans aucun doute un moyen de compresser encore plus les chiffres.

a=(0 3 S 9U 5CT 4HO6 5ODFS AMOZQ1 T27JJPQ 36K023FKI HW0NJPW01R);echo $[1+36#$a[$1]]
Gilles 'SO- arrête d'être méchant'
la source
-1

Python, 131 caractères

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

Version étendue:

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

Par exemple, supposons que n = 3. Les sous-ensembles possibles de [n] sont

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

où le ième bit indique si i est dans le sous-ensemble. Pour coder des ensembles de sous-ensembles, nous remarquons que chacun de ces sous-ensembles appartient ou n'appartient pas à l'ensemble en question. Ainsi, par exemple,

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

indique que x contient {}, {2} et {1,2,3}.

user76284
la source
Pourriez-vous expliquer comment cela fonctionne?
Ad Hoc Garf Hunter
@AdHocGarfHunter Ajout d'une version étendue.
user76284