根据某个指标

时间:2017-01-08 12:55:51

标签: algorithm set complexity-theory matching

我面临以下问题:

我有p项(n维向量)A和其他q项B的列表,其中包含度量,它描述了“良好匹配”是如何设置B(它是某个值)。现在,我想将B中的一个项目与A中的一个项目进行交换,以通过提到的指标来改进度量描述。

我正在寻找一种有效的算法而不是强力算法,在这个例子中,它具有复杂度p x q +计算度量值的复杂度。也许通过观察物品的特定坐标可以降低复杂性?

我将不胜感激任何帮助。

编辑: 假设我在交换之前和之后都有B组的条形码。我可以计算出它们之间的Wasserstein度量,但我认为它没有多大贡献。因此,让我们说B的度量就是条形码中条形的平均长度。

1 个答案:

答案 0 :(得分:0)

为了试图回答这个问题,我必须做出假设。当然,我的假设很可能是错误的,所以请澄清我在哪里有误解。幸运的是,我可以在代码方面重新构建我的假设,因此,至少做出我的假设,(大多数)是明确的。

如果我的问题是正确的,你有一个名为A的某些未指定项目类型(实数?)的n维向量的列表(例如java.util.List)。代码:

List<Item[]> A
assert(A.size() == p)

此外,你有一个集合(例如,java.util.Set,但我怀疑你只是真的意味着某种类型的集合,你可能希望索引)的项目是B - 并且有q他们。在代码中:

Collection<Item[]> B
assert(B.size() == q)

此外,你有一些功能 - 我会打电话给&#34;测量&#34; - 计算&#34;指标&#34; B.现在,我必须发出警告,因为&#34; metric&#34;是一个非常具体的数学术语,它定义了度量空间的两个元素之间的距离测量。有时候,人们可以使用&#34; metric&#34;对于度量空间的元素来描述它与原点的距离,即点[0,0,0,... 0]。如果您确实描述了度量标准空间上的操作,则可能会对该方法进行改进。在任何情况下,&#34;衡量&#34;函数将B作为输入并返回实数值。即:

double Measure(Collection<Item[]> B) {
  // Compute value ...
}

现在,如果我理解正确,那么解决问题的蛮力(即使对蛮力也不是很有效)可能看起来像这样:

Collection<Item[]> replaceItem(Collection<Item[]> c, Item[] removed, Item[] added) {
   Collection<Item[]> replacement = c.clone();
   // Technically, this might not work. Not sure offhand if an Array of
   // items qualifies as Comparable even if the Items are comparable.
   // But conceptually, the idea below is correct.
   replacement.remove(removed);
   replacement.add(added);
   return replacement;
}

double MeasureWithReplacement(Collection<Item[]> B, Item[] b, Item[] a) {
  // brute-force implementation. An improvement would be to implement
  // the original Measure function with the Measure function knowing how
  // to do this replacement.
  Collection<Item[]> replacement = replaceItem(B, b, a);
  return Measure(replacement);
}

Collection<Item[]> ImproveBUsingA(Collection<Item[]> B, List<Item[]> A) {
  double bestValue = Measure(B);
  Item[] bestRemoved = null;
  Item[] bestAdded = null;
  for (Item[] b : B) {
    for (Item[] a : A) {
      double currentMeasure = MeasureWithReplacement(B, b, a);
      if (currentMeasure > bestValue) {
        bestValue = currentMeasure;
        bestRemoved = b;
        bestAdded = a;
      }
    }
  }

  return (bestRemoved == null ? B : replaceItem(B, bestRemoved, bestAdded));
}

现在形成了我所理解的问题陈述:我们可以对这个算法进行大的改进吗?

我会假设在没有额外克隆Collection的情况下执行操作是相当简单的,所以在这个假设下,这里的操作就像你建议的那样,O(| A | * | B | * Complexity(Measure) (| B |)))

一个可能的改进: 尝试使用保存的结果计算Measure,然后仅使用不同的替换项操作来缩小计算Measure的成本。换句话说,创建这样的东西:

double MeasureFromBase(Collection<Item[]> base, double baseMeasure, Item[] a, Item[] b) {
  // Do calculation here, but use a and b to provide deltas compared to
  // baseMeasure
  ...
}

这会降低执行测量操作的成本,假设替换集合中的项目允许简单测量。然而,复杂性是O(| A | * | B | *复杂性(MeasureFromBase(| B |)),它不能得到你真正希望的东西。

为了获得任何真正的改进,我们必须更多地了解Item []和Measure计算。

特别是,了解Item []的某些元素是否比其他元素更重要。 Item []的第一个元素是最重要的吗?是第k个元素吗?它们同等重要吗?如果Item []的特定元素在计算中占主导地位,则可以进行一种分支定界计算,首先根据最重要的度量标准计算度量标准,然后仅在需要时使用二次和三次测量。 (参见:https://en.wikipedia.org/wiki/Principal_component_analysis了解这方面的有用工具)。

另外,可以比较两个Item值吗?我可以确定item1&lt; = item2吗?如果是这样,并且如果它们的相对比较值与它们对整个Measure值的影响有关,那么您可能能够为操作构建一种索引。

实际上,没有更多的东西可以确定。不过,我希望这会有所帮助。