Skip to content

Commit 46a829d

Browse files
authored
Add DAG generater
1 parent bddea4e commit 46a829d

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

cyaron/graph.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)