@@ -39,6 +39,15 @@ def __init__(self, point_count, directed=False):
3939 """
4040 self .directed = directed
4141 self .edges = [[] for i in range (point_count + 1 )]
42+
43+ def edge_count (self ):
44+ """edge_count(self) -> int
45+ Return the count of the edges in the graph.
46+ """
47+ cnt = sum (len (node ) for node in self .edges )
48+ if not self .directed :
49+ cnt //= 2
50+ return cnt
4251
4352 def to_str (self , ** kwargs ):
4453 """to_str(self, **kwargs) -> str
@@ -146,6 +155,9 @@ def tree(point_count, chain=0, flower=0, **kwargs):
146155 int/float weight_gen()
147156 = lambda: random.randint(weight_limit[0], weight_limit[1])
148157 -> the generator of the weights. It should return the weight. The default way is to use the random.randint()
158+ int father_gen(cur)
159+ = lambda cur: random.randrange(1, cur)
160+ -> the generator of the fathers of current point.
149161 """
150162 directed = kwargs .get ("directed" , False )
151163 weight_limit = kwargs .get ("weight_limit" , (1 , 1 ))
@@ -154,6 +166,7 @@ def tree(point_count, chain=0, flower=0, **kwargs):
154166 weight_gen = kwargs .get (
155167 "weight_gen" , lambda : random .randint (
156168 weight_limit [0 ], weight_limit [1 ]))
169+ father_gen = kwargs .get ("father_gen" , lambda cur : random .randrange (1 , cur ))
157170
158171 if not 0 <= chain <= 1 or not 0 <= flower <= 1 :
159172 raise Exception ("chain and flower must be between 0 and 1" )
@@ -174,7 +187,7 @@ def tree(point_count, chain=0, flower=0, **kwargs):
174187 for i in range (chain_count + 2 , chain_count + flower_count + 2 ):
175188 graph .add_edge (1 , i , weight = weight_gen ())
176189 for i in range (point_count - random_count + 1 , point_count + 1 ):
177- u = random . randrange ( 1 , i )
190+ u = father_gen ( i )
178191 graph .add_edge (u , i , weight = weight_gen ())
179192
180193 return graph
@@ -256,6 +269,11 @@ def graph(point_count, edge_count, **kwargs):
256269 directed = kwargs .get ("directed" , False )
257270 self_loop = kwargs .get ("self_loop" , True )
258271 repeated_edges = kwargs .get ("repeated_edges" , True )
272+ if not repeated_edges :
273+ max_edge = Graph ._calc_max_edge (point_count , directed , self_loop )
274+ if edge_count > max_edge :
275+ raise Exception ("the number of edges of this kind of graph which has %d vertexes must be less than or equal to %d." % (point_count , max_edge ))
276+
259277 weight_limit = kwargs .get ("weight_limit" , (1 , 1 ))
260278 if not list_like (weight_limit ):
261279 weight_limit = (1 , weight_limit )
@@ -286,7 +304,7 @@ def graph(point_count, edge_count, **kwargs):
286304 @staticmethod
287305 def DAG (point_count , edge_count , ** kwargs ):
288306 """DAG(point_count, edge_count, **kwargs) -> Graph
289- Factory method. Return a graph with point_count vertexes and edge_count edges.
307+ Factory method. Return a directed connected graph with point_count vertexes and edge_count edges.
290308 int point_count -> the count of vertexes
291309 int edge_count -> the count of edges
292310 **kwargs(Keyword args):
@@ -305,6 +323,11 @@ def DAG(point_count, edge_count, **kwargs):
305323 self_loop = kwargs .get ("self_loop" , False ) # DAG default has no loop
306324 repeated_edges = kwargs .get ("repeated_edges" , True )
307325 loop = kwargs .get ("loop" , False )
326+ if not repeated_edges :
327+ max_edge = Graph ._calc_max_edge (point_count , not loop , self_loop )
328+ if edge_count > max_edge :
329+ raise Exception ("the number of edges of this kind of graph which has %d vertexes must be less than or equal to %d." % (point_count , max_edge ))
330+
308331 weight_limit = kwargs .get ("weight_limit" , (1 , 1 ))
309332 if not list_like (weight_limit ):
310333 weight_limit = (1 , weight_limit )
@@ -348,7 +371,7 @@ def DAG(point_count, edge_count, **kwargs):
348371 @staticmethod
349372 def UDAG (point_count , edge_count , ** kwargs ):
350373 """UDAG(point_count, edge_count, **kwargs) -> Graph
351- Factory method. Return a graph with point_count vertexes and edge_count edges.
374+ Factory method. Return a undirected connected graph with point_count vertexes and edge_count edges.
352375 int point_count -> the count of vertexes
353376 int edge_count -> the count of edges
354377 **kwargs(Keyword args):
@@ -365,6 +388,11 @@ def UDAG(point_count, edge_count, **kwargs):
365388
366389 self_loop = kwargs .get ("self_loop" , True )
367390 repeated_edges = kwargs .get ("repeated_edges" , True )
391+ if not repeated_edges :
392+ max_edge = Graph ._calc_max_edge (point_count , False , self_loop )
393+ if edge_count > max_edge :
394+ raise Exception ("the number of edges of this kind of graph which has %d vertexes must be less than or equal to %d." % (point_count , max_edge ))
395+
368396 weight_limit = kwargs .get ("weight_limit" , (1 , 1 ))
369397 if not list_like (weight_limit ):
370398 weight_limit = (1 , weight_limit )
@@ -398,6 +426,18 @@ def UDAG(point_count, edge_count, **kwargs):
398426 i += 1
399427
400428 return graph
429+
430+ @staticmethod
431+ def connected (point_count , edge_count , directed = False , ** kwargs ):
432+ """connected(point_count, edge_count, **kwargs) -> Graph
433+ Factory method. Return a connected graph with point_count vertexes
434+ int point_count -> the count of vertexes
435+ bool directed -> whether the graph is directed
436+ """
437+ if directed :
438+ return Graph .DAG (point_count , edge_count , ** kwargs )
439+ else :
440+ return Graph .UDAG (point_count , edge_count , ** kwargs )
401441
402442 @staticmethod
403443 def hack_spfa (point_count , ** kwargs ):
@@ -446,3 +486,12 @@ def hack_spfa(point_count, **kwargs):
446486 graph .add_edge (u , v , weight = weight_gen ())
447487
448488 return graph
489+
490+ @staticmethod
491+ def _calc_max_edge (point_count , directed , self_loop ):
492+ max_edge = point_count * (point_count - 1 )
493+ if not directed :
494+ max_edge //= 2
495+ if self_loop :
496+ max_edge += point_count
497+ return max_edge
0 commit comments