- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我必须比较 2 个字符串,比如 CDABAB
和 EABACCCBB
。对我来说,相似性只是相同字符在两者中同时出现的数量,无论位置如何(即字符串是“文本”而不是“序列”)。此外,形成同现字符链的字符被赋予双倍权重。
在我的示例中,A
、A
、B
、B
、C
是共现的实例。此外,ABA
是一个包含 3 个字符的双倍权重链。所以,A(2)
,A(2)
,B(2)
,B(1)
, C(1)
求和,2+2+2+1+1=8
对我来说就是两个字符串的相似度。这个例子太简单了;在现实生活中,我有一千多个长度的字符串。所以我需要一个算法。
这显然是一个经典的分配问题。我知道它可以通过例如 Hungarian algorithm 来解决.我们应该构建共现矩阵(2 = double weight because of a chain):
E A B A C C C B B
C 1 1 1
D
A 2 1
B 2 1 1
A 2 2
B 2 1 1
并以最佳方式一对一地对行和列进行配对,以使对内相似度的总和最大化。它意味着在每一行和每一列中只留下一个正值,以一种给出最大矩阵值和的方式。匈牙利算法是一种通用方法,可以给出这样的最大和(最优解)。左侧条目的总和为 8
,与上面的计算结果相同:
但是,匈牙利语并不是特别快(而且不太容易编程)。我的长字符串需要另一种算法。 你能给我推荐另一种算法吗,更快更简单?请注意,我的数据是特殊情况:它是仅具有 3 个整数值的相似矩阵 - 0、1 和 2。
(使用二进制矩阵,很容易做出最佳配对。有了 3 个值,我知道该怎么做,但就准确性而言,它可以给出次优的,尽管是“好”的解决方案。是否有始终获得最佳结果的方法?)
附言重要。 我在字符串中的元素实际上不是来自有限字母表的真实字符,而是真实的单词;所以-它们来 self 事先不知道的可能无限的字母表。我不会做频率计数等预处理。我更倾向于从如上所示的矩形矩阵开始:我可以非常有效地制作具有适当 0,1,2 值的矩阵。我的主要问题是关于进一步的算法。
谢谢您(也感谢您的耐心等待)。
稍后更新:回复@j_random_hacker 的回答。
我喜欢提议的快速方法,它看起来很帅。但是我发现这是有问题的。下面的示例对此进行了演示。
Two strings are
S1= ABCACCDECF
S2= BACBCCDA
The matrix of co-occurences (where chains are given weight 2) is therefore:
B A C B C C D A
A 0 1 0 0 0 0 0 1*
B 1 0 0 2* 0 0 0 0
C 0 0 1 0 2* 1 0 0
A 0 2* 0 0 0 0 0 1
C 0 0 2* 0 2 1 0 0
C 0 0 1 0 1 2* 0 0
D 0 0 0 0 0 0 2* 0
E 0 0 0 0 0 0 0 0
C 0 0 1 0 1 1 0 0
F 0* 0 0 0 0 0 0 0
Hungarian algorithm of optimal pairing paired the rows and columns so as to maximize
the sum of within-pair values. These values - which pair a row and a column - are shown starred
in the matrix. And the sum is 13. It is the "similarity" between the strings.
Let us compute now the similarity by the quick algorithm suggested by @j_random_hacker.
Counts of individual characters (only occuring in both strings shown):
A B C D
S1 2 1 4 1
S2 2 2 3 1
---------------
Min 2 1 3 1
Sum1=7
Counts of dyadic chains (only occuring in both strings shown):
BC AC CC CD
S1 1 1 1 1
S2 1 1 1 1
-------------------
Min 1 1 1 1
Sum2=4
Counts of triadic chains (only occuring in both strings shown):
CCD
S1 1
S2 1
--------
Min 1
Sum3=1
Sum1 + 2Sum2 - Sum3 = 14. While I was expecting 13, as Hungarian algo gave.
The cause of the discrepancy seems obvious enough.
The second algorithm recognized 4 dyads: AC, BC, CD, and CC; and because CC and CD actually
superimpose by C (they form a triad CCD), C should be counted only once as a member of a dyad.
However, as seen from the starred elements in the matrix, Hungarian algorithm recognized
only 3 dyads: AC, BC, CD. Because the first of the two C is shared by by AC and CC or by
BC and CC, this character is (since it cannot be counted twice) is discarded altogether,
and hence the dyad it is a member of, CC, does not exist. And that is correct for me.
最佳答案
[编辑 23/7/2014:此答案不正确——请参阅顶部的 OP 反例。]
实际上这根本不是分配问题。
如下预处理每个字符串S:
(请参阅下文了解可能的加速。)
[编辑:修复了下面的公式以计算共享字母对中的每个字母。]
任意一对字符串 S 和 T 的相似度由 A + 2B - C 给出,其中
A = sum(min(f1[S][X], f1[T][X])) over all letters X
B = sum(min(f2[S][XY], f2[T][XY])) over all letter pairs XY
C = sum(min(f3[S][XYZ], f3[T][XYZ])) over all letter triples XYZ
A 计算 S 和 T 共享的字母数,B 计算相邻字母对的数量,C 校正 2 个共享相邻对重叠 1 个字母的情况(例如,如果 S 和 T 都是 ABC
,则 A = 3,B = 2(因为 AB
和 BC
出现在两个字符串中)并且 C = 1,因此 B
由这两对共享的代码不会被计算两次。)
如果字母表很大,可能会有很多字母对甚至更多的三元组。在这种情况下,您可以将“在 S 中至少出现一次”或“在 T 中至少出现一次”添加到定义 A、B 和 C 的每一行的末尾——也就是说,向前扫描其中一个就足够了字符串,查看其中出现的每个(唯一)字母、字母对和字母三元组。这将比较算法从字母大小的立方体更改为较小字符串长度的线性体。同样,在预处理阶段,您可以使用哈希表而不是普通数组,仅将 S 中实际出现的字母、对和三元组存储在 f1[S]、f2[S] 和 f3[S] 中。
关于algorithm - 少值整数数据的最优配对算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24783333/
我在一本书(Interview Question)中读到这个问题,想在这里详细讨论这个问题。请点亮它。 问题如下:- 隐私和匿名化 马萨诸塞州集团保险委员会早在 1990 年代中期就有一个绝妙的主意
我最近接受了一次面试,面试官给了我一些伪代码并提出了相关问题。不幸的是,由于准备不足,我无法回答他的问题。由于时间关系,我无法向他请教该问题的解决方案。如果有人可以指导我并帮助我理解问题,以便我可以改
这是我的代码 public int getDist(Node root, int value) { if (root == null && value !=0) return
就效率而言,Strassen 算法应该停止递归并应用乘法的最佳交叉点是多少? 我知道这与具体的实现和硬件密切相关,但对于一般情况应该有某种指南或某人的一些实验结果。 在网上搜索了一下,问了一些他们认为
我想学习一些关于分布式算法的知识,所以我正在寻找任何书籍推荐。我对理论书籍更感兴趣,因为实现只是个人喜好问题(我可能会使用 erlang(或 c#))。但另一方面,我不想对算法进行原始的数学分析。只是
我想知道你们中有多少人实现了计算机科学的“ classical algorithms ”,例如 Dijkstra's algorithm或现实世界中的数据结构(例如二叉搜索树),而不是学术项目? 当有
我正在解决旧编程竞赛中的一些示例问题。在这个问题中,我们得到了我们有多少调酒师以及他们知道哪些食谱的信息。制作每杯鸡尾酒需要 1 分钟,我们需要使用所有调酒师计算是否可以在 5 分钟内完成订单。 解决
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 8 年前。 Improve
我开始学习 Nodejs,但我被困在中间的某个地方。我从 npm 安装了一个新库,它是 express -jwt ,它在运行后显示某种错误。附上代码和错误日志,请帮助我! const jwt = re
我有一个证书,其中签名算法显示“sha256rsa”,但指纹算法显示“sha1”。我的证书 SHA1/SHA2 的标识是什么? 谢谢! 最佳答案 TL;TR:签名和指纹是完全不同的东西。对于证书的强度
我目前在我的大学学习数据结构类(class),并且在之前的类(class)中做过一些算法分析,但这是我在之前的类(class)中遇到的最困难的部分。我们现在将在我的数据结构类(class)中学习算法分
有一个由 N 个 1x1 方格组成的区域,并且该区域的所有部分都是相连的(没有任何方格无法到达的方格)。 下面是一些面积的例子。 我想在这个区域中选择一些方块,并且两个相邻的方块不能一起选择(对角接触
我有一些多边形形状的点列表,我想将其包含在我页面上的 Google map 中。 我已经从原始数据中删除了尽可能多的不必要的多边形,现在我剩下大约 12 个,但它们非常详细以至于导致了问题。现在我的文
我目前正在实现 Marching Squares用于计算等高线曲线,我对此处提到的位移位的使用有疑问 Compose the 4 bits at the corners of the cell to
我正在尝试针对给定算法的约束满足问题实现此递归回溯函数: function BACKTRACKING-SEARCH(csp) returns solution/failure return R
是否有包含反函数的库? 作为项目的一部分,我目前正在研究测向算法。我正在使用巴特利特相关性。在 Bartlett 相关性中,我需要将已经是 3 次矩阵乘法(包括 Hermitian 转置)的分子除以作
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 8 年前。 Improve
问题的链接是UVA - 1394 : And There Was One . 朴素的算法是扫描整个数组并在每次迭代中标记第 k 个元素并在最后停止:这需要 O(n^2) 时间。 我搜索了一种替代算法并
COM 中创建 GUID 的函数 (CoCreateGUID) 使用“分散唯一性算法”,但我的问题是,它是什么? 谁能解释一下? 最佳答案 一种生成 ID 的方法,该 ID 具有一定的唯一性保证,而不
在做一个项目时我遇到了这个问题,我将在这个问题的实际领域之外重新措辞(我想我可以谈论烟花的口径和形状,但这会使理解更加复杂).我正在寻找一种(可能是近似的)算法来解决它。 我有 n 个不同大小的容器,
我是一名优秀的程序员,十分优秀!