Test case generator for Tree using Disjoint-Set Union
In this article, we will generate test cases such that given set edges form a Tree. Below are the two conditions of the Tree:
- It should have one less edge than the number of vertices.
- There should be no cycle in it.
Approach: The idea is to run a loop and add one edge each time that is generated randomly, and for adding each edge we will check whether it is forming cycle or not. We can ensure that cycle is present or not with the help of Disjoint-Set Union. If adding any edges form cycle then ignore the current edges and generate the new set of edges. Else print the edges with randomly generated weight. Below is the implementation of the above approach:
C++
// C++ implementation to generate // test-case for the Tree #include <bits/stdc++.h> using namespace std; typedef long long int ll; #define fast ios_base::sync_with_stdio(false); #define MOD 1000000007 // Maximum Number Of Nodes #define MAXNODE 10; // Maximum Number Of testCases #define MAXT 10; // Maximum weight #define MAXWEIGHT 100; // Function for the path // compression technique ll find(ll parent[], ll x) { // If parent found if (parent[x] == x) return x; // Find parent recursively parent[x] = find(parent, parent[x]); // Return the parent node of x return parent[x]; } // Function to compute the union // by rank void merge(ll parent[], ll size[], ll x, ll y) { ll r1 = find(parent, x); ll r2 = find(parent, y); if (size[r1] < size[r2]) { parent[r1] = r2; size[r2] += size[r1]; } else { parent[r2] = r1; size[r1] += size[r2]; } } // Function to generate the // test-cases for the tree void generate() { ll t; t = 1 + rand () % MAXT; // Number of testcases cout << t << "\n" ; while (t--) { // for 2<=Number of Nodes<=MAXNODE // Randomly generate number of edges ll n = 2 + rand () % MAXNODE; ll i; cout << n << "\n" ; ll parent[n + 1]; ll size[n + 1]; // Initialise parent and // size arrays for (i = 1; i <= n; i++) { parent[i] = i; size[i] = 1; } vector<pair<ll, ll> > Edges; vector<ll> weights; // Now We have add N-1 edges for (i = 1; i <= n - 1; i++) { ll x = 1 + rand () % n; ll y = 1 + rand () % n; // Find edges till it does not // forms a cycle while (find(parent, x) == find(parent, y)) { x = 1 + rand () % n; y = 1 + rand () % n; } // Merge the nodes in tree merge(parent, size, x, y); // Store the current edge and weight Edges.push_back(make_pair(x, y)); ll w = 1 + rand () % MAXWEIGHT; weights.push_back(w); } // Print the set of edges // with weight for (i = 0; i < Edges.size(); i++) { cout << Edges[i].first << " " << Edges[i].second; cout << " " << weights[i]; cout << "\n" ; } } } // Driver Code int main() { // Uncomment the below line to store // the test data in a file // freopen ("output.txt", "w", stdout); // For random values every time srand ( time (NULL)); fast; generate(); } |
Python3
# Python3 implementation to generate # test-case for the Tree import random # Maximum Number Of Nodes MAXNODE = 10 # Maximum Number Of testCases MAXT = 10 # Maximum weight MAXWEIGHT = 100 # Function for the path # compression technique def find(parent, x): # If parent found if parent[x] = = x: return x # Find parent recursively parent[x] = find(parent, parent[x]) # Return the parent node of x return parent[x] # Function to compute the union # by rank def merge(parent, size, x, y): r1 = find(parent, x) r2 = find(parent, y) if size[r1] < size[r2]: parent[r1] = r2 size[r2] + = size[r1] else : parent[r2] = r1 size[r1] + = size[r2] # Function to generate the # test-cases for the tree def generate(): # Number of testcases t = random.randint( 1 , MAXT) print (t) for _ in range (t): # for 2<=Number of Nodes<=MAXNODE # Randomly generate number of edges n = random.randint( 2 , MAXNODE) print (n) parent = [i for i in range (n + 1 )] size = [ 1 for _ in range (n + 1 )] Edges = [] weights = [] # Now We have add N-1 edges for i in range (n - 1 ): x = random.randint( 1 , n) y = random.randint( 1 , n) # Find edges till it does not # forms a cycle while find(parent, x) = = find(parent, y): x = random.randint( 1 , n) y = random.randint( 1 , n) # Merge the nodes in tree merge(parent, size, x, y) # Store the current edge and weight Edges.append((x, y)) w = random.randint( 1 , MAXWEIGHT) weights.append(w) # Print the set of edges # with weight for i in range ( len (Edges)): print (Edges[i][ 0 ], Edges[i][ 1 ], weights[i]) # Driver Code if __name__ = = "__main__" : # Uncomment the below line to store # the test data in a file # open("output.txt", "w").close() # open("output.txt", "w").write(generate()) # For random values every time random.seed( None ) generate() # This code is contributed by Potta Lokesh |
Output:
1 10 4 2 67 8 3 64 6 5 31 7 6 77 8 2 64 9 2 44 5 9 10 1 6 71 10 7 32
Time Complexity: O(N*logN) Auxiliary Space: O(1)
Please Login to comment...