[英]Python Relations with Sets of Tuples
我試圖確定元組集是否具有某種類型的關系。 我試圖找出傳遞關系和復合關系。
對於傳遞關系:
# A relation 'Relation' is called transitive when:
# ∀ (a, b) ∈ Relation, (b, c) ∈ Relation ==> (a, c) ∈ Relation
例如:
>>> {(1,1), (1,2), (1,4), (2,1), (2,2), (3,3), (4,1), (4,4)} # Should be False
>>> {(1,1), (2,1), (3,1), (3,2), (4,1), (4,2), (4,3)} # Should be True
對於復合關系:
# The composite of relations 'R1' and 'R2' is the relation consisting
# of tuples (a,c), such that (a,b) ∈ R1 and (b,c) ∈ R2
例如:
{(1,0), (1,1), (2,1), (2,2), (3,0), (3,1)} == R1={(1,1), (1,4), (2,3), (3,1), (3,4)}, R2={(1,0), (2,0), (3,1), (3,2), (4,1)}
# Should return True
我不確定如何開始編碼這些功能。 任何幫助我開始的幫助將不勝感激。 謝謝!
編輯:這是我能夠成功編碼的一些其他關系:
# Reflexive Relation
# A relation 'Relation' on a set 'Set' is called reflexive when:
# ∀ a ∈ Set, (a,a) ∈ Relation
def is_reflexive(Set, Relation):
newSet = {(a, b) for a in Set for b in Set if a == b}
if Relation >= newSet:
return True
return False
# Symmetric Relation
# A relation 'Relation' is called symmetric when:
# ∀ (a, b) ∈ Relation, (b, a) ∈ Relation
def is_symmetric(Relation):
if all(tup[::-1] in Relation for tup in Relation):
return True
return False
我相信這是一種有效的蠻力方法。 首先,我們將使用“鄰接集”表示,然后使用深度嵌套的for循環顯式測試:
In [5]: r1 = {(1,1), (1,2), (1,4), (2,1), (2,2), (3,3), (4,1), (4,3)}
In [6]: adjacency = {}
...: for a,b in r1:
...: adjacency.setdefault(a,set()).add(b)
...:
In [7]: transitive = True
In [8]: for a, related in adjacency.items():
...: for b in related:
...: for c in adjacency[b]:
...: if c not in related:
...: transitive = False
...: print("({},{}) and ({},{}) but not ({},{})".format(a, b, b, c, a,c))
...:
(1,4) and (4,3) but not (1,3)
(2,1) and (1,4) but not (2,4)
(4,1) and (1,2) but not (4,2)
(4,1) and (1,4) but not (4,4)
In [9]: transitive
Out[9]: False
但是,對於你的第二個例子:
In [7]: r2 = {(1,1), (2,1), (3,1), (3,2), (4,1), (4,2), (4,3)}
In [8]: adjacency = {}
...: for a,b in r2:
...: adjacency.setdefault(a,set()).add(b)
...:
In [9]: transitive = True
In [10]: for a, related in adjacency.items():
...: for b in related:
...: for c in adjacency[b]:
...: if c not in related:
...: transitive = False
...: print("({},{}) and ({},{}) but not ({},{})".format(a, b, b, c, a,c))
...:
In [11]: transitive
Out[11]: True
使用這種數據結構應該會使時間復雜度的POV變得不那么可怕。
至於構建復合材料:
In [18]: def make_adjacency_set(R):
...: a = {}
...: for x,y in R:
...: a.setdefault(x, set()).add(y)
...: return a
...:
In [19]: def make_composite(R1, R2):
...: adj1 = make_adjacency_set(R1)
...: adj2 = make_adjacency_set(R2)
...: composite = set()
...: for a, related in adj1.items():
...: for b in related:
...: for c in adj2.get(b, []):
...: composite.add((a, c))
...: return composite
...:
In [20]: R1={(1,1), (1,4), (2,3), (3,1), (3,4)}; R2={(1,0), (2,0), (3,1), (3,2), (4,1)}
In [21]: make_composite(R1, R2)
Out[21]: {(1, 0), (1, 1), (2, 1), (2, 2), (3, 0), (3, 1)}
或者,只是堅持使用元組:
In [25]: composite = set()
...: for a, b in R1:
...: for c, d in R2:
...: if b == c:
...: composite.add((a,d))
...:
...:
In [26]: composite
Out[26]: {(1, 0), (1, 1), (2, 1), (2, 2), (3, 0), (3, 1)}
對於傳遞測試,只需在Python中轉換數學定義:
def is_transitive(relation):
for a,b in relation:
for c,d in relation:
if b == c and ((a,d) not in relation):
# print (a,b),(c,d) # uncomment for tests...
return False
return True
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.