dft2hd2reliabilityr 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dft2hd2reliabilityr/FaultTreeLib.py +291 -0
- dft2hd2reliabilityr/FaultTreeRLib.py +617 -0
- dft2hd2reliabilityr/HasseDiagramLib.py +1390 -0
- dft2hd2reliabilityr/LogicDoorLib.py +505 -0
- dft2hd2reliabilityr/__init__.py +34 -0
- dft2hd2reliabilityr-0.2.0.dist-info/METADATA +137 -0
- dft2hd2reliabilityr-0.2.0.dist-info/RECORD +10 -0
- dft2hd2reliabilityr-0.2.0.dist-info/WHEEL +5 -0
- dft2hd2reliabilityr-0.2.0.dist-info/licenses/LICENSE +21 -0
- dft2hd2reliabilityr-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# It's a class that creates a directed graph
|
|
2
|
+
"""
|
|
3
|
+
Bibliothèques utiles
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
#import plotly.graph_objects as go
|
|
7
|
+
# CORRECTION-04 : matplotlib/networkx sont importés paresseusement dans ViewGraph
|
|
8
|
+
# (deviennent un extra optionnel [viz] pour la publication PyPI).
|
|
9
|
+
from .LogicDoorLib import * # CORRECTION-11 : imports relatifs au package
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
Fault tree construction
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
FaultTrees={}
|
|
16
|
+
class FaultTree:
|
|
17
|
+
NFaultTree=0
|
|
18
|
+
def __init__(self,n):
|
|
19
|
+
"""
|
|
20
|
+
It creates a new object of class Tree, and adds it to the dictionary FaultTreeRs
|
|
21
|
+
|
|
22
|
+
:param n: number of nodes
|
|
23
|
+
"""
|
|
24
|
+
self.id=id(self)
|
|
25
|
+
FaultTrees[str(self.id)]=self
|
|
26
|
+
self.__class__.NFaultTree+=1
|
|
27
|
+
self.NNode=n # Le système a moins de composant que n
|
|
28
|
+
self.Node=[]
|
|
29
|
+
self.Label=[]
|
|
30
|
+
self.AdjMat={}#matlib.zeros((n, n))
|
|
31
|
+
self.RelMat=[[],[],[],[],[],[]]
|
|
32
|
+
#[[Door],[NodeIn],[NodeOut],[Orders],[Times],[IndicesPrincipal]]
|
|
33
|
+
self.IdxTable=[[],[],[]]
|
|
34
|
+
#[[NumRel],[Node i],[Node j]]
|
|
35
|
+
|
|
36
|
+
def __del__(self):
|
|
37
|
+
"""
|
|
38
|
+
The __del__ method is called when the instance is about to be destroyed
|
|
39
|
+
"""
|
|
40
|
+
self.__class__.NFaultTree-=1
|
|
41
|
+
|
|
42
|
+
def IdxNode(self,Indices=None):
|
|
43
|
+
"""
|
|
44
|
+
It returns the index of the node in the list of nodes
|
|
45
|
+
|
|
46
|
+
:param Indices: The index of the node you want to find
|
|
47
|
+
:return: The index of the node in the list of nodes.
|
|
48
|
+
"""
|
|
49
|
+
res=None
|
|
50
|
+
|
|
51
|
+
if (Indices in self.Node):
|
|
52
|
+
res=0
|
|
53
|
+
while (self.Node[res]!=Indices):
|
|
54
|
+
res=res+1
|
|
55
|
+
return res
|
|
56
|
+
|
|
57
|
+
def Root(self):
|
|
58
|
+
"""
|
|
59
|
+
It returns the roots of the graph.
|
|
60
|
+
:return: The roots of the graph.
|
|
61
|
+
"""
|
|
62
|
+
res=[]
|
|
63
|
+
for i in self.AdjMat.keys():
|
|
64
|
+
if (sum(self.AdjMat[i])<=self.AdjMat[i][i]):
|
|
65
|
+
res.append(i)
|
|
66
|
+
return res
|
|
67
|
+
|
|
68
|
+
def Leaves(self):
|
|
69
|
+
"""
|
|
70
|
+
The function `Leaves` returns a list of all the leaf nodes in the graph
|
|
71
|
+
:return: The function `Leaves` returns a list of all the leaf nodes in the graph.
|
|
72
|
+
"""
|
|
73
|
+
res=[]
|
|
74
|
+
# Checking if the node is a leaf node.
|
|
75
|
+
for j in range(len(self.AdjMat)):
|
|
76
|
+
Temp=0
|
|
77
|
+
# Iterating over the keys of the dictionary `self.AdjMat`.
|
|
78
|
+
for i in range(len(self.AdjMat)):
|
|
79
|
+
# Checking if the node is a leaf node.
|
|
80
|
+
if (i!=j):
|
|
81
|
+
Temp+=self.AdjMat[i][j]
|
|
82
|
+
if (Temp==0):#((Temp==0) and (self.RelMat[0][j]==1)):
|
|
83
|
+
res.append(j)
|
|
84
|
+
return res
|
|
85
|
+
|
|
86
|
+
def Update(self,ID_P=None ):
|
|
87
|
+
"""
|
|
88
|
+
If the number of nodes is less than the maximum number of nodes, then add the new node to the
|
|
89
|
+
list of nodes
|
|
90
|
+
|
|
91
|
+
CORRECTION-01 (cf. CORRECTIONS.md) : ``ID_P`` devient optionnel et prend ``ID_G``
|
|
92
|
+
par defaut. Avant, ``NewRelation`` appelait ``self.Update()`` sans argument,
|
|
93
|
+
donc TOUTE creation de relation levait ``TypeError``.
|
|
94
|
+
"""
|
|
95
|
+
if ID_P is None: # CORRECTION-01 : generateur d'etiquettes par defaut
|
|
96
|
+
ID_P = ID_G
|
|
97
|
+
n=len(self.RelMat[0])
|
|
98
|
+
if (n>0):
|
|
99
|
+
Test=(len(self.Node)<=self.NNode-2)
|
|
100
|
+
Test=Test or ((self.RelMat[1][-1] in self.Node) and (self.RelMat[2][-1] in self.Node))
|
|
101
|
+
Test=Test or ((not(self.RelMat[1][-1] in self.Node) or not(self.RelMat[2][-1] in self.Node)) and (len(self.Node)<=self.NNode-1))
|
|
102
|
+
if not(Test):
|
|
103
|
+
del(self.RelMat[0][-1])
|
|
104
|
+
del(self.RelMat[1][-1])
|
|
105
|
+
del(self.RelMat[2][-1])
|
|
106
|
+
del(self.RelMat[3][-1])
|
|
107
|
+
del(self.RelMat[4][-1])
|
|
108
|
+
del(self.RelMat[5][-1])
|
|
109
|
+
else:
|
|
110
|
+
if not(self.RelMat[1][-1] in self.Node):
|
|
111
|
+
self.Node.append(self.RelMat[1][-1])
|
|
112
|
+
# Appending the label of the node to the list of labels.
|
|
113
|
+
self.Label.append(ID_P(1))
|
|
114
|
+
for i in range(len(self.Node)-1):
|
|
115
|
+
self.AdjMat[i].append(0)
|
|
116
|
+
self.AdjMat[len(self.Node)-1]=[0 for i in range(len(self.Node))]
|
|
117
|
+
if not(self.RelMat[2][-1] in self.Node):
|
|
118
|
+
self.Node.append(self.RelMat[2][-1])
|
|
119
|
+
# Appending the label of the node to the list of labels.
|
|
120
|
+
self.Label.append(ID_P(self.RelMat[0][-1]))
|
|
121
|
+
for i in range(len(self.Node)-1):
|
|
122
|
+
self.AdjMat[i].append(0)
|
|
123
|
+
self.AdjMat[len(self.Node)-1]=[0 for i in range(len(self.Node))]
|
|
124
|
+
if (self.RelMat[0][-1]>=0):
|
|
125
|
+
self.IdxTable[0].append(n-1)
|
|
126
|
+
self.IdxTable[1].append(self.IdxNode(self.RelMat[1][-1]))
|
|
127
|
+
self.IdxTable[2].append(self.IdxNode(self.RelMat[2][-1]))
|
|
128
|
+
self.AdjMat[self.IdxTable[1][-1]][self.IdxTable[2][-1]]=1
|
|
129
|
+
|
|
130
|
+
def InOrder2(self,xx=[1,3,2],yy=[1,2,30]):
|
|
131
|
+
"""
|
|
132
|
+
The function `InOrder2` takes two lists of numbers as input and returns `True` if the first list
|
|
133
|
+
is in ascending order and the second list is in descending order
|
|
134
|
+
|
|
135
|
+
:param xx: the list of x-coordinates of the points in the first polygon
|
|
136
|
+
:param yy: the list of the values of the nodes in the tree
|
|
137
|
+
:return: True or False
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
Examples:
|
|
141
|
+
---------
|
|
142
|
+
|
|
143
|
+
>>> FaultTree.InOrder2(None, [1,3,2], [1,2,30])
|
|
144
|
+
False
|
|
145
|
+
"""
|
|
146
|
+
res=True
|
|
147
|
+
i=0
|
|
148
|
+
while ((res==True) and (i<min(len(xx),len(yy)))):
|
|
149
|
+
res=(res and (xx[i]<=yy[i]))
|
|
150
|
+
i=i+1
|
|
151
|
+
return res
|
|
152
|
+
|
|
153
|
+
def Sort(self):
|
|
154
|
+
"""
|
|
155
|
+
It sorts the relations in the order of the nodes in the graph
|
|
156
|
+
"""
|
|
157
|
+
Temp1=[]
|
|
158
|
+
Temp2=[]
|
|
159
|
+
for i in range(len(self.IdxTable[0])):
|
|
160
|
+
j=0
|
|
161
|
+
for k in range(len(self.IdxTable[0])):
|
|
162
|
+
#if (self.InOrder2(self.RelMat[2][k],self.RelMat[1][i]) and (self.IdxTable[2][k]!=self.IdxTable[1][i])):
|
|
163
|
+
Test=(self.AdjMat[self.IdxNode(self.RelMat[2][k])][self.IdxNode(self.RelMat[1][i])]==1)
|
|
164
|
+
Test=Test or (self.InOrder2(self.RelMat[2][k],self.RelMat[1][i]))
|
|
165
|
+
Test=Test and (self.IdxTable[2][k]!=self.IdxTable[1][i])
|
|
166
|
+
if Test:
|
|
167
|
+
j=j+1
|
|
168
|
+
while (j in Temp1):
|
|
169
|
+
j=j+1
|
|
170
|
+
Temp1.append(j)
|
|
171
|
+
Temp2.append(0)
|
|
172
|
+
for i in range(len(self.IdxTable[0])):
|
|
173
|
+
Temp2[int(Temp1[i])]=i
|
|
174
|
+
Temp3=[[],[],[]]
|
|
175
|
+
Temp4=[[],[],[],[],[],[]]
|
|
176
|
+
for i in range(len(self.IdxTable[0])):
|
|
177
|
+
Temp3[0].append(i)
|
|
178
|
+
Temp3[1].append(self.IdxTable[1][int(Temp2[i])])
|
|
179
|
+
Temp3[2].append(self.IdxTable[2][int(Temp2[i])])
|
|
180
|
+
Temp4[0].append(self.RelMat[0][int(Temp2[i])])
|
|
181
|
+
Temp4[1].append(self.RelMat[1][int(Temp2[i])])
|
|
182
|
+
Temp4[2].append(self.RelMat[2][int(Temp2[i])])
|
|
183
|
+
Temp4[3].append(self.RelMat[3][int(Temp2[i])])
|
|
184
|
+
Temp4[4].append(self.RelMat[4][int(Temp2[i])])
|
|
185
|
+
Temp4[5].append(self.RelMat[5][int(Temp2[i])])
|
|
186
|
+
self.IdxTable=Temp3.copy()
|
|
187
|
+
self.RelMat=Temp4.copy()
|
|
188
|
+
|
|
189
|
+
def NewRelation(self,Port=1,IndicesIn=None,IndicesOut=None,Orders=None,Times=None,IndicesPrincipal=None):
|
|
190
|
+
"""
|
|
191
|
+
It takes in a list of lists, and appends a list to the end of the list of lists
|
|
192
|
+
|
|
193
|
+
:param Port: The port number of the relation, defaults to 1 (optional)
|
|
194
|
+
:param IndicesIn: The indices of the nodes that are input to the relation
|
|
195
|
+
:param IndicesOut: The indices of the output nodes
|
|
196
|
+
:param Orders: a list of the orders of the relations
|
|
197
|
+
:param Times: The time at which the relation is applied
|
|
198
|
+
:param IndicesPrincipal: This is a list of indices that are the principal indices of the relation
|
|
199
|
+
"""
|
|
200
|
+
if (IndicesIn!=None) and (IndicesOut!=None):
|
|
201
|
+
if True:#(len(IndicesIn)==self.NNode) and (len(IndicesOut)==self.NNode):
|
|
202
|
+
self.RelMat[0].append(Port)
|
|
203
|
+
self.RelMat[1].append(IndicesIn)
|
|
204
|
+
self.RelMat[2].append(IndicesOut)
|
|
205
|
+
self.RelMat[3].append(Orders)
|
|
206
|
+
self.RelMat[4].append(Times)
|
|
207
|
+
self.RelMat[5].append(IndicesPrincipal)
|
|
208
|
+
self.Update()
|
|
209
|
+
self.Sort()
|
|
210
|
+
#print(self.RelMat)
|
|
211
|
+
|
|
212
|
+
def ViewGraph(self,ID_P,Dir=None):
|
|
213
|
+
"""
|
|
214
|
+
It takes a graph and returns a graph with the same nodes and edges, but with the nodes labeled
|
|
215
|
+
with their index in the original graph.
|
|
216
|
+
|
|
217
|
+
:param Dir: the directory where the graph will be saved
|
|
218
|
+
"""
|
|
219
|
+
# CORRECTION-04 : import paresseux de la pile graphique optionnelle
|
|
220
|
+
try:
|
|
221
|
+
import networkx as nx
|
|
222
|
+
import matplotlib.pyplot as plt
|
|
223
|
+
except ImportError as exc:
|
|
224
|
+
raise ImportError(
|
|
225
|
+
"ViewGraph requires the optional visualization extras: "
|
|
226
|
+
"pip install matplotlib networkx"
|
|
227
|
+
) from exc
|
|
228
|
+
G=nx.DiGraph()
|
|
229
|
+
GNode={}
|
|
230
|
+
nn=len(self.Node)
|
|
231
|
+
for i in self.AdjMat.keys():
|
|
232
|
+
for j in range(len(self.AdjMat[i])):
|
|
233
|
+
if (self.AdjMat[i][j]==1):
|
|
234
|
+
GNode[nn-1-self.IdxNode(self.Node[i])]=str(nn-1-self.IdxNode(self.Node[i]))+':'+self.Label[i]
|
|
235
|
+
GNode[nn-1-self.IdxNode(self.Node[j])]=str(nn-1-self.IdxNode(self.Node[j]))+':'+self.Label[j]
|
|
236
|
+
G.add_edge(GNode[nn-1-self.IdxNode(self.Node[i])],GNode[nn-1-self.IdxNode(self.Node[j])])
|
|
237
|
+
#G.add_edge(str(nn-1-self.IdxNode(self.Node[i]))+':'+self.Label[i],str(nn-1-self.IdxNode(self.Node[j]))+':'+self.Label[j])
|
|
238
|
+
#G.add_edge(str(self.Node[j]),str(self.Node[i]))
|
|
239
|
+
#CompleteNode=self.Node.copy()
|
|
240
|
+
|
|
241
|
+
mm=nn
|
|
242
|
+
for i in range(nn):
|
|
243
|
+
#print("yeah !")
|
|
244
|
+
#print(self.Node[i])
|
|
245
|
+
for j in range(nn):
|
|
246
|
+
if (i!=j) and self.InOrder2(self.Node[i],self.Node[j]):
|
|
247
|
+
G.add_edge(GNode[nn-1-self.IdxNode(self.Node[i])],GNode[nn-1-self.IdxNode(self.Node[j])])
|
|
248
|
+
for j in range(self.NNode):
|
|
249
|
+
Temp=[0 for k in range(self.NNode)]
|
|
250
|
+
Temp[j]=1
|
|
251
|
+
if (self.InOrder2(Temp,self.Node[i])) and (Temp!=self.Node[i]):
|
|
252
|
+
#print(Temp)
|
|
253
|
+
if not(Temp in self.Node):
|
|
254
|
+
# Adding a node to the graph.
|
|
255
|
+
GNode[mm]=str(mm)+':'+ID_P(1)
|
|
256
|
+
G.add_edge(GNode[mm],GNode[nn-1-self.IdxNode(self.Node[i])])
|
|
257
|
+
mm+=1
|
|
258
|
+
#G.add_edge(str(self.Node[i]),str(Temp))
|
|
259
|
+
#CompleteNode.append(Temp)
|
|
260
|
+
|
|
261
|
+
#print(G.adj)
|
|
262
|
+
#fig=plt.figure(figsize=(5,5))
|
|
263
|
+
plt.subplots(figsize=(10, 10))
|
|
264
|
+
plt.clf() # Efface le contenu de la figure courante
|
|
265
|
+
nx.draw_networkx(G,pos=nx.circular_layout(G),node_size=(10**4)/2)
|
|
266
|
+
#nx.draw(G)
|
|
267
|
+
#nx.draw(G,pos=nx.circular_layout(G),node_color='r',edge_color='b')
|
|
268
|
+
plt.axis('off')
|
|
269
|
+
#plt.grid(False)
|
|
270
|
+
if (Dir!=None):
|
|
271
|
+
plt.savefig(Dir+"AD.png")
|
|
272
|
+
plt.savefig(Dir+"AD.pdf",format="pdf")
|
|
273
|
+
plt.show()
|
|
274
|
+
|
|
275
|
+
"""
|
|
276
|
+
Dir="E:/Pedagogie/Encadrement/EncadrementEnsai/MasterRThese/20192020/TadieBenjaulys/"
|
|
277
|
+
MyTree=FaultTree(2)
|
|
278
|
+
#MyTree.NewRelation(1,[1,0],[1,0])
|
|
279
|
+
#MyTree.NewRelation(1,[0,1],[0,1])
|
|
280
|
+
MyTree.NewRelation(4,[0,1],[1,1])
|
|
281
|
+
MyTree.NewRelation(3,[1,1],[1,1])
|
|
282
|
+
|
|
283
|
+
print(MyTree.NNode)
|
|
284
|
+
print(MyTree.Leaves())
|
|
285
|
+
print(MyTree.Node)
|
|
286
|
+
print(MyTree.IdxTable)
|
|
287
|
+
print(MyTree.RelMat)
|
|
288
|
+
print(MyTree.AdjMat)
|
|
289
|
+
print(MyTree.Root())
|
|
290
|
+
MyTree.ViewGraph(Dir)
|
|
291
|
+
"""
|