How to calculate all possible cycles (all nodes must be visited once) on a graph? Hamilton circle - algorithm

I am trying to write a program which
outputs all possible cycles starting and ending with node 1 and visiting all other nodes exactly once.
Given is a complete undirected unweighted graph with N nodes.
For example:
n = 4 then
1-2-3-4, 1-2-4-3, 1-3-2-4, 1-3-4-2, 1-4-3-2, 1-4-2-3
My approach would be to use Hamilton-circle method to find out a possible combination and then iterate until all combinations are calculated.
I assume the complexity is (n-1)!
class Permutation
main {
string list1 = "1"
string list2 = "2,3,4"
l2 = list2.length()
init Permutation
permutaion.permute (list2, 0, n-1)!
print list1 + list2
}
permute(list2, start, end) {
if (start==end)
print list2
else
for (i=start, i<=end, i++)
list2 = swap(list2, start, i)
permute(list2, start+1, end)
list2 = swap(list2, start, i)
}
Thank you for your time and help!

Related

Find all possible paths between N set of nodes

I have N number of nodes at start and end where they can be paired as N number of sets (1 to 1, .., n to n, .., N to N). However, I have M stages (can be assumed as parallel stages) in between the start and end, and each stage has R number of nodes where R>=N.
If I consider start n node to end n node (i.e., n to n pair), I have to pass (M+1) hops to reach end node, and there are R^M possible paths. Thus, all possible paths for all pairs are N*R^M.
I weight each link as : the link between node i at stage m and node j at stage m+1 as w_{i,j}^{m,m+1}.
I want to write a MATLAB code to generate all possible paths each pair, i.e., N number of pairs. Can someone please help me?
I tried it only using exhaustive search just for 2 start and end nodes with 2 stages that have 3 nodes. But I don't know how to write this for a general network with effective way. Please help me !!!
Added: For example: N = M = 2, R = 3 I have R^M=2^3=9 possible paths for each pair. For both pairs, I have 18. For 1 to 1 pair, possible paths set is:
{1-1-1-1, 1-1-2-1,1-1-3-1
1-2-1-1, 1-2-2-1,1-2-3-1
1-3-1-1, 1-3-2-1,1-3-3-1}
and corresponding weights set is (0 represents start) :
{w_{1,1}^{0,1}-w_{1,1}^{1,2}-w_{1,1}^{2,3}; w_{1,1}^{0,1}-w_{1,2}^{1,2}-w_{2,1}^{2,3}; w_{1,1}^{0,1}-w_{1,3}^{1,2}-w_{3,1}^{2,3}, ........., w_{1,3}^{0,1}-w_{3,3}^{1,2}-w_{3,1}^{2,3}}
Same follows for the 2 to 2 pair.
Actually, my exhaustive search I generate each hop as matrix with randomly generated weights. From start to 1st hop: A=rand(2,3), then 1st hop to 2nd hop: B=rand(3,3), and 2nd to end: C=rand(3,2)
Okay, so per your update you just want to generate the Cartesian product
{i} X {1, 2, ..., R}^M X {j}
A quick-and-dirty approach would be to do something like this:
paths = zeros(R ^ M, M + 2); # initialize array
paths(:, 1) = i; # start all paths at node i
paths(:, M+2) = j; # end all paths at node j
for c = 1:M
for r = 1:(R ^ M)
paths(r, c+1) = mod(idivide(r-1, R ^ (c-1)), R)+1 ;
end
end
You could then loop through paths and calculate the weights.

How to keep track of depth in breadth first search?

I have a tree as input to the breadth first search and I want to know as the algorithm progresses at which level it is?
# Breadth First Search Implementation
graph = {
'A':['B','C','D'],
'B':['A'],
'C':['A','E','F'],
'D':['A','G','H'],
'E':['C'],
'F':['C'],
'G':['D'],
'H':['D']
}
def breadth_first_search(graph,source):
"""
This function is the Implementation of the breadth_first_search program
"""
# Mark each node as not visited
mark = {}
for item in graph.keys():
mark[item] = 0
queue, output = [],[]
# Initialize an empty queue with the source node and mark it as explored
queue.append(source)
mark[source] = 1
output.append(source)
# while queue is not empty
while queue:
# remove the first element of the queue and call it vertex
vertex = queue[0]
queue.pop(0)
# for each edge from the vertex do the following
for vrtx in graph[vertex]:
# If the vertex is unexplored
if mark[vrtx] == 0:
queue.append(vrtx) # mark it as explored
mark[vrtx] = 1 # and append it to the queue
output.append(vrtx) # fill the output vector
return output
print breadth_first_search(graph, 'A')
It takes tree as an input graph, what I want is, that at each iteration it should print out the current level which is being processed.
Actually, we don't need an extra queue to store the info on the current depth, nor do we need to add null to tell whether it's the end of current level. We just need to know how many nodes the current level contains, then we can deal with all the nodes in the same level, and increase the level by 1 after we are done processing all the nodes on the current level.
int level = 0;
Queue<Node> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
int level_size = queue.size();
while (level_size-- != 0) {
Node temp = queue.poll();
if (temp.right != null) queue.add(temp.right);
if (temp.left != null) queue.add(temp.left);
}
level++;
}
You don't need to use extra queue or do any complicated calculation to achieve what you want to do. This idea is very simple.
This does not use any extra space other than queue used for BFS.
The idea I am going to use is to add null at the end of each level. So the number of nulls you encountered +1 is the depth you are at. (of course after termination it is just level).
int level = 0;
Queue <Node> queue = new LinkedList<>();
queue.add(root);
queue.add(null);
while(!queue.isEmpty()){
Node temp = queue.poll();
if(temp == null){
level++;
queue.add(null);
if(queue.peek() == null) break;// You are encountering two consecutive `nulls` means, you visited all the nodes.
else continue;
}
if(temp.right != null)
queue.add(temp.right);
if(temp.left != null)
queue.add(temp.left);
}
Maintain a queue storing the depth of the corresponding node in BFS queue. Sample code for your information:
queue bfsQueue, depthQueue;
bfsQueue.push(firstNode);
depthQueue.push(0);
while (!bfsQueue.empty()) {
f = bfsQueue.front();
depth = depthQueue.front();
bfsQueue.pop(), depthQueue.pop();
for (every node adjacent to f) {
bfsQueue.push(node), depthQueue.push(depth+1);
}
}
This method is simple and naive, for O(1) extra space you may need the answer post by #stolen_leaves.
Try having a look at this post. It keeps track of the depth using the variable currentDepth
https://stackoverflow.com/a/16923440/3114945
For your implementation, keep track of the left most node and a variable for the depth. Whenever the left most node is popped from the queue, you know you hit a new level and you increment the depth.
So, your root is the leftMostNode at level 0. Then the left most child is the leftMostNode. As soon as you hit it, it becomes level 1. The left most child of this node is the next leftMostNode and so on.
With this Python code you can maintain the depth of each node from the root by increasing the depth only after you encounter a node of new depth in the queue.
queue = deque()
marked = set()
marked.add(root)
queue.append((root,0))
depth = 0
while queue:
r,d = queue.popleft()
if d > depth: # increase depth only when you encounter the first node in the next depth
depth += 1
for node in edges[r]:
if node not in marked:
marked.add(node)
queue.append((node,depth+1))
If your tree is perfectly ballanced (i.e. each node has the same number of children) there's actually a simple, elegant solution here with O(1) time complexity and O(1) space complexity. The main usecase where I find this helpful is in traversing a binary tree, though it's trivially adaptable to other tree sizes.
The key thing to realize here is that each level of a binary tree contains exactly double the quantity of nodes compared to the previous level. This allows us to calculate the total number of nodes in any tree given the tree's depth. For instance, consider the following tree:
This tree has a depth of 3 and 7 total nodes. We don't need to count the number of nodes to figure this out though. We can compute this in O(1) time with the formaula: 2^d - 1 = N, where d is the depth and N is the total number of nodes. (In a ternary tree this is 3^d - 1 = N, and in a tree where each node has K children this is K^d - 1 = N). So in this case, 2^3 - 1 = 7.
To keep track of depth while conducting a breadth first search, we simply need to reverse this calculation. Whereas the above formula allows us to solve for N given d, we actually want to solve for d given N. For instance, say we're evaluating the 5th node. To figure out what depth the 5th node is on, we take the following equation: 2^d - 1 = 5, and then simply solve for d, which is basic algebra:
If d turns out to be anything other than a whole number, just round up (the last node in a row is always a whole number). With that all in mind, I propose the following algorithm to identify the depth of any given node in a binary tree during breadth first traversal:
Let the variable visited equal 0.
Each time a node is visited, increment visited by 1.
Each time visited is incremented, calculate the node's depth as depth = round_up(log2(visited + 1))
You can also use a hash table to map each node to its depth level, though this does increase the space complexity to O(n). Here's a PHP implementation of this algorithm:
<?php
$tree = [
['A', [1,2]],
['B', [3,4]],
['C', [5,6]],
['D', [7,8]],
['E', [9,10]],
['F', [11,12]],
['G', [13,14]],
['H', []],
['I', []],
['J', []],
['K', []],
['L', []],
['M', []],
['N', []],
['O', []],
];
function bfs($tree) {
$queue = new SplQueue();
$queue->enqueue($tree[0]);
$visited = 0;
$depth = 0;
$result = [];
while ($queue->count()) {
$visited++;
$node = $queue->dequeue();
$depth = ceil(log($visited+1, 2));
$result[$depth][] = $node[0];
if (!empty($node[1])) {
foreach ($node[1] as $child) {
$queue->enqueue($tree[$child]);
}
}
}
print_r($result);
}
bfs($tree);
Which prints:
Array
(
[1] => Array
(
[0] => A
)
[2] => Array
(
[0] => B
[1] => C
)
[3] => Array
(
[0] => D
[1] => E
[2] => F
[3] => G
)
[4] => Array
(
[0] => H
[1] => I
[2] => J
[3] => K
[4] => L
[5] => M
[6] => N
[7] => O
)
)
Set a variable cnt and initialize it to the size of the queue cnt=queue.size(), Now decrement cnt each time you do a pop. When cnt gets to 0, increase the depth of your BFS and then set cnt=queue.size() again.
In Java it would be something like this.
The idea is to look at the parent to decide the depth.
//Maintain depth for every node based on its parent's depth
Map<Character,Integer> depthMap=new HashMap<>();
queue.add('A');
depthMap.add('A',0); //this is where you start your search
while(!queue.isEmpty())
{
Character parent=queue.remove();
List<Character> children=adjList.get(parent);
for(Character child :children)
{
if (child.isVisited() == false) {
child.visit(parent);
depthMap.add(child,depthMap.get(parent)+1);//parent's depth + 1
}
}
}
Use a dictionary to keep track of the level (distance from start) of each node when exploring the graph.
Example in Python:
from collections import deque
def bfs(graph, start):
queue = deque([start])
levels = {start: 0}
while queue:
vertex = queue.popleft()
for neighbour in graph[vertex]:
if neighbour in levels:
continue
queue.append(neighbour)
levels[neighbour] = levels[vertex] + 1
return levels
I write a simple and easy to read code in python.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def dfs(self, root):
assert root is not None
queue = [root]
level = 0
while queue:
print(level, [n.val for n in queue if n is not None])
mark = len(queue)
for i in range(mark):
n = queue[i]
if n.left is not None:
queue.append(n.left)
if n.right is not None:
queue.append(n.right)
queue = queue[mark:]
level += 1
Usage,
# [3,9,20,null,null,15,7]
n3 = TreeNode(3)
n9 = TreeNode(9)
n20 = TreeNode(20)
n15 = TreeNode(15)
n7 = TreeNode(7)
n3.left = n9
n3.right = n20
n20.left = n15
n20.right = n7
DFS().dfs(n3)
Result
0 [3]
1 [9, 20]
2 [15, 7]
I don't see this method posted so far, so here's a simple one:
You can "attach" the level to the node. For e.g., in case of a tree, instead of the typical queue<TreeNode*>, use a queue<pair<TreeNode*,int>> and then push the pairs of {node,level}s into it. The root would be pushed in as, q.push({root,0}), its children as q.push({root->left,1}), q.push({root->right,1}) and so on...
We don't need to modify the input, append nulls or even (asymptotically speaking) use any extra space just to track the levels.

How to implement depth first search for graph with a non-recursive approach

I have spent lots of time on this issue. However, I can only find solutions with non-recursive methods for a tree: Non recursive for tree, or a recursive method for the graph, Recursive for graph.
And lots of tutorials (I don't provide those links here) don't provide the approaches as well. Or the tutorial is totally incorrect. Please help me.
Updated:
It's really hard to describe:
If I have an undirected graph:
1
/ | \
4 | 2
3 /
1-- 2-- 3 --1 is a cycle.
At the step: 'push the neighbors of the popped vertex into the stack', what's the order in which the vertices should be pushed?
If the pushed order is 2, 4, 3, the vertices in the stack are:
| |
|3|
|4|
|2|
_
After popping the nodes, we get the result: 1 -> 3 -> 4 -> 2 instead of 1--> 3 --> 2 -->4.
It's incorrect. What condition should I add to stop this scenario?
A DFS without recursion is basically the same as BFS - but use a stack instead of a queue as the data structure.
The thread Iterative DFS vs Recursive DFS and different elements order handles with both approaches and the difference between them (and there is! you will not traverse the nodes in the same order!)
The algorithm for the iterative approach is basically:
DFS(source):
s <- new stack
visited <- {} // empty set
s.push(source)
while (s is not empty):
current <- s.pop()
if (current is in visited):
continue
visited.add(current)
// do something with current
for each node v such that (current,v) is an edge:
s.push(v)
This is not an answer, but an extended comment, showing the application of the algorithm in #amit's answer to the graph in the current version of the question, assuming 1 is the start node and its neighbors are pushed in the order 2, 4, 3:
1
/ | \
4 | 2
3 /
Actions Stack Visited
======= ===== =======
push 1 [1] {}
pop and visit 1 [] {1}
push 2, 4, 3 [2, 4, 3] {1}
pop and visit 3 [2, 4] {1, 3}
push 1, 2 [2, 4, 1, 2] {1, 3}
pop and visit 2 [2, 4, 1] {1, 3, 2}
push 1, 3 [2, 4, 1, 1, 3] {1, 3, 2}
pop 3 (visited) [2, 4, 1, 1] {1, 3, 2}
pop 1 (visited) [2, 4, 1] {1, 3, 2}
pop 1 (visited) [2, 4] {1, 3, 2}
pop and visit 4 [2] {1, 3, 2, 4}
push 1 [2, 1] {1, 3, 2, 4}
pop 1 (visited) [2] {1, 3, 2, 4}
pop 2 (visited) [] {1, 3, 2, 4}
Thus applying the algorithm pushing 1's neighbors in the order 2, 4, 3 results in visit order 1, 3, 2, 4. Regardless of the push order for 1's neighbors, 2 and 3 will be adjacent in the visit order because whichever is visited first will push the other, which is not yet visited, as well as 1 which has been visited.
The DFS logic should be:
1) if the current node is not visited, visit the node and mark it as visited
2) for all its neighbors that haven't been visited, push them to the stack
For example, let's define a GraphNode class in Java:
class GraphNode {
int index;
ArrayList<GraphNode> neighbors;
}
and here is the DFS without recursion:
void dfs(GraphNode node) {
// sanity check
if (node == null) {
return;
}
// use a hash set to mark visited nodes
Set<GraphNode> set = new HashSet<GraphNode>();
// use a stack to help depth-first traversal
Stack<GraphNode> stack = new Stack<GraphNode>();
stack.push(node);
while (!stack.isEmpty()) {
GraphNode curr = stack.pop();
// current node has not been visited yet
if (!set.contains(curr)) {
// visit the node
// ...
// mark it as visited
set.add(curr);
}
for (int i = 0; i < curr.neighbors.size(); i++) {
GraphNode neighbor = curr.neighbors.get(i);
// this neighbor has not been visited yet
if (!set.contains(neighbor)) {
stack.push(neighbor);
}
}
}
}
We can use the same logic to do DFS recursively, clone graph etc.
Many people will say that non-recursive DFS is just BFS with a stack rather than a queue. That's not accurate, let me explain a bit more.
Recursive DFS
Recursive DFS uses the call stack to keep state, meaning you do not manage a separate stack yourself.
However, for a large graph, recursive DFS (or any recursive function that is) may result in a deep recursion, which can crash your problem with a stack overflow (not this website, the real thing).
Non-recursive DFS
DFS is not the same as BFS. It has a different space utilization, but if you implement it just like BFS, but using a stack rather than a queue, you will use more space than non-recursive DFS.
Why more space?
Consider this:
// From non-recursive "DFS"
for (auto i&: adjacent) {
if (!visited(i)) {
stack.push(i);
}
}
And compare it with this:
// From recursive DFS
for (auto i&: adjacent) {
if (!visited(i)) {
dfs(i);
}
}
In the first piece of code you are putting all the adjacent nodes in the stack before iterating to the next adjacent vertex and that has a space cost. If the graph is large it can make a significant difference.
What to do then?
If you decide to solve the space problem by iterating over the adjacency list again after popping the stack, that's going to add time complexity cost.
One solution is to add items to the stack one by one, as you visit them. To achieve this you can save an iterator in the stack to resume the iteration after popping.
Lazy way
In C/C++, a lazy approach is to compile your program with a larger stack size and increase stack size via ulimit, but that's really lousy. In Java you can set the stack size as a JVM parameter.
Recursion is a way to use the call stack to store the state of the graph traversal. You can use the stack explicitly, say by having a local variable of type std::stack, then you won't need the recursion to implement the DFS, but just a loop.
okay. if you are still looking for a java code
dfs(Vertex start){
Stack<Vertex> stack = new Stack<>(); // initialize a stack
List<Vertex> visited = new ArrayList<>();//maintains order of visited nodes
stack.push(start); // push the start
while(!stack.isEmpty()){ //check if stack is empty
Vertex popped = stack.pop(); // pop the top of the stack
if(!visited.contains(popped)){ //backtrack if the vertex is already visited
visited.add(popped); //mark it as visited as it is not yet visited
for(Vertex adjacent: popped.getAdjacents()){ //get the adjacents of the vertex as add them to the stack
stack.add(adjacent);
}
}
}
for(Vertex v1 : visited){
System.out.println(v1.getId());
}
}
Python code. The time complexity is O(V+E) where V and E are the number of vertices and edges respectively. The space complexity is O(V) due to the worst-case where there is a path that contains every vertex without any backtracking (i.e. the search path is a linear chain).
The stack stores tuples of the form (vertex, vertex_edge_index) so that the DFS can be resumed from a particular vertex at the edge immediately following the last edge that was processed from that vertex (just like the function call stack of a recursive DFS).
The example code uses a complete digraph where every vertex is connected to every other vertex. Hence it is not necessary to store an explicit edge list for each node, as the graph is an edge list (the graph G contains every vertex).
numv = 1000
print('vertices =', numv)
G = [Vertex(i) for i in range(numv)]
def dfs(source):
s = []
visited = set()
s.append((source,None))
time = 1
space = 0
while s:
time += 1
current, index = s.pop()
if index is None:
visited.add(current)
index = 0
# vertex has all edges possible: G is a complete graph
while index < len(G) and G[index] in visited:
index += 1
if index < len(G):
s.append((current,index+1))
s.append((G[index], None))
space = max(space, len(s))
print('time =', time, '\nspace =', space)
dfs(G[0])
Output:
time = 2000
space = 1000
Note that time here is measuring V operations and not E. The value is numv*2 because every vertex is considered twice, once on discovery and once on finishing.
Acutally, stack is not well able to deal with discover time and finish time, if we want to implement DFS with stack, and want to deal with discover time and finish time, we would need to resort to another recorder stack, my implementation is shown below, have test correct, below is for case-1, case-2 and case-3 graph.
from collections import defaultdict
class Graph(object):
adj_list = defaultdict(list)
def __init__(self, V):
self.V = V
def add_edge(self,u,v):
self.adj_list[u].append(v)
def DFS(self):
visited = []
instack = []
disc = []
fini = []
for t in range(self.V):
visited.append(0)
disc.append(0)
fini.append(0)
instack.append(0)
time = 0
for u_ in range(self.V):
if (visited[u_] != 1):
stack = []
stack_recorder = []
stack.append(u_)
while stack:
u = stack.pop()
visited[u] = 1
time+=1
disc[u] = time
print(u)
stack_recorder.append(u)
flag = 0
for v in self.adj_list[u]:
if (visited[v] != 1):
flag = 1
if instack[v]==0:
stack.append(v)
instack[v]= 1
if flag == 0:
time+=1
temp = stack_recorder.pop()
fini[temp] = time
while stack_recorder:
temp = stack_recorder.pop()
time+=1
fini[temp] = time
print(disc)
print(fini)
if __name__ == '__main__':
V = 6
G = Graph(V)
#==============================================================================
# #for case 1
# G.add_edge(0,1)
# G.add_edge(0,2)
# G.add_edge(1,3)
# G.add_edge(2,1)
# G.add_edge(3,2)
#==============================================================================
#==============================================================================
# #for case 2
# G.add_edge(0,1)
# G.add_edge(0,2)
# G.add_edge(1,3)
# G.add_edge(3,2)
#==============================================================================
#for case 3
G.add_edge(0,3)
G.add_edge(0,1)
G.add_edge(1,4)
G.add_edge(2,4)
G.add_edge(2,5)
G.add_edge(3,1)
G.add_edge(4,3)
G.add_edge(5,5)
G.DFS()
I think you need to use a visited[n] boolean array to check if the current node is visited or not earlier.
A recursive algorithm works very well for DFS as we try to plunge as deeply as we can, ie. as soon as we find an un-explored vertex, we're going to explore its FIRST un-explored neighbor right away. You need to BREAK out of the for loop as soon as you find the first un-explored neighbor.
for each neighbor w of v
if w is not explored
mark w as explored
push w onto the stack
BREAK out of the for loop
I think this is an optimized DFS regarding space-correct me if I am wrong.
s = stack
s.push(initial node)
add initial node to visited
while s is not empty:
v = s.peek()
if for all E(v,u) there is one unvisited u:
mark u as visited
s.push(u)
else
s.pop
Using Stack and implementing as done by the call stack in the recursion process-
The Idea is to push a vertex in the stack, and then push its vertex adjacent to it which is stored in a adjacency list at the index of the vertex and then continue this process until we cannot move further in the graph, now if we cannot move ahead in the graph then we will remove the vertex which is currently on the top of the stack as it is unable to take us on any vertex which is unvisited.
Now, using stack we take care of the point that the vertex is only removed from the stack when all the vertices that can be explored from the current vertex have been visited, which was being done by the recursion process automatically.
for ex -
See the example graph here.
( 0 ( 1 ( 2 ( 4 4 ) 2 ) ( 3 3 ) 1 ) 0 ) ( 6 ( 5 5 ) ( 7 7 ) 6 )
The above parenthesis show the order in which the vertex is added on the stack and removed from the stack, so a parenthesis for a vertex is closed only when all the vertices that can be visited from it have been done.
(Here I have used the Adjacency List representation and implemented as a vector of list (vector > AdjList) by using C++ STL)
void DFSUsingStack() {
/// we keep a check of the vertices visited, the vector is set to false for all vertices initially.
vector<bool> visited(AdjList.size(), false);
stack<int> st;
for(int i=0 ; i<AdjList.size() ; i++){
if(visited[i] == true){
continue;
}
st.push(i);
cout << i << '\n';
visited[i] = true;
while(!st.empty()){
int curr = st.top();
for(list<int> :: iterator it = AdjList[curr].begin() ; it != AdjList[curr].end() ; it++){
if(visited[*it] == false){
st.push(*it);
cout << (*it) << '\n';
visited[*it] = true;
break;
}
}
/// We can move ahead from current only if a new vertex has been added on the top of the stack.
if(st.top() != curr){
continue;
}
st.pop();
}
}
}
The following Java Code will be handy:-
private void DFS(int v,boolean[] visited){
visited[v]=true;
Stack<Integer> S = new Stack<Integer>();
S.push(v);
while(!S.isEmpty()){
int v1=S.pop();
System.out.println(adjLists.get(v1).name);
for(Neighbor nbr=adjLists.get(v1).adjList; nbr != null; nbr=nbr.next){
if (!visited[nbr.VertexNum]){
visited[nbr.VertexNum]=true;
S.push(nbr.VertexNum);
}
}
}
}
public void dfs() {
boolean[] visited = new boolean[adjLists.size()];
for (int v=0; v < visited.length; v++) {
if (!visited[v])/*This condition is for Unconnected Vertices*/ {
System.out.println("\nSTARTING AT " + adjLists.get(v).name);
DFS(v, visited);
}
}
}

4x4 2D character matrix permutations

I have a 4x4 2D array of characters like this:
A B C D
U A L E
T S U G
N E Y I
Now, I would need to find all the permutations of 3 characters, 4 characters, etc till 10.
So, some words that one could "find" out of this are TEN, BALD, BLUE, GUYS.
I did search SO for this and Googled, but to no concrete help. Can you push me in the right direction in which algorithm I should learn (A* maybe?). Please be gentle as I'm no algorithms guy (aren't we all (well, at least a majority :)), but am willing to learn just don't know where exactly to start.
Ahhh, that's the game Boggle isn't it... You don't want permutations, you want a graph and you want to find words in the graph.
Well, I would start by arranging the characters as graph nodes, and join them to their immediate and diagonal neighbours.
Now you just want to search the graph. For each of the 16 starting nodes, you're going to do a recursion. As you move to a new node, you must flag it as being used so that you can't move to it again. When you leave a node (having completely searched it) you unflag it.
I hope you see where this is going...
For each node, you will visit each of its neighbours and add that character to a string. If you have built your dictionary with this search in mind, you will immediately be able to see whether the characters you have so far are the beginning of a word. This narrows the search nicely.
The kind of dictionary I'm talking about is where you have a tree whose nodes have one child for each letter of the alphabet. The beauty of these is that you only need to store which tree node you're currently up to in the search. If you decide you've found a word, you just backtrack via the parent nodes to work out which word it is.
Using this tree style along with a depth-first graph search, you can search ALL possible word lengths at the same time. That's about the most efficient way I can think of.
Let me just write a pseudocodish function for your graph search:
function FindWords( graphNode, dictNode, wordsList )
# can't use a letter twice
if graphNode.used then return
# don't continue if the letter not part of any word
if not dictNode.hasChild(graphNode.letter) then return
nextDictNode = dictNode.getChild(graphNode.letter)
# if this dictionary node is flagged as a word, add it to our list
nextDictNode.isWord()
wordsList.addWord( nextDictNode .getWord() )
end
# Now do a recursion on all our neighbours
graphNode.used = true
foreach nextGraphNode in graphNode.neighbours do
FindWords( nextGraphNode, nextDictNode, wordsList )
end
graphNode.used = false
end
And of course, to kick the whole thing off:
foreach graphNode in graph do
FindWords( graphNode, dictionary, wordsList )
end
All that remains is to build the graph and the dictionary. And I just remembered what that dictionary data structure is called! It's a Trie. If you need more space-efficient storage, you can compress into a Radix Tree or similar, but by far the easiest (and fastest) is to just use a straight Trie.
As you not define preferred language I implemented on C#:
private static readonly int[] dx = new int[] { 1, 1, 1, 0, 0, -1, -1, -1 };
private static readonly int[] dy = new int[] { -1, 0, 1, 1, -1, -1, 0, 1 };
private static List<string> words;
private static List<string> GetAllWords(char[,] matrix ,int d)
{
words = new List<string>();
bool[,] visited = new bool[4, 4];
char[] result = new char[d];
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
Go(matrix, result, visited, d, i, j);
return words;
}
private static void Go(char[,] matrix, char[] result, bool[,] visited, int d, int x, int y)
{
if (x < 0 || x >= 4 || y < 0 || y >= 4 || visited[x, y])
return;
if (d == 0)
{
words.Add(new String(result));
return;
}
visited[x, y] = true;
result[d - 1] = matrix[x, y];
for (int i = 0; i < 8; i++)
{
Go(matrix, result, visited, d - 1, x + dx[i], y + dy[i]);
}
visited[x, y] = false;
}
Code to get results:
char[,] matrix = new char[,] { { 'A', 'B', 'C', 'D' }, { 'U', 'A', 'L', 'E' }, { 'T', 'S', 'U', 'G' }, { 'N', 'E', 'Y', 'I' } };
List<string> list = GetAllWords(matrix, 3);
Change parameter 3 to required text length.
It seems you just use the 4x4 matrix as an array of length 16. If it is the case, you can try the recursive approach to generate permutations up to length k as follows:
findPermutations(chars, i, highLim, downLim, candidate):
if (i > downLim):
print candidate
if (i == highLim): //stop clause
return
for j in range(i,length(chars)):
curr <- chars[i]
candidate.append(curr)
swap(chars,i,j) // make it unavailable for repicking
findPermutations(chars,i+1,highLim,downLim,candidate)
//clean up environment after recursive call:
candidate.removeLast()
swap(chars ,i, j)
The idea is to print each "candidate" that has more chars then downLim (3 in your case), and terminate when you reach the upper limit (highLim) - 10 in your case.
At each time, you "guess" which character is the next to put - and you append it to the candidate, and recursively invoke to find the next candidate.
Repeat the process for all possible guesses.
Note that there are choose(10,16)*10! + choose(9,16)*9! + ... + choose(3,16)*3! different such permutations, so it might be time consuming...
If you want meaningful words, you are going to need some kind of dictionary (or to statistically extract one from some context) in order to match the candidates with the "real words".

Obtain forest out of tree with even number of nodes

I'm stuck on a code challenge, and I want a hint.
PROBLEM: You are given a tree data structure (without cycles) and are asked to remove as many "edges" (connections) as possible, creating smaller trees with even numbers of nodes. This problem is always solvable as there are an even number of nodes and connections.
Your task is to count the removed edges.
Input:
The first line of input contains two integers N and M. N is the number of vertices and M is the number of edges. 2 <= N <= 100.
Next M lines contains two integers ui and vi which specifies an edge of the tree. (1-based index)
Output:
Print the number of edges removed.
Sample Input
10 9
2 1
3 1
4 3
5 2
6 1
7 2
8 6
9 8
10 8
Sample Output :
2
Explanation : On removing the edges (1, 3) and (1, 6), we can get the desired result.
I used BFS to travel through the nodes.
First, maintain an array separately to store the total number of child nodes + 1.
So, you can initially assign all the leaf nodes with value 1 in this array.
Now start from the last node and count the number of children for each node. This will work in bottom to top manner and the array that stores the number of child nodes will help in runtime to optimize the code.
Once you get the array after getting the number of children nodes for all the nodes, just counting the nodes with even number of nodes gives the answer. Note: I did not include root node in counting in final step.
This is my solution. I didn't use bfs tree, just allocated another array for holding eachnode's and their children nodes total number.
import java.util.Scanner;
import java.util.Arrays;
public class Solution {
public static void main(String[] args) {
int tree[];
int count[];
Scanner scan = new Scanner(System.in);
int N = scan.nextInt(); //points
int M = scan.nextInt();
tree = new int[N];
count = new int[N];
Arrays.fill(count, 1);
for(int i=0;i<M;i++)
{
int u1 = scan.nextInt();
int v1 = scan.nextInt();
tree[u1-1] = v1;
count[v1-1] += count[u1-1];
int root = tree[v1-1];
while(root!=0)
{
count[root-1] += count[u1-1];
root = tree[root-1];
}
}
System.out.println("");
int counter = -1;
for(int i=0;i<count.length;i++)
{
if(count[i]%2==0)
{
counter++;
}
}
System.out.println(counter);
}
}
If you observe the input, you can see that it is quite easy to count the number of nodes under each node. Consider (a b) as the edge input, in every case, a is the child and b is the immediate parent. The input always has edges represented bottom-up.
So its essentially the number of nodes which have an even count(Excluding the root node). I submitted the below code on Hackerrank and all the tests passed. I guess all the cases in the input satisfy the rule.
def find_edges(count):
root = max(count)
count_even = 0
for cnt in count:
if cnt % 2 == 0:
count_even += 1
if root % 2 == 0:
count_even -= 1
return count_even
def count_nodes(edge_list, n, m):
count = [1 for i in range(0, n)]
for i in range(m-1,-1,-1):
count[edge_list[i][1]-1] += count[edge_list[i][0]-1]
return find_edges(count)
I know that this has already been answered here lots and lots of time. I still want to know reviews on my solution here. I tried to construct the child count as the edges were coming through the input and it passed all the test cases.
namespace Hackerrank
{
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
var tempArray = Console.ReadLine().Split(' ').Select(x => Convert.ToInt32(x)).ToList();
int verticeNumber = tempArray[0];
int edgeNumber = tempArray[1];
Dictionary<int, int> childCount = new Dictionary<int, int>();
Dictionary<int, int> parentDict = new Dictionary<int, int>();
for (int count = 0; count < edgeNumber; count++)
{
var nodes = Console.ReadLine().Split(' ').Select(x => Convert.ToInt32(x)).ToList();
var node1 = nodes[0];
var node2 = nodes[1];
if (childCount.ContainsKey(node2))
childCount[node2]++;
else childCount.Add(node2, 1);
var parent = node2;
while (parentDict.ContainsKey(parent))
{
var par = parentDict[parent];
childCount[par]++;
parent = par;
}
parentDict[node1] = node2;
}
Console.WriteLine(childCount.Count(x => x.Value % 2 == 1) - 1);
}
}
}
My first inclination is to work up from the leaf nodes because you cannot cut their edges as that would leave single-vertex subtrees.
Here's the approach that I used to successfully pass all the test cases.
Mark vertex 1 as the root
Starting at the current root vertex, consider each child. If the sum total of the child and all of its children are even, then you can cut that edge
Descend to the next vertex (child of root vertex) and let that be the new root vertex. Repeat step 2 until you have traversed all of the nodes (depth first search).
Here's the general outline of an alternative approach:
Find all of the articulation points in the graph.
Check each articulation point to see if edges can be removed there.
Remove legal edges and look for more articulation points.
Solution - Traverse all the edges, and count the number of even edges
If we remove an edge from the tree and it results in two tree with even number of vertices, let's call that edge - even edge
If we remove an edge from the tree and it results in two trees with odd
number of vertices, let's call that edge - odd edge
Here is my solution in Ruby
num_vertices, num_edges = gets.chomp.split(' ').map { |e| e.to_i }
graph = Graph.new
(1..num_vertices).to_a.each do |vertex|
graph.add_node_by_val(vertex)
end
num_edges.times do |edge|
first, second = gets.chomp.split(' ').map { |e| e.to_i }
graph.add_edge_by_val(first, second, 0, false)
end
even_edges = 0
graph.edges.each do |edge|
dup = graph.deep_dup
first_tree = nil
second_tree = nil
subject_edge = nil
dup.edges.each do |e|
if e.first.value == edge.first.value && e.second.value == edge.second.value
subject_edge = e
first_tree = e.first
second_tree = e.second
end
end
dup.remove_edge(subject_edge)
if first_tree.size.even? && second_tree.size.even?
even_edges += 1
end
end
puts even_edges
Note - Click Here to check out the code for Graph, Node and Edge classes

Resources