【问题标题】:Where am I going wrong implementing Kendall's tau实施 Kendall 的 tau 我哪里错了
【发布时间】:2021-10-17 03:24:21
【问题描述】:

所以我找到了这篇关于如何非常有效地计算 Kendall 的 tau O(n log n) 的文章。但我似乎无法做到这一点。

在文章中,代码流在概念上进行了解释,代码示例在底部。我正在尝试实现 SDTau 变体。 我得到了诸如 -1.5 之类的值,其中包含一系列测试数字,这对于 Kendall 的 tau 来说是不可能的。它应该在 -1 和 1 之间。

链接:no login required, open fulltext or download 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 类型吗?据我了解,SortedSet 基本上与 AVL 树相同?我的代码也比文章中描述的时间慢得多。尝试使用 1,000,000 的样本时,我的数量级更多

【问题讨论】:

  • 此代码无法编译。你有SortedByXThenY 声明了两次。而XYPoints 不存在。那应该是方法参数XY吗?你能修复它以便其他人可以运行它吗?
  • @Zer0 抱歉,问题应该现在解决

标签: c# .net algorithm


【解决方案1】:

Where 方法遍历整个SortedSet 以查找满足给定条件的元素。这具有 O(n) 成本,因此您的函数的总体渐近运行时间为 O(n2),而不是您假设的 O(n log n)。

为了有效实现您在 SortedSet 上执行的操作(查找其值大于或等于给定值的节点数),您可以使用order statistic tree

【讨论】:

  • 您会假设它的 log n 时间,因为它本质上是一棵二叉树,并且每次选择 node.left 或 node.right 时它应该有效地将集合减半。我将如何使用 log n 来做呢?
  • @CodeMuppet Enumerable.Where 是一种通用方法,旨在与实现 IEnumerable 的任何东西(可以是数组、链表、树或任何其他可迭代数据结构)一起使用。对于可以使用更有效算法的 SortedSet,它没有任何特殊情况。唯一具有 log(n) 成本的 SortedSet 方法是 Add、Remove、Contains、Min 和 Max。如果你不能用这些操作来表达你的算法,你将不得不跳过 SortedSet 并自己实现一切。
猜你喜欢
  • 2015-05-22
  • 2018-10-19
  • 2011-02-03
  • 2015-05-12
  • 2015-12-18
  • 2011-06-07
  • 2018-01-21
  • 1970-01-01
相关资源
最近更新 更多