Как я могу реализовать класс бесконечного множества?

Я разрабатываю библиотеку классов для дискретной математики и не могу придумать, как реализовать бесконечный набор .

Что у меня есть до сих пор: у меня есть абстрактный базовый класс Set, который реализует интерфейс ISet. Для конечных наборов я создаю класс FiniteSet, который реализует каждый метод набора. Затем я могу использовать его следующим образом:

FiniteSet<int> set1 = new FiniteSet<int>(1, 2, 3);
FiniteSet<int> set2 = new FiniteSet<int>(3, 4, 5);
Console.WriteLine(set1); //{1, 2, 3}
Console.WriteLine(set2); //{3, 4, 5}

set1.UnionWith(set2);
Console.WriteLine(set1); //{1, 2, 3, 4, 5}

Теперь я хочу представить бесконечное множество. У меня была идея создать еще один абстрактный класс из множества, InfiniteSet, а затем разработчикам, использующим библиотеку, пришлось бы наследовать от InfiniteSet для реализации своих собственных классов. Я бы поставил часто используемые наборы, такие как N, Z, Q и R.

Но я понятия не имею, как реализовать такие методы, как Subset и GetEnumerator — я даже начинаю думать, что это невозможно. Как на практике перечислить бесконечное множество, чтобы его можно было пересечь/объединить с другим бесконечным множеством? Как вы можете проверить в коде, что N является подмножеством R? А что касается кардинальности.. Ну это, наверное, отдельный вопрос.

Все это приводит меня к выводу, что моя идея реализации бесконечного множества, вероятно, ошибочна. Я был бы очень признателен за ваш вклад :).

Редактировать: просто чтобы быть ясным, я также хотел бы представить несчетно бесконечные множества.

Edit2: я думаю, важно помнить, что конечной целью является реализация ISet, а это означает, что любое решение должно предоставлять (как и должно) способы реализации всех методы ISet, наиболее проблематичными из которых являются методы перечисления и метод IsSubsetOf.


person Daniel    schedule 25.07.2012    source источник
comment
Создать бесконечный набор очень просто с помощью yield return msdn.microsoft.com/en-us /библиотека/9k7k7cf0.aspx   -  person asawyer    schedule 26.07.2012
comment
@asawyer Я действительно не понимаю, как это относится к какой-либо из проблем здесь, кроме реализации перечисления, что по-прежнему оставляет проблему его реализации «практически».   -  person Daniel    schedule 26.07.2012
comment
Создать счетно бесконечное множество легко с помощью yield return.   -  person Michael Graczyk    schedule 26.07.2012
comment
@ Даниэль Что сказал Майкл. Извините, если я неправильно понял вопрос.   -  person asawyer    schedule 26.07.2012
comment
Нет, все в порядке, вероятно, это моя вина, что я не указал, что я также хотел бы представлять несчетно бесконечные множества - я отредактирую свой вопрос, чтобы отразить это.   -  person Daniel    schedule 26.07.2012
comment
По определению, вы не можете перечислить несчетное множество. Если вы готовы отказаться от перечисления, то реализация набора должна быть тривиальной (просто иметь предикат, проверяющий принадлежность. Пересечения И два предиката и объединения ИЛИ их).   -  person Michael Graczyk    schedule 26.07.2012
comment
Я не совсем хочу отказываться от перечисления, потому что тогда мне придется отказаться от ISet (правильно?). И даже если бы я был, я все равно не думаю, что проблема становится тривиальной: я не вижу, как решается проблема написания кода, который проверяет, является ли N подмножеством R.   -  person Daniel    schedule 26.07.2012
comment
Что ж, если вы не беспокоитесь о том, что ваш код будет выполняться за конечное время, тогда все тривиально... Хотя вы правы, кроме тестов на членство, объединений и пересечений, я не вижу никакого способа реализовать набор. Я приведу доказательство в качестве ответа.   -  person Michael Graczyk    schedule 26.07.2012


Ответы (5)


Невозможно полностью реализовать ISet<T> для несчетно бесконечных множеств.

Вот доказательство (любезно предоставлено Бертраном Расселом):

Предположим, вы создали класс MySet<T>, который может представлять несчетно бесконечное множество. Теперь давайте рассмотрим некоторые MySet<object> объекты.

Мы помечаем конкретный MySet<object>, называем его instance "ненормальным", если:

instance.Contains(instance) возвращает истину.

Точно так же мы пометим instance как "обычный", если:

instance.Contains(instance) возвращает ложь.

Обратите внимание, что это различие четко определено для всех instance.

Теперь рассмотрим экземпляр MySet<MySet<object>> с именем paradox.

Мы определяем paradox как MySet<MySet<object>>, который содержит все возможные обычные экземпляры MySet<object>.

Что должен вернуть paradox.Contains(paradox)?

Если он возвращает true, то paradox является ненормальным и должен был возвращать false при вызове самого себя.

Если он возвращает false, то paradox является нормальным и должен был возвращать true при вызове самого себя.

Невозможно реализовать Contains для разрешения этого парадокса, поэтому нет способа полностью реализовать ISet<T> для всех возможных несчетных множеств.


Теперь, если вы ограничите мощность MySet<T> равной или меньше мощности континуума (|R|), вы сможете обойти этот парадокс.

Даже в этом случае вы не сможете реализовать Contains или подобные методы, потому что это будет эквивалентно решению проблемы остановки. (Помните, что множество всех C# программ имеет мощность, равную |Z| ‹ |R|.)

ИЗМЕНИТЬ

Чтобы быть более подробным, вот объяснение моего утверждения, что «это было бы эквивалентно решению проблемы остановки».

Рассмотрим MySet<string>, состоящий из всех программ на C# (в виде строк), которые останавливаются за конечное время (если быть точным, предположим, что они останавливаются при любом вводе). Назовите его paradox2. Набор *рекурсивно перечислим", что означает, что вы можете реализовать на нем GetEnumerator (не легко, но возможно). Это также означает, что он корректно определен. Однако этот набор не является "разрешимым", потому что его дополнение не рекурсивно. перечислимый.

Определите программу C# следующим образом:

using ... //Everything;

public static class Decider {

    private MySet<string> _haltingSet = CreateHaltingSet();

    static void Main(string [] args) {
        Console.WriteLine(_haltingSet.Contains(args[0]));
    }
}

Скомпилируйте приведенную выше программу и передайте ее себе в качестве входных данных. Что происходит?

Если ваш метод Contains реализован правильно, вы решили проблему остановки. Однако мы знаем, что это невозможно, поэтому мы можем только заключить, что невозможно правильно реализовать Contains, даже для счетно бесконечных множеств.

Вы можете ограничить свой класс MySet<T> работой со всеми разрешимыми множествами. Однако тогда вы по-прежнему сталкиваетесь со всевозможными проблемами, когда ваша функция никогда не останавливается за конечное время.

В качестве примера предположим, что у нас есть вещественный тип произвольной точности с именем Real, и пусть nonHalting будет экземпляром MySet<Real>, включающим все нетривиальные нули дзета-функции Римана (это разрешимое множество). Если вы сможете правильно реализовать IsProperSubsetOf на nonHalting, чтобы вернуть за конечное время набор всех комплексных чисел с действительной частью 1/2 (также разрешимый набор), то вы выиграете Премия тысячелетия.

person Michael Graczyk    schedule 25.07.2012
comment
Теперь, если вы ограничите мощность MySet‹T› равной или меньшей мощности континуума (|R|), вы сможете обойти этот парадокс. Я готов это сделать (вроде как должен, не так ли :P?). Но как IsSubsetOf приравнивается к решению проблемы остановки? - person Daniel; 26.07.2012
comment
попробую разобраться на примере. - person Michael Graczyk; 26.07.2012

Вам придется обобщить то, что вы подразумеваете под Set.

Если у вас будет бесконечное множество, вы не сможете получить осмысленное перечисление над ним, поэтому вы не будете определять операции над множествами с операциями над перечислениями.

Если вы определяете Set<f> в терминах метода bool IsMember(f obj), его можно использовать для бесконечных наборов.

Вы определяете объединение или пересечение двух наборов как логическое и или или метода IsMember двух наборов.

person antlersoft    schedule 25.07.2012
comment
Я не уверен, что понимаю - учитывая IsMember из R и IsMember из N, как вы можете определить, что N является подмножеством R. И как вы можете их пересечь или объединить? - person Daniel; 26.07.2012
comment
Зависит от того, набран ли R. Если R — натуральные числа, то N union R — это N, а N пересечений R — это R. - person Tony Hopkinson; 26.07.2012
comment
@TonyHopkinson Я говорю о том, как вы можете сделать это в коде: P.. Я знаю, как это сделать на бумаге. А также, R содержит не только натуральные числа — ненатуральных чисел в нем несчетно больше. - person Daniel; 26.07.2012
comment
@Daniel -- Пересечение и объединение очень просты: (A union B).IsMember(f) = (A.IsMember(f) || B.IsMember(f)); (Пересечение B).IsMember(f) = (A.IsMember(f) && B.IsMember(f)). Проверить, что A является подмножеством B, непросто (фактически невозможно в самом общем случае, как показано в другом ответе) для бесконечных множеств; вам придется представить предикат IsMember символически и доказать, что предикат A подразумевает B. - person antlersoft; 26.07.2012
comment
@Дэниел. Как и я, это должны быть символы и правила, как и в математике. Никто никогда не доказывал, что N является подмножеством R, путем перечисления каждого члена N и проверки того, является ли он членом R, есть ли они.... - person Tony Hopkinson; 27.07.2012

представлять несчетно бесконечные множества

Давайте рассмотрим это утверждение в контексте того, как это делается на практике. Например, при запросе погоды набор A является подмножеством набора Z (целые положительные числа), субъект не является Z. Каждое число в Z не анализируется. Анализируется рассматриваемый набор A. Поскольку невозможно сравнить Ak (A sub k, где k — число от 1 до |A|) с каждым значением Z (бесконечным), каждое значение A должно быть по сравнению со свойствами, составляющими Z. Если каждое значение в A удовлетворяет свойствам Z, то A является подмножеством Z.

как вы можете представить в коде R объединение N

Тот же процесс, что и выше. Свойства R - это "любое действительное число" - в коде это может быть "любое двойное число, которое не вызывает исключение" (очевидно, что Math.Pow(-1,.5) вызовет проблемы и в результате не находится в R). Свойства N — «любое целое число» — в коде это может быть любое число, где Math.Floor != Math.Ceiling. Союз этих двух есть союз их свойств. Любое число, которое соответствует свойствам R или N — в коде это будет любое число, которое не вызывает исключение для создания или, которое Math.Floor != Math.Ceiling.

Сводка

Для представления несчетных бесконечных множеств используйте их свойства, а не их значения.


изменения

N ⊆ R?

Давайте вернемся к идее свойств, так как это тема, которую я хотел бы развивать. Является ли N подмножеством R? Чтобы N было подмножеством R, свойства N должны удовлетворять всем свойствам R. Список свойств должен быть точным. Чтобы представить числовое значение бесконечности, я бы предложил использовать класс, который содержит целочисленное число, допускающее значение NULL, и обычный знак int.

public class Infinite
{
 public int? Number { get; set; }
 public int Sign { get; set; }
}

Что-то в этом духе. Number.Value == null подразумевает бесконечность. Знак можно использовать для отображения отрицательного (-1), +- (0) или положительного (1) значения.

Вернемся к подмножеству N ситуации R. Помимо перечисленных ранее свойств, N также будет иметь Infinite.Number == null и Infinite.Sign == 0 в качестве границ своих свойств. Как и R. Итак, N сможет удовлетворить граничному свойству. Далее будут свойства, определенные выше. Я действительно застрял здесь. Я не уверен, как доказать в коде, что каждое число, которое .Floor == .Ceiling, не вызовет исключения. Однако, поскольку существует только 9 таких типов надмножеств (рациональное, иррациональное, целочисленное, вещественное, сложное, мнимое, трансцендентное, алгебраическое, естественное), вы можете специально определить их взаимодействия в бесконечном масштабе, а затем использовать более простую реализацию для конечных. сравнения.

person Travis J    schedule 25.07.2012
comment
Это устраняет проблему объединения, которая, на мой взгляд, является самой тривиальной, но все же не является ли N подмножеством R? проблема, или проблема перечисления. Я ценю (хорошо написанный) ответ, хотя :). - person Daniel; 26.07.2012

Что именно вы собираетесь с этим делать. Вы не можете перечислить это.

Я думаю, что буду относиться к нему как к потомку универсального набора.

Я думаю, я бы начал с другого конца

Определите универсальный набор, в котором Ismember всегда истинен. Тогда потомок, в котором IsMember истинен, если он представляет натуральное число {1,2,3,4}, является дополнительным ограничением N

В любом случае мысль

person Tony Hopkinson    schedule 25.07.2012

Это возможно с множеством ограничений, как и обработка символьных выражений.

Вот небольшой пример:

class IntSet
{
    int m_first;
    int m_delta;

    public IntSet(int first, int delta)
    {
        m_first = first;
        m_delta = delta;
    }

    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();

        sb.Append('[');
        sb.Append(m_first);
        sb.Append(',');
        sb.Append(m_first + m_delta);
        sb.Append(',');
        sb.Append("...");
        sb.Append(']');

        return sb.ToString();
    }

    public IEnumerable<int> GetNumbers()
    {
        yield return m_first;

        int next = m_first;

        while (true)
        {
            next += m_delta;

            yield return next;
        }
    }
}
person Feng Yuan    schedule 26.07.2012