使用快速排序对区间进行模糊排序

时间:2019-02-20 04:06:28

标签: python-3.x algorithm sorting quicksort

算法简介

问题7-6提出以下要求:

考虑一个排序问题,在该问题中我们不完全知道数字。相反,对于每个数字,我们知道它所属的实线上的间隔。也就是说,我们以[ a_i b_i ]的形式给出 n 个闭合间隔,其中a_i <= b_i。我们希望对这些间隔进行 模糊排序 。 (Cormen,Leiserson,Rivest和Stein,2009年,第189页)

Demaine和Goldwasser(2004)阐明“没有间隔包含任何其他间隔”,或“如果a_i <= a_j,则b_i,b_j。”

我已经实现了Lanman(2006)的伪代码。尽管我觉得我很亲密,但是这些函数在测试输入上未返回正确的结果。我的代码如下:

def sort_fuzzy(intervals, p, s):
    """
    Given a list whose elements are 2-tuples that represent inclusive intervals,
    sort it in place by partitioning it.  Assume no interval completely contains
    any other interval.
    :param  list intervals: An unsorted list of 2-tuples that represent a \
                            closed interval in which a fuzzy value lies.
    :param  int p:          Starting index of the region to sort.
    :param  int s:          Ending index of the region to sort.
    """

    if p < s:
        x = find_intersection(intervals, p, s)
        r = partition_fuzzy_right(intervals, p, s, x)
        q = partition_fuzzy_left_middle(intervals, p, r, x)
        sort_fuzzy(intervals, p, q - 1)
        sort_fuzzy(intervals, r + 1, s)

def partition_fuzzy_right(intervals, p, s, x):
    """
    Given a list whose elements are 2-tuples that represent inclusive intervals,
    partition it into three regions: p to r - 1, r, and r + 1 to s.
    :param  list intervals: An unsorted list of 2-tuples that represent a \
                            closed interval in which a fuzzy value lies.
    :param  int p:          Starting index of the region to sort.
    :param  int s:          Ending index of the region to sort.
    :param  tuple x:        Intersection of intervals.
    """

    i = p - 1
    for j in range(p, s):
        if intervals[j][0] <= x[0]:
            i += 1
            intervals[i], intervals[j] = intervals[j], intervals[i]

    intervals[i + 1], intervals[s] = intervals[s], intervals[i + 1]

    return i + 1

def partition_fuzzy_left_middle(intervals, p, r, x):
    """
    Given a list whose elements are 2-tuples that represent inclusive intervals,
    partition it into four regions: p to q - 1. q, q + 1 to r, and r + 1 to s.
    :param  list intervals: An unsorted list of 2-tuples that represent a \
                            closed interval in which a fuzzy value lies.
    :param  int p:          Starting index of the region to sort.
    :param  int s:          Ending index of the region to sort.
    :param  tuple x:        Intersection of intervals.
    """

    i = p - 1
    for j in range(p, r):
        if intervals[j][1] < x[1]:
            i += 1
            intervals[i], intervals[j] = intervals[j], intervals[i]

    intervals[i + 1], intervals[r] = intervals[r], intervals[i + 1]

    return i + 1

def find_intersection(intervals, p, s):
    """
    Given a list whose elements are 2-tuples that represent inclusive intervals,
    return the intersection of a pivot interval and the 2-tuples if one exists.
    Otherwise, just return the pivot interval.
    :param  list intervals: An unsorted list of 2-tuples that represent a \
                            closed interval in which a fuzzy value lies.
    :param  int p:          Starting index of the region to sort.
    :param  int s:          Ending index of the region to sort.
    """

    x = intervals[s]

    for i in range(p, s):
        if intervals[i][0] <= x[1] and intervals[i][1] >= x[0]:
            if intervals[i][0] > x[0]:
                x = (intervals[i][0], x[1])
            if intervals[i][1] < x[1]:
                x = (x[0], intervals[i][1])

    return x

if __name__ == '__main__':
    list = [(13, 20), (19, 21), (9, 11), (5, 7), (12, 16), (8, 10), (7, 9), (4, 6), (20, 24), (2, 2), (6, 8), (11, 15)]
    print(list)
    sort_fuzzy(list, 0, len(list) - 1)
    print(list)

任何帮助和提示将不胜感激。我已经为此工作了好几天。

更新:Lanman(2006)中伪代码的一种更直接的实现,即将元组的输入数组拆分为A和B数组并从那里进行适应没有帮助。我得到了相同的结果。

参考文献:

Cormen,T. H.,Leiserson,C.E.,Rivest,R.L.,&Stein,C.(2009年)。 算法简介(第三版)[ProQuest Ebook Central版本]。取自https://ebookcentral.proquest.com

Demaine,E.和Goldwasser,S.(2004年2月24日)。习题2 [课堂讲义]。取自https://courses.csail.mit.edu/6.046/spring04/handouts/ps2-sol.pdf

Lanman,D.R.(2006年3月13日)。 CS 157:作业3 [课堂讲义]。取自http://alumni.media.mit.edu/~dlanman/courses/cs157/HW3.pdf

2 个答案:

答案 0 :(得分:1)

正如@tobias_k所指出的,我的问题是不了解问题或正确的解决方案是什么样的。关于正确的解决方案,Cormen等。 (2009年)说:“我们希望对这些区间进行模糊排序,即产生区间的置换,使得对于j = 1,2,...,n,存在满足c_1的c_j∈[a_i_j,b_i_j] <= c_2 <= ... <= c_n。”

因此,对于输入[(13, 20), (19, 21), (9, 11), (5, 7), (12, 16), (8, 10), (7, 9), (4, 6), (20, 24), (2, 2), (6, 8), (11, 15)],我的代码输出[(2, 2), (4, 6), (6, 8), (7, 9), (5, 7), (8, 10), (9, 11), (11, 15), (13, 20), (12, 16), (19, 21), (20, 24)] 是正确的解决方案。

您可以看到,就像Cormen等人一样。 (2009年)写道,如果间隔中的 any 数大于或等于间隔中的 any 数,则它可能正确地跟随了该间隔。换句话说,请考虑以下内容:

2 | 2 ∈ [2, 2] <= 4 | 4 ∈ [4, 6] <= 6 | 6 ∈ [6, 8] <= 7 | 7 ∈ [7, 9] <= 7 | 7 ∈ [5, 7] 8 | 8 ∈ <= [8, 10] <= 9 | 9 ∈ [9, 11] <= 11 | 11 ∈ [11, 15] <= 13 | 13 ∈ [13, 20] <= 13 | 13 ∈ [12, 16] <= 19 | 19 ∈ [19, 21] <= 20 | 20 ∈ [20, 24]

不是必须按递增顺序对左边缘进行排序,而只是间隔以某种模糊的递增顺序重叠即可。请参阅Lanman(2006)的第四页,并在解决问题之前真正了解什么是正确的模糊排序。

参考文献:

Cormen,T. H.,Leiserson,C.E.,Rivest,R.L.,&Stein,C.(2009年)。 算法简介(第三版)[ProQuest Ebook Central版本]。取自https://ebookcentral.proquest.com

Lanman,D.R.(2006年3月13日)。 CS 157:作业3 [课堂讲义]。取自http://alumni.media.mit.edu/~dlanman/courses/cs157/HW3.pdf

答案 1 :(得分:0)

由于间隔互不包含,因此您可以按左边缘,中边缘或右边缘进行排序,您将获得相同的准确答案。

如果要使排序模糊,可以对间隔进行采样(假设均匀或想要的任何分布,然后对采样值进行排序。