@@ -274,6 +274,69 @@ def graph(point_count, edge_count, **kwargs):
274274 i += 1
275275 return graph
276276
277+ @staticmethod
278+ def DAG (point_count , edge_count , ** kwargs ):
279+ """DAG(point_count, edge_count, **kwargs) -> Graph
280+ Factory method. Return a graph with point_count vertexes and edge_count edges.
281+ int point_count -> the count of vertexes
282+ int edge_count -> the count of edges
283+ **kwargs(Keyword args):
284+ bool self_loop = True -> whether to allow self loops or not
285+ bool repeated_edges = True -> whether to allow repeated edges or not
286+ bool directed = False -> whether the chain is directed(true:directed,false:not directed)
287+ (int,int) weight_limit = (1,1) -> the limit of weight. index 0 is the min limit, and index 1 is the max limit(both included)
288+ int weight_limit -> If you use a int for this arg, it means the max limit of the weight(included)
289+ int/float weight_gen()
290+ = lambda: random.randint(weight_limit[0], weight_limit[1])
291+ -> the generator of the weights. It should return the weight. The default way is to use the random.randint()
292+ """
293+ if point_count > edge_count - 1 :
294+ raise Exception ("the number of edges of DAG must more than the number of nodes + 1" )
295+
296+ directed = kwargs .get ("directed" , False )
297+ self_loop = kwargs .get ("self_loop" , True )
298+ repeated_edges = kwargs .get ("repeated_edges" , True )
299+ weight_limit = kwargs .get ("weight_limit" , (1 , 1 ))
300+ if not list_like (weight_limit ):
301+ weight_limit = (1 , weight_limit )
302+ weight_gen = kwargs .get (
303+ "weight_gen" , lambda : random .randint (
304+ weight_limit [0 ], weight_limit [1 ]))
305+
306+ used_edges = set ()
307+ edge_buf = [edge for edge in Graph .tree (point_count , weight_limit = weight_limit ).iterate_edges ()]
308+ graph = Graph (point_count , directed )
309+
310+ for edge in edge_buf :
311+ if random .randint (1 , 2 ) == 1 and directed :
312+ edge .start , edge .end = edge .end , edge .start
313+ graph .add_edge (edge .start , edge .end , weight = edge .weight )
314+
315+ if not repeated_edges :
316+ used_edges .add ((edge .start , edge .end ))
317+ if not directed :
318+ used_edges .add ((edge .end , edge .start ))
319+
320+ i = point_count - 1
321+ while i < edge_count :
322+ u = random .randint (1 , point_count )
323+ v = random .randint (1 , point_count )
324+
325+ if (not self_loop and u == v ) or (not repeated_edges and (u , v ) in used_edges ):
326+ # Then we generate a new pair of nodes
327+ continue
328+
329+ graph .add_edge (u , v , weight = weight_gen ())
330+
331+ if not repeated_edges :
332+ used_edges .add ((u , v ))
333+ if not directed :
334+ used_edges .add ((v , u ))
335+
336+ i += 1
337+
338+ return graph
339+
277340 @staticmethod
278341 def hack_spfa (point_count , ** kwargs ):
279342 """hack_spfa(point_count, **kwargs) -> None
0 commit comments