我不认为这个问题可以通过散列来解决。困难在于:假设您有一个红色像素,并且您希望 3 和 5 散列到相同的值。好吧,那么您还希望 5 和 7 散列到相同的值,以及 7 和 9,依此类推……您可以构建一个链,表示您希望所有像素散列到相同的值。
这是我会尝试的方法:
- 构建一个巨大的 B 树,每个节点都有 32 路扇出,包含所有图像。
- 树中的所有图像都具有相同的大小,或者它们不是重复的。
- 给每个彩色像素一个从零开始的唯一数字。对于 R、G、B 组件,左上角的编号可能为 0、1、2,或者您可能最好使用随机排列,因为您将按该编号的顺序比较图像。
- 深度为 n 的内部节点在像素 n 除以 8 的值上区分 32 种方式(这消除了附近像素中的一些噪声。
- 叶节点包含少量图像,例如 10 到 100。或者图像的数量可能是深度的递增函数,因此如果您有 500 个图像的副本,在一定深度后,您将停止尝试区分它们.
一个所有两百万个节点都插入到树中,两个图像只有在它们位于同一节点时才是重复的。对?错误的!如果两个图像中的像素值分别为 127 和 128,则一个进入 outedge 15,另一个进入 outedge 16。所以实际上,当您区分一个像素时,您可以将该图像插入一个或两个孩子:
- 对于亮度,在、和
B
处插入。有时所有 3 将相等,并且总是 2 of 3 将相等。但是以 3/8 的概率,您将出现图像的边缘数量增加一倍。根据事情的深入程度,您可能会有很多额外的节点。 B/8
(B-3)/8
(B+3)/8
其他人将不得不进行数学运算,看看您是否必须除以大于 8 的值才能防止图像重复过多。好消息是,即使真正的扇出仅在 4 左右而不是 32 左右,您也只需要深度为 10 的树。10 中的 4 次重复可以让您在叶子处获得多达 3200 万张图像。我希望你有足够的内存供你使用!如果没有,您可以将树放入文件系统中。
让我知道这是怎么回事!