使用C基于彼此已知的相似性快速对对象数组进行排序

时间:2010-10-19 22:44:24

标签: c arrays sorting

我有一个随机排序的整数数组。

这些数字中的每一个都代表一种颜色,并且与其他地方定义的数组中的每个其他数字有关系(它们是非线性的,并且基于颜色和色调的亮度)。

我需要一种快速,有效的算法来根据它们彼此的相似性对这些数字进行排序。排序要么是基于相似性的阵列簇中的数字,要么是相反的,即以这样的方式使得彼此相似的数字彼此尽可能远。

最好的方法是什么?

4 个答案:

答案 0 :(得分:1)

您可以尝试将您的颜色从HSL颜色空间(我认为您使用它,因为您提到了色调和亮度)转换为CIELAB。在CIELAB色彩空间中,您可以很容易地计算出颜色的相似性,就像人眼感知它一样。计算出该距离后,您可以对颜色进行排序。

答案 1 :(得分:1)

首先,我假设您将使用qsort或类似函数进行排序,并需要一个比较函数来传递给它。这些比较函数的行为类似于memcnpstrcmp - 返回一个整数来表示小于,等于或大于。

这样做的一种方法是将整个颜色值视为一个大数字,直到比较为止:

int bright_hue_compare(const void * a, const void * b) {
    int rc = bright_compare(a, b);
    if (!rc) {
        rc = hue_compare(a, b);
    }
    return rc;
}

这将首先根据亮度(假设您编写亮度比较功能)对颜色进行分组,然后按颜色对颜色进行分组。您可能想要交换这些的顺序,在内部它们可能会更复杂。

排序使得相似的颜色彼此之间的距离更加复杂,因为您确实需要一次将它与几个可能的相邻值进行比较,以进一步将它们分开。我怀疑你可以用quicksort可靠地得到这个(stdlib qsort函数可能不是快速排序,但假设它是),但是:

int bright_hue_inverse_compare(const void * a, const void * b) {
    int rc = bright_hue_compare(a, b);
    if (rc) {
       return 0;
    }
    return random(); // so that they are the same so randomize greater/lesser
}

可能 适合你,但收益远远不是最佳结果。

实际上你可能不得不为此编写自己的排序函数,并且可能会有非常高的运行时间,因为每种颜色需要与其许多邻居进行比较。你希望这种分布越优化,这就越开始看起来像一个人工智能问题,每种颜色都要尽可能地远离颜色。

哦,我刚才想到的可能产生良好效果的东西,如果平均所有色调和所有亮度,然后将数组分成两半并试图使每个子阵列的平均值与你一样接近可以通过在阵列之间交换一些颜色来平衡整个阵列的平均值。然后将这些数组分成两半并重复。我不认为你会(也可能不会)用这个获得最佳结果,但我认为这可能是相当不错的。找到交换的内容将是这里最大的问题。

答案 2 :(得分:0)

PMG的评论是正确的。根据您所说的,没有理由不使用具有客户比较功能的快速排序。有关详细信息,请参阅PMG在其评论中发布的链接,并确保您的比较功能(int (*compar)(const void *, const void *))为您提供了魔力。

答案 3 :(得分:0)

一种方法是先选择一个对象,然后使用度量函数搜索剩余的对象,找到最近的一个/最远的一个。对添加到输出列表的每个对象重复此操作。算法是O(n^2),这不算太糟糕。