Home  >  Article  >  Backend Development  >  Compute all permutations of integers that form an acyclic graph according to given conditions

Compute all permutations of integers that form an acyclic graph according to given conditions

WBOY
WBOYforward
2023-09-07 11:37:02904browse

Compute all permutations of integers that form an acyclic graph according to given conditions

Counting stages within an integer N, forming an acyclic graph requires investigating every possible change and checking whether they form an acyclic graph according to given conditions. These conditions may be related to the structure of coordination graphs formed by changes, where the absence of cycles indicates acyclicity. This problem involves concepts from graph theory and can be solved by depth-first search or dynamic programming. Depth-first search works by investigating each stage recursively, and dynamic programming optimizes loops by storing intermediate results. The number of valid stages counted at the end shows the number of ways within an integer N that can be organized into an acyclic graph that satisfies predetermined conditions.

usage instructions

  • Depth First Search (DFS)

  • Dynamic programming

Depth First Search (DFS)

In the DFS method of generating groupings with a given operation, we start from the given number and recalculate until the value 1 is reached. We proceed as follows: if the number is indeed 2, we divide it by 2; if it is an odd number, we multiply it by 3 and add 1. We update the numbers to reflect the unused results and add them to the series. This process continues until the number reaches 1. The resulting sequence represents a repeating Collatz sequence for a given starting number. This approach allows us to track the progression of numbers as they change through repeated calculations, reveal patterns, and consider the behavior of Collatz sequences. It provides a simple and reproducible method to generate sequences and analyze the fascinating features of this mathematical marvel.

algorithm

  • Choose a starting hub to start traversing

  • Mark centers as visited to monitor which centers have proactively investigated.

  • Visit the unvisited neighbors of the central node in progress (if any). To determine the neighbors of an ongoing central node, you really need to know an infectious description of the graph (e.g., a proximity list or a proximity framework)

  • Assuming there are unvisited neighbors, choose one of them and rehash stages 2 to 4 from that neighbor (recursively)

  • Assuming there are no unvisited neighbors, go back to the past center and continue the investigation from that point (if possible). This step is crucial to explore all potential paths in the graph

  • Re-do the hashing in stages 2 to 5 until all central nodes in the graph have been visited. If the graph is not connected (contains multiple parts), you may need to do a depth-first search (DFS) starting from an unvisited central node.

The Chinese translation of

Example

is:

Example

#include <iostream>
#include <vector>

using namespace std;

void dfs(int node, vector<vector<int>>& graph, vector<bool>& visited) {
   visited[node] = true;
   cout << "Visited hub: " << node << endl;
   for (int neighbor : graph[node]) {
      if (!visited[neighbor]) {
         cout << "Moving to neighbor: " << neighbor << endl;
         dfs(neighbor, graph, visited);
      }
   }
}

int main() {
   vector<vector<int>> graph = {
      {1, 2},
      {0, 2, 3},
      {0, 1, 3},
      {1, 2, 4},
      {3}
   };
   int hubs = graph.size();
   vector<bool> visited(hubs, false);
   int startingHub = 0;
   cout << "DFS Traversal starting from hub " << startingHub << ":" << endl;
   dfs(startingHub, graph, visited);
   return 0;
}

Output

DFS Traversal starting from hub 0:
Visited hub: 0
Moving to neighbor: 1
Visited hub: 1
Moving to neighbor: 2
Visited hub: 2
Moving to neighbor: 3
Visited hub: 3
Moving to neighbor: 4
Visited hub: 4

Dynamic programming

In this approach, we can utilize dynamic programming to efficiently calculate the number of acyclic stages to reach N. We will define a DP table, where dp[i] represents the number of non-cyclic transitions ending with the number I.

algorithm

  • Investigate the problem and decide if it can be broken down into smaller sub-problems. If solving the same subproblem multiple times is inefficient, dynamic programming can improve the solution by remembering the solutions to the subproblems.

  • Express the arrangement of a larger problem as the arrangement of its sub-problems. This duplicate connection is the key to solving the problem using DP.

  • Given the duplicate connections, make a table or display to store the answers to the subquestions. This will prevent double counting.

  • Fill out the form starting with the smallest subproblem, usually in a bottom-up approach, or using memoization to store and retrieve the solution in a recursive process

  • When all subproblems are solved, separate the final arrangement from the DP table or memoized display.

The Chinese translation of

Example

is:

Example

#include <iostream>
#include <vector>
using namespace std;

int knapsackHelper(vector<vector<int>>& dp, vector<int>& weights, vector<int>& values, int n, int capacity) {
   if (n == 0 || capacity == 0) {
      return 0;
   }

   if (dp[n][capacity] != -1) {
      return dp[n][capacity];
   }

   if (weights[n - 1] <= capacity) {
      dp[n][capacity] = max(values[n - 1] + knapsackHelper(dp, weights, values, n - 1, capacity - weights[n - 1]),
                      knapsackHelper(dp, weights, values, n - 1, capacity));
   } else {
      dp[n][capacity] = knapsackHelper(dp, weights, values, n - 1, capacity);
   }

   return dp[n][capacity];
}

int knapsack(vector<int>& weights, vector<int>& values, int capacity) {
   int n = weights.size();
   vector<vector<int>> dp(n + 1, vector<int>(capacity + 1, -1));
   return knapsackHelper(dp, weights, values, n, capacity);
}

int main() {
   vector<int> weights = {10, 20, 30};
   vector<int> values = {60, 100, 120};
   int capacity = 50;
   cout << "Maximum value in Knapsack: " << knapsack(weights, values, capacity) << endl;
   return 0;
}

Output

Maximum value in Knapsack: 220

in conclusion

The stages of computing that acyclic graphs can be formed include studying different arrangements of integers to ensure that they satisfy a given condition. DFS explores stages recursively, while DP improves the loop through memoization. These two methods provide important ways to solve this problem. The choice of method depends on the constraints and the size of N. Through these methods, we can efficiently find the number of legal stages, helping us understand the way in which numbers can form acyclic graphs according to predetermined conditions.

The above is the detailed content of Compute all permutations of integers that form an acyclic graph according to given conditions. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:tutorialspoint.com. If there is any infringement, please contact admin@php.cn delete