Где я ошибаюсь, реализуя тау Кендалла

#c# #.net #algorithm

Вопрос:

Поэтому я нашел эту статью о том, как очень эффективно вычислить тау Кендалла O(n log n). Но я, кажется, не могу сделать это правильно.

В статье поток кода объясняется концептуально и приведен пример кода внизу. Я пытаюсь реализовать вариант SDTau. Я получаю такие значения, как -1,5, с массивом тестовых чисел, что просто невозможно для тау Кендалла. Оно должно быть между -1 и 1.

Ссылка: вход не требуется, откройте полный текст или загрузите pdf

Мой код

 class Kendall_Correlation
{

public static double RUN(List<XYPoint> XY)
{
    List<XYPoint> SortedByXThenY = new List<XYPoint>();
    SortedByXThenY = XY.OrderBy(XYPoint => XYPoint.X).ThenBy(XYPoint => XYPoint.Y).ToList();

    SortedSet<double> tree = new SortedSet<double>();

    int NumBefore = 0;
    int Equals = 0;
    int Discordant = 0;
    int concordant = 0;
    int ExtraX = 0;
    int EXtraY = 0;
    int ACount = 0;
    int BCount = 0;
    int CCount = 0;
    int DCount = 0;
    int ECount = 0;
    double PreviousX = SortedByXThenY[0].X;
    double PreviousY = SortedByXThenY[0].Y;
    tree.Add(SortedByXThenY[0].Y);

    for (int i = 1; i < SortedByXThenY.Count; i  )
    {
        if (SortedByXThenY[i].X == PreviousX)
        {
            DCount = 0;
            ECount = 1;
        }
        else
        {
            if (SortedByXThenY[i].Y == PreviousY)
            {
                ECount  ;
            }
            else
            {
                DCount  = ECount;
                ECount = 1;
            }
        }

        tree.Add(SortedByXThenY[i].Y);

        Equals = tree.Where(node => node == SortedByXThenY[i].Y).Count();
        NumBefore = tree.Where(node => node < SortedByXThenY[i].Y).Count();

        ACount = NumBefore - DCount;
        BCount = Equals - ECount;
        CCount = i - (ACount   BCount   DCount   ECount - 1);
        EXtraY  = DCount;
        ExtraX  = BCount;
        concordant  = ACount;
        Discordant  = CCount;
        PreviousX = SortedByXThenY[i].X;
        PreviousY = SortedByXThenY[i].Y;
    }

    int n0 = concordant   Discordant   ExtraX;
    int n1 = concordant   Discordant   EXtraY;

    double tau = ((Double) concordant - (Double) Discordant) / Math.Sqrt(n0 * n1);
    return tau;
}

public class XYPoint
{
    public double X;
    public double Y;
}
 

Это потому, что я использую SortedSet Тип? Насколько я понимаю, a SortedSet в основном идентичен дереву AVL? Мой код также значительно медленнее, чем показано в статье. Мой больше по величине минут при попытке с выборкой в 1 000 000

Комментарии:

1. Этот код не компилируется. Вы дважды SortedByXThenY заявляли об этом. И XYPoints не существует. Должен ли это быть метод парама XY вместо этого? Вы можете исправить, чтобы другие могли запустить это?

2. @Zer0 Извиняюсь, проблемы должны быть устранены сейчас

Ответ №1:

Where Метод повторяется по всему SortedSet , чтобы найти элементы, удовлетворяющие заданному условию. Это имеет стоимость O(n), поэтому ваша функция имеет общее асимптотическое время выполнения O(n 2), а не O(n log n), как вы предполагали.

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

Комментарии:

1. Вы могли бы предположить, что его журнал n раз, так как он по сути является двоичным деревом, и он должен эффективно уменьшать набор вдвое при каждом выборе узла. влево или вправо. Как бы я сделал это с помощью log n вместо этого?

2. @CodeMuppet Перечисляется. Где находится универсальный метод, предназначенный для работы со всем, что реализует IEnumerable (это может быть массив, связанный список, дерево или любая другая повторяющаяся структура данных). В нем нет никакого специального случая для набора сортировки, в котором можно использовать более эффективный алгоритм. Единственными методами сортировки наборов со стоимостью журнала(n) являются Добавление, удаление, Содержит, Минимум и Максимум. Если вы не можете выразить свой алгоритм в терминах этих операций, вам придется пропустить набор сортировки и реализовать все самостоятельно.