【问题标题】:Median of Medians algorithm error中位数算法错误的中位数
【发布时间】:2015-08-07 05:14:12
【问题描述】:

我正在使用 Median of Medians 枢轴方法实现第 k 个选择算法。具体来说,我正在关注pseudocode listed here.。但是,我的代码崩溃(下面讨论的错误),我明白它为什么会崩溃,但我不明白我能做些什么。

错误

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 32017219
at Selection.partition(Selection.java:173)

原因
在 wiki 链接中,select 方法将在 left == right 时返回一个 。但是,当从pivot 的返回语句中调用相互递归时,这意味着它将返回一个值(而不是索引)给父级,并且父级将将该值设置为pivotIndex

守则

public static int alg5(int[] a, int left, int right, int k) {
    if (left == right) {
        return a[left];
    }

    while (true) {
        int pivotIndex = pivot(a, left, right);         
        pivotIndex = partition(a, left, right, pivotIndex);

        if (k == pivotIndex) {
            return a[k];
        } else if (k < pivotIndex) {
            right = pivotIndex - 1;
        } else {
            left = pivotIndex + 1;
        }

    }
}

public static int pivot(int[] a, int left, int right) {
    for (int i = left; i <= right; i = i + 5) {
        int subRight = i + 4;
        if (subRight > right) {
            subRight = right;
        }

        int median5 = partition5(a, i, subRight);
        swap(a, median5, (int)(Math.floor(i / 5)));
    }

    return alg5(a, left, (int)(left + Math.ceil((right - left) / 5) - 1), ((right - left) / 10));
}

public static int partition5(int[] a, int left, int right) {
    Arrays.sort(a);

    return ((a.length - 1) / 2);
}

public static int partition(int[] a, int left, int right, int pivotIndex) {
    int pivotValue = a[pivotIndex];
    a = swap(a, pivotIndex, right);
    int storeIndex = left;

    for (int i = left; i <= right; i++) {
        int aOfi = a[i];
        if (a[i] < pivotValue) {
            swap(a, storeIndex, i);
            storeIndex++;
        }
    }

    swap(a, right, storeIndex);

    return storeIndex;
}

我完全理解为什么我的代码不起作用,我只是不明白如何修复它,因为它看起来正是算法指定的。非常感谢指针!

【问题讨论】:

  • 据我所知,这是 wiki 中的一个错误,请尝试返回 pivotIndex 而不是 a[k],并将您的结果与已经实现的 k-means 算法进行比较,例如 R (或者也许是 matlab?)。
  • @ShellFish 同样的错误,Selection.partition 超出范围。

标签: java algorithm median-of-medians


【解决方案1】:

有不少错误:

  1. 方法pivot 不应修改数组a。它应该只是为未来找到一个支点partition。一个肮脏的解决方法是调用pivot(a.clone(), left, right);。 (你不应该这样做,只是为了给你一个想法。)

  2. Math.ceil((right - left) / 5) 是整数除法。您应该将它们转换为浮点数:Math.ceil(((float)(right - left)) / 5f)

  3. partition5 中,您对整个数组a 进行排序!您只需进行比较即可找到a[left]a[right] 之间中位数的索引

  4. 在某些时候你可能有right &lt; left,所以alg5的第一行你应该写if (left &gt;= right)

【讨论】:

  • #4 修复了崩溃,谢谢!我通过搜索实现了#3,并实现了#1 和#2,这改变了输出,但它仍然不是正确的答案。我很高兴崩溃现在消失了,所以我可以专注于为什么它给出了错误的答案。再次感谢您的解决方案!
猜你喜欢
  • 1970-01-01
  • 2021-11-14
  • 2020-05-04
  • 2012-01-18
  • 2012-09-14
  • 2021-08-17
  • 1970-01-01
  • 1970-01-01
  • 2019-02-26
相关资源
最近更新 更多