- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个图像名称列表和它们的(阈值)相似度矩阵。相似关系是自反和对称的,但不一定是传递性的,即如果 image_i
与 image_j
和 image_k
相似,则不需要意味着 image_j
和 image_k
是相似的。
例如:
images = ['image_0', 'image_1', 'image_2', 'image_3', 'image_4']
sm = np.array([[1, 1, 1, 0, 1],
[1, 1, 0, 0, 1],
[1, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[1, 1, 0, 0, 1]])
相似度矩阵 sm
解释如下:如果 sm[i, j] == 1
那么 image_i
和 image_j
相似,否则不相似。这里我们看到 image_0
类似于 image_1
和 image_2
,但是 image_1
和 image_2
不相似(这只是非传递性的一个例子)。
我想保留最大数量的唯一图像(根据给定的 sm
矩阵,它们都是成对不相似的)。对于此示例,它将是 [image_2, image_3, image_4]
或 [image_1, image_2, image_3]
(通常有多个这样的子集,但我不介意哪个保持它们的最大长度)。我正在寻找一种有效的方法来执行此操作,因为我有数千张图像。
编辑:我原来的解决方案如下
np.array(images)[np.tril(sm).sum(0) == 1]
但是,不能保证它会返回一个最大长度子集。考虑以下示例:
sm = np.array([[1, 1, 0, 0, 0],
[1, 1, 0, 0, 0],
[0, 0, 1, 1, 0],
[0, 0, 1, 1, 1],
[0, 0, 0, 1, 1]])
此解决方案将返回 ['image_1', 'image_4']
,而所需的结果是 ['image_0', 'image_2', 'image_4']
或['image_1', 'image_2', 'image_4']
。
更新:请参阅我的回答,其中使用图论更详细地解释了问题。我仍然愿意接受建议,因为我还没有找到一种合理快速的方法来获得数千张图像列表的结果。
最佳答案
经过进一步研究,我发现这就是图论中所谓的最大独立集问题,不幸的是NP-hard。
安independent set图 G 的 S 是 G 的顶点的子集,因此 S 中的顶点不相邻。在我们的例子中,我们正在寻找最大独立集 (MIS),即具有尽可能多的顶点的独立集。
有几个用于处理图形和网络的库,例如 igraph 或 NetworkX,它们具有查找最大独立集的函数。我最终使用了 igraph。
对于我的问题,我们可以将图像视为图 G 的顶点,将“相似性矩阵”视为邻接矩阵:
images = ['image_0', 'image_1', 'image_2', 'image_3', 'image_4']
sm = np.array([[1, 1, 1, 0, 1],
[1, 1, 0, 0, 1],
[1, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[1, 1, 0, 0, 1]])
# Adjacency matrix
adj = sm.copy()
np.fill_diagonal(adj, 0)
# Create the graph
import igraph
g = igraph.Graph.Adjacency(adj.tolist(), mode='UNDIRECTED')
# Find the maximum independent sets
g.largest_independent_vertex_sets()
[(1, 2, 3), (2, 3, 4)]
不幸的是,这对于成千上万的图像(顶点)来说太慢了。所以我仍然愿意接受有关更快方法的建议(也许不是找到所有的 MIS,而是找到一个)。
注意:@Sergey(更新#1)和@marke 提出的解决方案并不总是返回 MIS——它们是贪婪的近似算法,删除了一个最大度的顶点,直到没有边缘剩余。为了证明这一点,请考虑以下示例:
sm = np.array([[1, 1, 0, 0, 0, 1],
[1, 1, 0, 1, 0, 0],
[0, 0, 1, 1, 1, 0],
[0, 1, 1, 1, 0, 0],
[0, 0, 1, 0, 1, 1],
[1, 0, 0, 0, 1, 1]])
两种解决方案都返回 [3, 5]
,但对于此示例,最大独立集为两个,[(0, 3, 4), (1, 2, 5)]
,正如 igraph
正确找到的那样。要了解为什么这些解决方案无法找到 MIS,下面是一个 gif,它显示了每次迭代时如何删除顶点和边(这是返回第一次出现的 np.argmax
的“副作用”对于多次出现的最大值):
Sergey 的解决方案(更新#2)似乎可行,但它比 igraph 的 largest_independent_vertex_sets()
慢得多。对于速度比较,您可以使用以下随机生成的长度为 100 的相似度矩阵:
a = np.random.randint(2, size=(100, 100))
# create a symmetric similarity matrix
sm = np.tril(a) + np.tril(a, -1).T
np.fill_diagonal(sm, 1)
# create adjacency matrix for igraph
adj = sm.copy()
np.fill_diagonal(adj, 0)
更新:事实证明,虽然我有数千个图像-顶点,但边的数量相对较少(即我有一个稀疏图),所以使用 igraph 查找 MIS 是可以接受的速度方面。或者,作为折衷方案,可以使用贪婪近似算法来查找大型独立集(如果足够幸运,也可以使用 MIS)。下面是一个看起来相当快的算法:
def independent_set(adj):
'''
Given adjacency matrix, returns an independent set
of size >= np.sum(1/(1 + adj.sum(0)))
'''
adj = np.array(adj, dtype=bool).astype(np.uint8)
np.fill_diagonal(adj, 1) # for the purposes of algorithm
indep_set = set(range(len(adj)))
# Loop until no edges remain
while adj.sum(0).max() > 1:
degrees = adj.sum(0)
# Randomly pick a vertex v of max degree
v = random.choice(np.where(degrees == degrees.max())[0])
# "Remove" the vertex v and the edges to its neigbours
adj[v, :], adj[:, v] = 0, 0
# Update the maximal independent set
indep_set.difference_update({v})
return indep_set
或者更好的是,我们可以获得一个最大独立集:
def maximal_independent_set(adj):
adj = np.array(adj, dtype=bool).astype(np.uint8)
degrees = adj.sum(0)
V = set(range(len(adj))) # vertices of the graph
mis = set() # maximal independent set
while V:
# Randomly pick a vertex of min degree
v = random.choice(np.where(degrees == degrees.min())[0])
# Add it to the mis and remove it and its neighbours from V
mis.add(v)
Nv_c = set(np.nonzero(adj[v])[0]).union({v}) # closed neighbourhood of v
V.difference_update(Nv_c)
degrees[list(Nv_c)] = len(adj) + 1
return mis
关于python - 按相似关系过滤图像列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59907662/
下面的说法正确吗? “人最好的 friend 是狗。” public class Mann { private BestFriend dog; //etc } 最佳答案 我想说这样
我一直在 documentation 中查看 Laravel 4 中的关系我正在尝试解决以下问题。 我的数据库中有一个名为“事件”的表。该表具有各种字段,主要包含与其他表相关的 ID。例如,我有一个“
我的表具有如下关系: 我有相互链接的级联下拉框,即当您选择国家/地区时,该国家/地区下的区域将加载到区域下拉列表中。但现在我想将下拉菜单更改为基于 Ajax 的自动完成文本框。 我的问题是,我应该有多
我正在尝试弄清楚如何构建这个数据库。我之前用过Apple的核心数据就好了,现在我只是在做一个需要MySQL的不同项目。我是 MySQL 的新手,所以请放轻松。 :) 对于这个例子,假设我有三个表,Us
MongoDB 的关系表示多个文档之间在逻辑上的相互联系。 文档间可以通过嵌入和引用来建立联系。 MongoDB 中的关系可以是: 1:1 (1对1) 1: N (1对多)
您能解释一下 SQL 中“范围”和“分配单元”之间的区别或关系吗? 最佳答案 分配单元基本上只是一组页面。它可以很小(一页)或很大(很多页)。它在 sys.allocation_units 中有一个元
我有一个表 geoLocations,其中包含两列纬度和经度。还有第二个表(让我们将其命名为城市),其中包含每对唯一的纬度和经度对应的城市。 如何使用 PowerPivot 为这种关系建模?创建两个单
我想用 SQLDelight 建模关系,尤其是 一对多关系。 我有 2 张 table :recipe和 ingredient .为简单起见,它们看起来像这样: CREATE TABLE recipe
我是 Neo4J 新手,我有一个带有源和目标 IP 的简单 CSV。我想在具有相同标签的节点之间创建关系。 类似于... source_ip >> ALERTS >> dest_ip,或者相反。 "d
我正在创建一个类图,但我想知道下面显示的两个类之间是否会有任何关联 - 据我了解,对于关联,ClassA 必须有一个 ClassB 的实例,在这种情况下没有但是,它确实需要知道 ClassB 的一个变
是否可以显示其他属性,即“hasTopping”等? 如何在 OWLViz 中做到这一点? 最佳答案 OWLViz 仅 显示类层次结构(断言和推断的类层次结构)。仅使用“is-a”关系进行描述。 OW
public class MainClass { ArrayList mans = new ArrayList(); // I'm filling in this arraylist,
我想知道“多对二”的关系。 child 可以与两个 parent 中的任何一个联系,但不能同时与两个 parent 联系。有什么办法可以加强这一点吗?我也想防止 child 重复条目。 一个真实的例子
我有一个已经创建的Grails插件,旨在支持许多应用程序。该插件具有一个Employee域对象。问题在于,当在主应用程序中使用该应用程序中的域对象时,需要将其引用回Employee对象。因此,我的主应
我有一个类(class)表、类(class)hasMany部分和部分hasMany讲座以及讲座hasMany评论。如果我有评论 ID 并且想知道其类(class)名称,我应该如何在 LectureCo
我有一个模型团队,包含 ID 和名称。所有可能的团队都会被存储。 我的模型游戏有两列 team_1 和 team_2..我需要哪种关系? 我已经测试了很多,但它只适用于一列.. 最佳答案 也许你可以试
我读了很多关于 ICE 或 Corba 等技术中使用的仆人和对象的文章。有很多资源我可以读到这样的东西: 一个仆人可以处理多个对象(为了节省资源)。 一个对象可以由多个仆人处理(为了可靠性)。 有人可
嗨, 我有一个令人沮丧的问题,我在这方面有点生疏。我有两个这样的类(class): class A{ int i; String j ; //Getters and setters} class B
class Employee { private String name; void setName(String n) { name = n; } String getNam
如果您有这样的关系: 员工与其主管员工之间存在多对一关系 员工与其部门的多对一关系 部门与其经理一对一 我会在 Employee 实体中写入: @ManyToOne (cascade=CascadeT
我是一名优秀的程序员,十分优秀!