311 lines
7.0 KiB
Python
311 lines
7.0 KiB
Python
#!/usr/bin/env python
|
||
# coding: utf-8
|
||
|
||
# In[78]:
|
||
|
||
|
||
# matrices from the document
|
||
R1 = [[1,0,1],[0,1,0],[1,0,0]]
|
||
R2 = [[1,1,0],[0,0,1],[1,0,1]]
|
||
R3 = [[1, 1, 1], [0, 0, 1], [0, 0, 1]]
|
||
R4 = [[1, 1, 0, 1], [1, 1, 0, 1], [0, 0, 1, 0], [1, 1, 0, 1]]
|
||
R5 = [[0, 1, 0], [0, 0, 1], [1, 0, 0]]
|
||
R6 = [[1, 1, 1], [0, 0, 1], [1, 0, 0]]
|
||
|
||
tests = [R1, R2, R3, R4, R5, R6]
|
||
|
||
CHAMPIONS = [[1,1,0,1,1],
|
||
[0,1,0,0,0],
|
||
[1,1,1,1,1],
|
||
[1,1,0,1,1],
|
||
[0,1,0,0,1]]
|
||
|
||
|
||
# In[79]:
|
||
|
||
|
||
# Check if a matrix is reflexive
|
||
def reflexive(R):
|
||
for i in range(len(R)):
|
||
if R[i][i] != 1:
|
||
return False
|
||
return True
|
||
|
||
# Check if a matrix is symmetric
|
||
def symmetrical(R):
|
||
for i in range(len(R)):
|
||
for j in range(len(R)):
|
||
if R[i][j] != R[j][i]:
|
||
return False
|
||
return True
|
||
|
||
# Check if a matrix is anti-symmetric
|
||
def anti_symmetrical(R):
|
||
for i in range(len(R)):
|
||
for j in range(len(R)):
|
||
if R[i][j] > 0 and R[j][i] > 0 and i != j:
|
||
return False
|
||
return True
|
||
|
||
# Check if a matrix is asymmetrical
|
||
def asymmetrical(R):
|
||
for i in range(len(R)):
|
||
for j in range(len(R)):
|
||
if R[i][j] > 0 and R[j][i] > 0:
|
||
return False
|
||
return True
|
||
|
||
# Check if a matrix is irreflexive
|
||
def irreflexive(R):
|
||
for i in range(len(R)):
|
||
if R[i][i] > 0:
|
||
return False
|
||
return True
|
||
|
||
# Check if a matrix is transitive
|
||
def transitive(matrix):
|
||
is_transitive = True
|
||
for i in range(len(matrix)):
|
||
for j in range(len(matrix)):
|
||
if matrix[i][j] > 0:
|
||
for k in range(len(matrix)):
|
||
if matrix[j][k] > 0:
|
||
is_transitive = is_transitive and matrix[i][k] > 0
|
||
|
||
return is_transitive
|
||
|
||
# Check if a matrix is intransitive
|
||
def intransitive(matrix):
|
||
is_transitive = True
|
||
for i in range(len(matrix)):
|
||
for j in range(len(matrix)):
|
||
if matrix[i][j] > 0:
|
||
for k in range(len(matrix)):
|
||
if matrix[j][k] > 0:
|
||
is_transitive = is_transitive and matrix[i][k] != 1
|
||
|
||
return is_transitive
|
||
|
||
# Check if a matrix is non-transitive
|
||
def non_transitive(matrix):
|
||
n = len(matrix)
|
||
|
||
for i in range(n):
|
||
for j in range(n):
|
||
if matrix[i][j] > 0:
|
||
for k in range(n):
|
||
if matrix[j][k] > 0 and matrix[i][k] == 0:
|
||
return True
|
||
return False
|
||
|
||
|
||
# In[80]:
|
||
|
||
|
||
# Testing all the matrices from the slides
|
||
|
||
for i in range(len(tests)):
|
||
print("--------------------------------------------------")
|
||
print("Matrix: R", i+1)
|
||
a = reflexive(tests[i])
|
||
print("reflexive: ", a)
|
||
a = irreflexive(tests[i])
|
||
print("irreflexive: ", a)
|
||
a = symmetrical(tests[i])
|
||
print("symmetrical: ", a)
|
||
a = anti_symmetrical(tests[i])
|
||
print("anti_symmetrical: ", a)
|
||
a = asymmetrical(tests[i])
|
||
print("asymmetrical: ", a)
|
||
a = transitive(tests[i])
|
||
print("transitive: ", a)
|
||
a = intransitive(tests[i])
|
||
print("intransitive: ", a)
|
||
a = non_transitive(tests[i])
|
||
print("non_transitive: ", a)
|
||
|
||
|
||
# In[81]:
|
||
|
||
|
||
# Equivalence classes
|
||
|
||
def equivalence_classes(R):
|
||
n = len(R)
|
||
classes = []
|
||
scores = []
|
||
|
||
# Count number of (x,y) existing on each row
|
||
for x in range(n):
|
||
score = 0
|
||
for y in range(n):
|
||
if R[x][y] > 0:
|
||
score += 1
|
||
scores.append(score)
|
||
|
||
lastScore = 0
|
||
|
||
for i in range(n):
|
||
max_score = 0
|
||
max_index = 0
|
||
for j in range(n):
|
||
if scores[j] > max_score:
|
||
max_score = scores[j]
|
||
max_index = j
|
||
|
||
if(max_score == lastScore):
|
||
classes[len(classes)-1].append(max_index)
|
||
else:
|
||
# Add the class to the list of classes
|
||
classes.append([max_index])
|
||
|
||
lastScore = max_score
|
||
scores[max_index] = 0
|
||
|
||
return classes, scores
|
||
|
||
|
||
# In[82]:
|
||
|
||
|
||
print(equivalence_classes(CHAMPIONS))
|
||
|
||
|
||
# In[83]:
|
||
|
||
|
||
def transitive_closure(adjacency_matrix):
|
||
"""
|
||
Calculate the transitive closure of a directed graph represented as an adjacency matrix.
|
||
|
||
Args:
|
||
adjacency_matrix (list of lists): The adjacency matrix of the graph.
|
||
|
||
Returns:
|
||
list of lists: The transitive closure matrix.
|
||
"""
|
||
n = len(adjacency_matrix)
|
||
|
||
# Initialize the transitive closure matrix as a copy of the adjacency matrix
|
||
closure_matrix = [row[:] for row in adjacency_matrix]
|
||
|
||
# Perform the Floyd-Warshall algorithm to compute transitive closure
|
||
for k in range(n):
|
||
for i in range(n):
|
||
for j in range(n):
|
||
closure_matrix[i][j] = closure_matrix[i][j] or (closure_matrix[i][k] and closure_matrix[k][j])
|
||
|
||
return closure_matrix
|
||
|
||
# Example usage:
|
||
adjacency_matrix = [
|
||
[0, 1, 0, 0],
|
||
[0, 0, 0, 1],
|
||
[1, 0, 0, 0],
|
||
[0, 0, 1, 0]
|
||
]
|
||
|
||
ex_cours = [
|
||
[0, 0, 1, 0],
|
||
[0, 0, 0, 0],
|
||
[0, 1, 1, 1],
|
||
[1, 0, 0, 0]
|
||
]
|
||
|
||
transitive_closure_matrix = transitive_closure(ex_cours)
|
||
|
||
# Print the transitive closure matrix
|
||
for row in transitive_closure_matrix:
|
||
print(row)
|
||
|
||
|
||
# In[84]:
|
||
|
||
|
||
# Make transitive closure
|
||
|
||
transitive_closure_matrix = [
|
||
[1, 0, 0, 0],
|
||
[0, 1, 0, 1],
|
||
[1, 0, 0, 0],
|
||
[0, 0, 1, 1]
|
||
]
|
||
|
||
def transitive_closure(matrix):
|
||
modification = True
|
||
while modification:
|
||
modification = False
|
||
for i in range(len(matrix)):
|
||
for j in range(len(matrix)):
|
||
for k in range(len(matrix)):
|
||
if matrix[i][j] > 0 and matrix[j][k] > 0 and matrix[i][k] == 0:
|
||
matrix[i][k] = matrix[i][j] + matrix[j][k]
|
||
modification = True
|
||
else:
|
||
modification = False
|
||
|
||
return matrix
|
||
|
||
full_closure = transitive_closure(ex_cours)
|
||
|
||
for row in full_closure:
|
||
print(row)
|
||
|
||
|
||
# In[85]:
|
||
|
||
|
||
# Remove transitive closure
|
||
|
||
transitive_closure_matrix = [
|
||
[1, 0, 0, 0],
|
||
[0, 1, 2, 1],
|
||
[1, 0, 0, 0],
|
||
[2, 0, 1, 1]
|
||
]
|
||
|
||
m = [
|
||
[1,1,1,1,1,1,1],
|
||
[0,1,0,0,1,1,1],
|
||
[0,0,1,0,0,0,1],
|
||
[0,0,0,1,1,1,1],
|
||
[0,0,0,0,1,1,1],
|
||
[0,0,0,0,0,1,1],
|
||
[0,0,0,0,0,0,1]
|
||
]
|
||
|
||
def remove_transitive_closure(matrix):
|
||
n = len(matrix)
|
||
modification = True
|
||
|
||
while modification:
|
||
# reset modification
|
||
modification = False
|
||
for i in range(n):
|
||
for j in range(n):
|
||
# checking if there is a path from i to j
|
||
if matrix[i][j] > 0:
|
||
for k in range(j,n):
|
||
# checking if there is a path from i k to to k
|
||
if matrix[i][k] > 0 and matrix[j][k] > 0:
|
||
matrix[i][k] = 0
|
||
modification = True
|
||
print("Removing ", i, k)
|
||
# restart while loop
|
||
break
|
||
if modification:
|
||
break
|
||
|
||
return matrix
|
||
|
||
no_closure = remove_transitive_closure(transitive_closure_matrix)
|
||
|
||
for row in no_closure:
|
||
print(row)
|
||
|
||
no_closure = remove_transitive_closure(m)
|
||
|
||
for row in no_closure:
|
||
print(row)
|
||
|