代码之家  ›  专栏  ›  技术社区  ›  svth

使用C快速地根据已知的对象相似性对对象数组进行排序

  •  0
  • svth  · 技术社区  · 14 年前

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

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

    我需要一个快速,有效的算法来排序这些数字的基础上,他们彼此的相似性。排序要么是使数组簇中的数字基于相似性,要么是相反的,即使彼此相似的数字尽可能远离彼此。

    最好的方法是什么?

    4 回复  |  直到 14 年前
        1
  •  1
  •   nategoose    14 年前

    首先,我假设你会使用 qsort memcnp strcmp --返回表示小于、等于或大于的整数。

    一种方法是将整个颜色值视为一个大数值,直到比较结束:

    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;
    }
    

    这将首先根据颜色的亮度(假设您编写了亮度比较函数)对颜色进行分组,然后根据颜色的色调进行分组。您可能想交换这些命令,而在内部它们可能更复杂。

    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
  •  1
  •   mlusiak    14 年前

    你可以试着把你的颜色从HSL颜色空间(我想你用它,因为你提到了色调和亮度)转换成CIELAB。在CIELAB颜色空间中,你可以很容易地计算出颜色的相似性,就像人类的眼睛所感知到的那样。计算出距离后,你就可以对颜色进行分类了。

        3
  •  0
  •   OJ.    14 年前

    PMG的评论是对的。根据您所说的,没有理由不使用带有客户比较功能的快速排序。查看PMG在其评论中发布的链接以获取更多信息,并确保您的比较功能(即 int (*compar)(const void *, const void *) )为你施魔法。

        4
  •  0
  •   R.. GitHub STOP HELPING ICE    14 年前

    O(n^2) 这还不算太糟。