Summary
So I have a directed acyclic weighted graph where each edge has an input and output node, each node has an ID and I use a dictionary to map all ingoing edges to one node by its ID and another to do the same for all outgoing edges so when presented a node ID I can tell all ingoing and outgoing edges in ~O(1) time.
Requirement
I need to be able to add new random edges (i.e. connect two random nodes) in a way where it is guaranteed that no matter how big the graph is it wont be having any cycles.
What I tried
Since I'm in full control of how to build my graph I could sort it topologically and use Kahn's Algorithm to figure if for two uniformly randomly chosen nodes N1 and N2 the graph will result in a cycle in O(n) time. The problem with that is what if it does? I'd have to try a new random pair and repeat the process until I get lucky. This sounds as if it will scale really badly with the graph since the more edge dense the graph is the more likely it is that a new random one will create a cycle.
I have also read this post: Generating a random DAG , which is similar in nature to my problem, however, I can't use the suggested solution to connect nodes based on their IDs and only connect smaller to larger IDs (nodes that came before with nodes that are new) due to other constraints that I have on the problem.
Question
Is there a way to design a structure that will only ever allow me to randomly pick between nodes none of which, if connected through a new edge, will yield a cycle irrelevant of the memory overhead? This should then be an O(1) operation.