Обчисліть кількість топологій на {1,2,…, n}


9

Завдання

Напишіть функцію / програму, яка приймає nза параметр / вхід і друкує / повертає кількість топологій (що показано нижче) на наборі {1,2,...,n}.

Визначення топології

Нехай X - будь-яке кінцеве безліч, і припустимо, що T, що є підмножиною набору потужностей X (тобто множина, що містить підмножини X), відповідає цим умовам :

  1. X і порожній набір - у Т.

  2. Якщо два множини U і V знаходяться в T, то об'єднання цих двох множин знаходиться в T.

  3. Якщо два множини U і V знаходяться в T, то перетин цих двох множин знаходиться в T.

... тоді T називається топологією на X.

Технічні умови

  1. Ваша програма:

    • функція, яка приймається nяк параметр
    • або програма, яка вводить n

    і друкує або повертає кількість (різних) топологій на наборі {1,2,...,n}.

  2. n - це будь-яке невід'ємне ціле число, яке менше 11 (звичайно, немає жодної проблеми, якщо ваша програма обробляє n більше 11), а вихід - ціле додатне число.

  3. Ваша програма не повинна використовувати будь-які види бібліотечних функцій або нативних функцій, які безпосередньо обчислюють кількість топології.

Приклад введення (значення n): 7

Приклад виведення / повернення: 9535241

Ви можете перевірити свою повернуту вартість тут або тут .

Звичайно, виграє найкоротший код.


Переможець вирішений, однак я можу змінити переможця, якщо з'явиться коротший код.


Чи має воно давати результати в цьому столітті, чи це досить хороший доказ коректності?
Пітер Тейлор

@Peter Насправді я не маю уявлення, скільки часу це займе. Тому доказ коректності програми достатньо хороший, але все ж програма повинна дати результат у розумний час, якщо n невелике, як 4 ~ 5.
JiminP

@JiminP, здається, що обчислення його для n = 12 коштувало паперу ще за той день, і не існує відомої формули. Для 4 або 5 я підозрюю, що це можливо зробити за кілька хвилин грубою силою.
Пітер Тейлор

Чи неправильна підмножина 2 ^ X також є топологією?
FUZxxl

@FUZxxl: Так. Я думаю, що це називається дискретною топологією .
JiminP

Відповіді:


4

Хаскелл, 144 символи

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]

Практично пряма реалізація специфікації, модуль якоїсь монадійної магії.

Надзвичайно повільно для n > 4.


5

Пітон, 147 символів

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

Швидкий для N <= 6, повільний для N = 7, навряд чи N> = 8 коли-небудь завершиться.

Окремі набори представлені цілими бітовими масками, а топології наборами бітових масок. S(i,K)обчислює кількість різних топологій, які ви можете сформувати, починаючи з Kі додаючи набори з бітовими масками> = i.


0

Зш, 83 символи

Це рішення відповідає листу ваших вимог (але, звичайно, не духу). Існує, безсумнівно, спосіб ще більше стиснути числа.

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

-1

Пітон, 131 чол

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

Розширена версія:

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

Наприклад, припустимо, що n = 3. Можливі підмножини [n] є

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

де i-й біт вказує, чи є я в підмножині. Для кодування наборів підмножин ми помічаємо, що кожна з цих підмножин або належить, або не належить до відповідного набору. Так, наприклад,

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

вказує, що x містить {}, {2} і {1,2,3}.


Чи можете ви пояснити, як це працює?
Спеціальний мисливець на Гарф на

@AdHocGarfHunter Додано розширену версію.
користувач76284
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.