【发布时间】:2010-06-12 19:00:17
【问题描述】:
假设我有一组对象S。有一个算法f,给定一个集合S 在其上构建特定的数据结构D:f(S) = D。如果S 很大和/或包含非常不同的对象,D 会变得很大,以至于无法使用(即不适合分配的内存)。为了克服这个问题,我将S 拆分为几个不相交的子集:S = S1 + S2 + ... + Sn 并为每个子集构建Di。使用n 结构的效率不如使用结构,但至少这样我可以适应内存限制。由于f(S) 的大小比S 本身增长得更快,所以Di 的组合大小远小于D 的大小。
但是,仍然希望减少n,即子集的数量;或减小Di 的组合大小。为此,我需要拆分S,使每个Si 包含“相似”对象,因为如果输入对象彼此“足够相似”,f 将产生更小的输出结构。
问题在于,虽然S 中对象的“相似性”和f(S) 的大小确实相关,但除了评估f(S) 和f 之外,没有办法计算后者,而且f 不是很快.
我目前的算法是将S 中的每个下一个对象迭代地添加到Si 之一中,这样可以尽可能少地(在此阶段)增加Di 的组合大小:
for x in S:
i = such i that
size(f(Si + {x})) - size(f(Si))
is min
Si = Si + {x}
这给出了实际有用的结果,但肯定远非最佳(即最小可能的组合大小)。而且,这慢。为了加快速度,我只计算i 的i,其中x 与Si 中已有的对象“足够相似”。
这类问题有什么标准方法吗?
我知道分支和边界算法系列,但它不能在这里应用,因为它会非常慢。我的猜测是,根本不可能在合理的时间内计算出S 到Si 的最佳分布。但是有一些常见的迭代改进算法吗?
编辑:
正如 cmets 所指出的,我从未定义过“相似性”。事实上,我想要的只是将Si 的组合大小拆分成这样的子集Di = f(Si) 是最小的或至少足够小。 “相似度”仅被定义为这一点,不幸的是,它根本无法轻松计算。我确实有一个简单的近似值,但它只是一个近似值。
所以,我需要一个(可能是启发式的)算法来最小化sum f(Si),因为没有简单的方法来计算后者——我只使用近似值来丢弃那些非常不太可能给出好的结果。
【问题讨论】:
-
你如何定义“相似”?也许你可以用一种能够使用先验算法的方式来制定它。
-
由于大小增量完全取决于
f(S),并且与“相似性”相关...我不确定您希望找到哪种算法,或者它如何帮助,除了专门针对f(S)(如@honk)所说的大小影响定义“相似性”,然后分区变得微不足道。 -
@honk:嗯,“相似性”是对象的一些内在属性,或者更确切地说,是它们的集合。在我的例子中,对象本身可以看作是点到值的映射;相似的对象有许多共同点,如果它们在相同点具有相同的值,则更好。不幸的是,这是相关的,但不直接定义
f输出的大小。 -
@honk:另外,请参阅问题本身的编辑。
-
@doublep:如果“相似性”仅由它引入的集合的大小定义(如您的编辑中建议的那样),则使其产生
size(S)/size(available_memory)不同的集合。但可能这不是你的意思。
标签: algorithm heuristics fuzzy