Python 检查矩阵中的某些元素是否具有内聚性
我必须编写一个非常小的Python程序来检查一些坐标组是否都连接在一起(通过一条直线,而不是对角线)。接下来的两张图片展示了我的意思。在左图中,所有颜色组都是内聚的,在右图中,不是: 我已经编写了这段代码,但它似乎不起作用,我被卡住了,关于如何修复它有什么想法吗Python 检查矩阵中的某些元素是否具有内聚性,python,algorithm,Python,Algorithm,我必须编写一个非常小的Python程序来检查一些坐标组是否都连接在一起(通过一条直线,而不是对角线)。接下来的两张图片展示了我的意思。在左图中,所有颜色组都是内聚的,在右图中,不是: 我已经编写了这段代码,但它似乎不起作用,我被卡住了,关于如何修复它有什么想法吗 def cohesive(container): co = container.pop() container.add(co) return connected(co, container) def connect
def cohesive(container):
co = container.pop()
container.add(co)
return connected(co, container)
def connected(co, container):
done = {co}
todo = set(container)
while len(neighbours(co, container, done)) > 0 and len(todo) > 0:
done = done.union(neighbours(co, container, done))
return len(done) == len(container)
def neighbours(co, container, done):
output = set()
for i in range(-1, 2):
if i != 0:
if (co[0] + i, co[1]) in container and (co[0] + i, co[1]) not in done:
output.add((co[0] + i, co[1]))
if (co[0], co[1] + i) in container and (co[0], co[1] + i) not in done:
output.add((co[0], co[1] + i))
return output
这是一些参考资料,应该返回True
:
cohesive({(1, 2), (1, 3), (2, 2), (0, 3), (0, 4)})
这应该返回False
:
cohesive({(1, 2), (1, 4), (2, 2), (0, 3), (0, 4)})
这两种测试都能工作,但当我尝试用不同的数字测试时,函数会失败。通常,要检查某些东西是否连接,需要使用不相交的集合数据结构,更有效的变化包括加权快速并集、加权快速并集和路径压缩 这是一个实现,您可以根据需要修改它。此外,A.Aho在《计算机算法的设计与分析》一书中的实现允许您指定添加2个连接元素的组的名称,因此我认为这是您正在寻找的修改(只需要使用1个额外的数组来跟踪组编号) 作为旁注,由于不相交集通常适用于数组,请不要忘记,可以将N×N矩阵表示为大小为N*N的数组 编辑:刚意识到我不清楚你一开始问的是什么,我意识到你还提到对角线分量没有连接,在这种情况下,算法如下所示: 0)检查所有元素是否引用同一组 1) 遍历表示相关矩阵中坐标的对数组 2) 对于每一对,制作一组满足以下公式的对:
|entry.x - otherEntry.x| + |entry.y - otherEntry.y|=1.
“entry”指的是外部for循环所指的元素
3) 检查所有集合是否重叠。这可以通过“联合”您正在查看的集合来实现,最后,如果您得到的集合超过1个,那么元素就没有内聚性
复杂度为O(n^2+n^2*log(n))
例如:
(0,4)、(1,2)、(1,4)、(2,2)、(2,3)
0)检查它们是否都在同一组中:
他们都属于第5组
1) 制作套装:
set1:(0,4),(1,4)
set2:(1,2),(2,2)
set3:(0,4),(1,4)//这里我们假设集合是排序的,而不是它
应该是(1,4),(0,4)
set4:(1,2),(2,2),(2,3)
set5:(2,2),(2,3)
2) 检查重叠:
set1与set3重叠,因此我们得到:
set1’:(0,4),(1,4)
set2与set4和SET5重叠,因此我们得到:
set2’:(1,2)、(2,2)、(2,3)
正如您所看到的,set1'和set2'不重叠,因此您得到了两个不相交的集合,它们位于同一组中,因此答案为“false”
请注意,这是低效的,但我不知道如何更有效地执行,但这回答了您的问题。连接函数中的逻辑似乎是错误的。创建todo变量,但决不更改其内容。你总是在同一个起点附近寻找邻居 请尝试以下代码:
def connected(co, container):
done = {co}
todo = {co}
while len(todo) > 0:
co = todo.pop()
n = neighbours(co, container, done)
done = done.union(n)
todo = todo.union(n)
return len(done) == len(container)
todo
是我们仍要检查的所有点的集合
done
是一组我们发现的与起点4-连接的所有点。我将以不同的方式解决这个问题。。。如果你要找五个,那就意味着:
def cells_are_connected(connections):
return all(c > 0 for c in connections)
def groups_are_connected(connections):
return len([1 for c in connections if c > 1]) > 2
def cohesive(coordinates):
connections = []
for x, y in coordinates:
neighbours = [(x-1, y), (x+1, y), (x, y-1), (x, y+1)]
connections.append(len([1 for n in neighbours if n in coordinates]))
return cells_are_connected(connections) and groups_are_connected(connections)
print cohesive([(1, 2), (1, 3), (2, 2), (0, 3), (0, 4)]) # True
print cohesive([(1, 2), (1, 4), (2, 2), (0, 3), (0, 4)]) # False
不需要通用案例解决方案或联合逻辑。:)请注意,这是一个特定于“五行合一”问题的问题。您可以在可能的情况下获取一个元素并附加其相邻元素
def dist(A,B):return abs(A[0]-B[0]) + abs(A[1]-B[1])
def grow(K,E):return {M for M in E for N in K if dist(M,N)<=1}
def cohesive(E):
K={min(E)} # an element
L=grow(K,E)
while len(K)<len(L) : K,L=L,grow(L,E)
return len(L)==len(E)
为什么你不能检查所有的元素是否都有相同的颜色?甚至价值?或者“非对角部分”是不是意味着{(1,1),(2,2)}应该返回false?另外,您的示例查询有点向后,因为它们的意思是(y,x)而不是(x,y),非常不直观,但我只是说它们不是(y,x),而是(行,列)。这是一个矩阵,连标题都这么说。@StefanPochmann是的,我想我只是习惯了(x,y)。好问题,很好的图表。我建议直接使用。谢谢你的解释!这很有帮助!
In [1]: cohesive({(1, 2), (1, 3), (2, 2), (0, 3), (0, 4)})
Out[1]: True
In [2]: cohesive({(1, 2), (1, 4), (2, 2), (0, 3), (0, 4)})
Out[2]: False