@@ -175,14 +175,16 @@ def add_edge(self, v1, v2, **kwargs):
175
175
:type v1: Vertex subclass
176
176
:param v2: second vertex (end if a directed graph)
177
177
:type v2: Vertex subclass
178
- :param kwargs: optional arguments to pass to ``connect``
178
+ :param kwargs: optional arguments to pass to ``Vertex. connect``
179
179
:return: edge
180
180
:rtype: Edge
181
181
182
- .. note:: This is a graph centric way of creating an edge. The
183
- alternative is the ``connect`` method of a vertex.
182
+ Create an edge between a vertex pair and adds it to the graph.
184
183
185
- :seealso: :meth:`Edge.connect`
184
+ This is a graph centric way of creating an edge. The
185
+ alternative is the ``connect`` method of a vertex.
186
+
187
+ :seealso: :meth:`Edge.connect` :meth:`Vertex.connect`
186
188
"""
187
189
if isinstance (v1 , str ):
188
190
v1 = self [v1 ]
@@ -1312,20 +1314,56 @@ class Edge:
1312
1314
edgelist of _each_ vertex.
1313
1315
- This class can be inherited to provide user objects with graph capability.
1314
1316
- Inheritance is an alternative to providing arbitrary user data.
1317
+
1318
+ An Edge points to a pair of vertices. At ``connect`` time the vertices
1319
+ get references back to the Edge object.
1320
+
1321
+ ``graph.add_edge(v1, v2)`` calls ``v1.connect(v2)``
1315
1322
"""
1316
1323
1317
- def __init__ (self , v1 , v2 , cost = None , data = None ):
1318
- if cost is None :
1319
- try :
1320
- self .cost = np .linalg .norm (v1 .coord - v2 .coord )
1321
- except TypeError :
1322
- self .cost = None
1323
- else :
1324
- self .cost = cost
1325
- self .data = data
1324
+ def __init__ (self , v1 = None , v2 = None , cost = None , data = None ):
1325
+ """
1326
+ Create an edge object
1327
+
1328
+ :param v1: start of the edge, defaults to None
1329
+ :type v1: Vertex subclass, optional
1330
+ :param v2: end of the edge, defaults to None
1331
+ :type v2: Vertex subclass, optional
1332
+ :param cost: edge cost, defaults to None
1333
+ :type cost: any, optional
1334
+ :param data: edge data, defaults to None
1335
+ :type data: any, optional
1336
+
1337
+ Creates an edge but does not connect it to the vertices or add it to the
1338
+ graph.
1339
+
1340
+ If vertices are given, and have associated coordinates, the edge cost
1341
+ will be computed according to the distance measure associated with the
1342
+ graph.
1343
+
1344
+ ``data`` is a way of associating any object with the edge, its value
1345
+ can be found as the ``.data`` attribute of the edge. An alternative
1346
+ approach is to subclass the ``Edge`` class.
1347
+
1348
+ .. note:: To compute edge cost from the vertices, the vertices must have
1349
+ been added to the graph.
1350
+
1351
+ :seealso: :meth:`Edge.connect` :meth:`Vertex.connect`
1352
+ """
1326
1353
self .v1 = v1
1327
1354
self .v2 = v2
1328
1355
1356
+ self .data = data
1357
+
1358
+ # try to compute edge cost as metric distance if not given
1359
+ if cost is not None :
1360
+ self .cost = cost
1361
+ elif not (v1 is None or v1 .coord is None or v2 is None or v2 .coord is None ):
1362
+ self .cost = v1 ._graph .metric (v1 .coord - v2 .coord )
1363
+ else :
1364
+ self .cost = None
1365
+
1366
+
1329
1367
def __repr__ (self ):
1330
1368
return str (self )
1331
1369
@@ -1336,6 +1374,36 @@ def __str__(self):
1336
1374
s += f" data={ self .data } "
1337
1375
return s
1338
1376
1377
+ def connect (self , v1 , v2 ):
1378
+ """
1379
+ Add edge to the graph
1380
+
1381
+ :param v1: start of the edge
1382
+ :type v1: Vertex subclass
1383
+ :param v2: end of the edge
1384
+ :type v2: Vertex subclass
1385
+
1386
+ The edge is added to the graph and connects vertices ``v1`` and ``v2``.
1387
+
1388
+ .. note:: The vertices must already be added to the graph.
1389
+ """
1390
+
1391
+ if v1 ._graph is None :
1392
+ raise ValueError ('vertex v1 does not belong to a graph' )
1393
+ if v2 ._graph is None :
1394
+ raise ValueError ('vertex v2 does not belong to a graph' )
1395
+ if not v1 ._graph is v2 ._graph :
1396
+ raise ValueError ('vertices must belong to the same graph' )
1397
+
1398
+ # connect edge to its vertices
1399
+ self .v1 = v1
1400
+ self .v2 = v2
1401
+
1402
+ # tell the vertices to add edge to their edgelists as appropriate for
1403
+ # DGraph or UGraph
1404
+ v1 .connect (v2 , edge = self )
1405
+
1406
+
1339
1407
def next (self , vertex ):
1340
1408
"""
1341
1409
Return other end of an edge
@@ -1459,10 +1527,10 @@ def connect(self, dest, edge=None, cost=None, data=None):
1459
1527
:param dest: The node to connect to
1460
1528
:type dest: ``Vertex`` subclass
1461
1529
:param edge: Use this as the edge object, otherwise a new ``Edge``
1462
- object is created, defaults to None
1530
+ object is created from the vertices being connected,
1531
+ and the ``cost`` and ``edge`` parameters, defaults to None
1463
1532
:type edge: ``Edge`` subclass, optional
1464
- :param cost: the cost to traverse this edge, required for planning
1465
- methods, defaults to None
1533
+ :param cost: the cost to traverse this edge, defaults to None
1466
1534
:type cost: float, optional
1467
1535
:param data: reference to arbitrary data associated with the edge,
1468
1536
defaults to None
@@ -1478,6 +1546,8 @@ def connect(self, dest, edge=None, cost=None, data=None):
1478
1546
- If the vertices subclass ``UVertex`` the edge is undirected, and if
1479
1547
they subclass ``DVertex`` the edge is directed.
1480
1548
- Vertices must both be of the same ``Vertex`` subclass
1549
+
1550
+ :seealso: :meth:`Edge`
1481
1551
"""
1482
1552
1483
1553
if not dest .__class__ .__bases__ [0 ] is self .__class__ .__bases__ [0 ]:
@@ -1486,7 +1556,9 @@ def connect(self, dest, edge=None, cost=None, data=None):
1486
1556
e = edge
1487
1557
else :
1488
1558
e = Edge (self , dest , cost = cost , data = data )
1559
+
1489
1560
self ._graph ._edgelist .add (e )
1561
+ self ._graph ._connectivitychange = True
1490
1562
self ._connectivitychange = True
1491
1563
1492
1564
return e
0 commit comments