我认为应该有这样的算法 - 可能在像生物信息学这样的领域(这个问题让我想起了一些序列对齐)所以我希望有人可以帮助我。
问题如下:假设我已经将一些数据分类为两个不同的类X和Y.结果可能如下所示:..XXX Y XXX ..进一步假设我们对这些有一些领域知识类并且知道连续不到一定数量的实例是极不可能的(即序列中不可能有少于4个X或Ys - 最好是每个类可以使用不同的阈值,但这不是必须的)。因此,如果我们使用这种领域知识,那么我们希望用X替换中间的单个Y是“显而易见的”。
因此,算法应该采用一系列分类实例和类的阈值(如果它简化了问题,则为1的阈值)并尝试找到满足属性的序列(没有比给定的更短的类序列)阈)。显然,可能存在极大数量的正确解决方案(例如,在上面的示例中,我们也可以用Y替换所有X),因此我认为合理的优化标准将是最小化替换次数。
我不需要这里特别有效的算法,因为实例的数量会相当小(比如说< 4k),我们只有两个类。此外,由于这显然只是一种启发式方法,如果它们大大简化了算法,我会很好地处理一些不准确的事情。
答案 0 :(得分:2)
一个非常类似的问题可以解决为经典的动态编程最短路径问题。我们希望找到最小化某些成本概念的序列。惩罚序列中与原始序列中的相应字符不同的每个字符。惩罚序列中每个字符的变化,因此惩罚从X到Y的每个变化,反之亦然。
这不是你想要的,因为YYYXYYY的惩罚与YXXXXXXY的惩罚相同 - YX的一个惩罚和XY的一个惩罚 - 但是它可能是一个很好的近似,因为例如如果基本序列显示YYY .... YXY .... YY那么将中心X更改为Y比支付XY和YX的成本更便宜 - 而且你可以明显地摆弄不同的成本惩罚得到看似合理的东西。
现在把序列中的每个位置都想象成两个点,一个在另一个之上,一个点代表“X在这里”,一个代表“Y在这里”。您可以使用成本行链接点,具体取决于原始序列中相应的字符是X还是Y,以及该行是将X与X连接还是将X与Y连接。然后使用动态程序计算从左到右的最短路径,该动态程序计算在位置i + 1处终止于X和Y的最佳路径,同时了解在位置i处终止于X和Y的最佳路径的成本。 / p>
如果你真的想要比长期变化更严厉地惩罚短暂的变化你可以通过增加路径寻找表示中的点数来实现这一点 - 你会得到与此处的X相对应的点数Y是3个字符前“。但是根据你想要的惩罚,你可能会在每个角色上得到一个非常大量的分数。
答案 1 :(得分:1)
您可以使用动态编程,如下面的伪代码草图(为简单起见,此代码假设阈值是连续3 X或Y,而不是4):
min_switch(s):
n = len(s)
optx = array(4, n, infinity) // initialize all values to infinity
opty = array(4, n, infinity) // initialize all values to infinity
if s[0] == 'X':
optx[1][0] = 0
opty[1][0] = 1
else:
optx[1][0] = 1
opty[1][0] = 0
for i in {1, n - 1}:
x = s[i]
if x == 'X':
optx[1][i] = opty[3][i - 1]
optx[2][i] = optx[1][i - 1]
optx[3][i] = min(optx[2][i - 1], optx[3][i - 1])
opty[1][i] = 1 + min(optx[1][i - 1], optx[2][i - 1], optx[3][i - 1])
opty[2][i] = 1 + opty[1][i - 1]
opty[3][i] = 1 + min(opty[2][i - 1], opty[3][i - 1])
else:
optx[1][i] = 1 + min(opty[1][i - 1], opty[2][i - 1], opty[3][i - 1])
optx[2][i] = 1 + opty[1][i - 1]
optx[3][i] = 1 + min(opty[2][i - 1], opty[3][i - 1])
opty[1][i] = optx[3][i - 1]
opty[2][i] = opty[1][i - 1]
opty[3][i] = min(opty[2][i - 1], opty[3][i - 1])
return min(optx[3][n - 1], opty[3][n - 1])
上述代码基本上计算创建平滑序列的最低成本,直到第i个字符存储行中连续X或Y的所有相关数量的最佳值(行中的1,2或3)。更正式的
opt[i][0][k]
存储最小的
转换字符串s[0...k]
的费用
然后以平滑的顺序结束
i
个连续的X.运行3或更多
在opt[3][0][k]
中计算。opt[0][j][k]
存储最小的
转换字符串s[0...k]
的费用
然后以平滑的顺序结束
j
连续Ys。运行3或更多
在opt[0][3][k]
中计算。可以直接将其转换为返回序列和最优成本的算法。
请注意,上面代码中的某些情况可能是不必要的,它只是从约束中得到的直接重复。