C# Object suddenly null - c#

I've searched so long and hard for this and now I'm at road's end. I've had this issue with more than this project, but I ended up scrapping the others. I have a code (C#) which is basically me trying to do Huffman tree. At one point I do this ("nodeList" is List(Node)):
Node node = new Node(nodeList[0], nodeList[1]);
nodeList.Add(node); // Adds a new node which includes two subnodes.
// Remove nodes from list (as they are now included in another node)
nodeList.RemoveAt(0);
nodeList.RemoveAt(1);
And the constructors in use here is:
// Constructor that takes nodes
public Node(Node left, Node right)
{
leftNode = new Node(left);
rightNode = new Node(right);
}
// Constructor that only takes 1 single node
public Node(Node copy)
{
rightNode = copy.rightNode;
leftNode = copy.leftNode;
unencodedBits = copy.unencodedBits;
encodingValue = copy.encodingValue;
positions = copy.positions;
}
I did the second constructor as a hope that it would fix my problem (thinking that removing the node from the list maybe nulled it out.) (all of the values in my Node-class is on the right side of the second constructor.)
The problem: After doing the second "RemoveAt" the Node will no longer contain the two nodes. And I can not understand why. What do I have to do to prevent this from happening and why does it happen (so I can understand similar cases in the future)?
I probably forgot to include some vital information; If I did, please tell me. And thanks for any assistance.

Is your nodeList object in array or a List? If it is a list, then nodeList.RemoveAt(0) causes the node currently located and index 1 to now be located at index 0. so you would need to call
nodeList.RemoveAt(0);
nodeList.RemoveAt(0);
instead of
nodeList.RemoveAt(0);
nodeList.RemoveAt(1);
see here: http://msdn.microsoft.com/en-us/library/5cw9x18z(v=vs.110).aspx

Related

Get first (or any) value from HashSet

Currently, my code looks like this:
private List<Node> dirtyNodes = new List<Node> dirtyNodes();
public void UpdateDirtyNodes()
{
while(dirtyNodes.Count > 0)
{
Node nodeToUpdate = dirtyNodes[0];
nodeToUpdate.UpdateNode();
dirtyNodes.Remove(nodeToUpdate);
}
}
public void MarkNodeDirty(Node node)
{
if(!dirtyNodes.Contains(node))
{
dirtyNodes.Add(node);
}
}
public void MarkNodeClean(Node node)
{
dirtyNodes.Remove(node);
}
This is a performance-critical part of the code, and it's slower than I'd like because dirtyNodes.Contains has to iterate over the entire array in most cases. I'd like to replace the List with a HashSet because it should be faster, but I can't figure out how to make that work with UpdateDirtyNodes().
The difficulty is that UpdateNode() can add or remove nodes from dirtyNodes at any time, hence the slightly awkward while loop. Is there a way I can get the "first" value from a HashSet? Order doesn't matter, I just need to stay in the while loop until dirtyNodes is empty, updating whatever node comes next.
I would prefer to avoid using Linq since this code will be part of a library and I don't want to force them to include Linq.
How can I do this?
Turns out it's very easy to just use the enumerator directly:
public void UpdateDirtyNodes()
{
while(dirtyNodes.Count > 0)
{
using(HashSet<Node>.Enumerator enumerator = dirtyNodes.GetEnumerator())
{
if(enumerator.MoveNext())
{
Node nodeToUpdate = enumerator.Current;
nodeToUpdate.UpdateNode();
dirtyNodes.Remove(nodeToUpdate);
}
}
}
}
public void MarkNodeDirty(Node node)
{
dirtyNodes.Add(node);
}
I originally tried something similar but didn't fully understand how to manually use enumerators and it didn't work.
It's significantly faster than the List (overall frame time is ~25-50% faster depending on the situation just from that one change) so I'm very happy. (Don't panic about that 30MB allocation in the screenshot below - I'm working on it.)
Add a bool dirty field inside the Node class. This is in addition to keeping a hash set. Then MarkNodeClean() doesn't need to remove nodes from the HashSet, shaving off some CPU cycles.
If you feel that adding a field inside Node class is too "dirty" (pun intended), then just make a HashSet<(Node, bool)> instead of HashSet<Node>, but you are loosing performance on allocating and garbage-collecting extra objects, which is not ideal since your code is performance-critical.
UpdateDirtyNodes() will take nodes one at a time until the HashSet is empty. After taking each node, it will look at the boolean flag to decide whether the node is actually dirty.
P.S.
You should remove dirtyNodes.Clear(); from UpdateDirtyNodes(). This is a race condition. If a node is added after the while loop finds that dirtyNodes.Count is 0, then dirtyNodes.Clear(); clears out that node without processing it. This is a separate bug, not related to your question.

Recursion algorithm Stops running after finding the first Leaf node

I do apology in advance if there are many variables in the following code sample that their "types" is not clear to you, it is a big library, I just can't put all of that in here, so think of it at high-level, and the name of the variables is kind of helpful too...
Problem: A "concept" can have many "relations". Each of those relations can also have many concepts, For example like a father and child, a father has many children, a child may itsself be a father and has more children ,etc...
So I want to pass the root father and get all the hierarchy and write it to a file ...
The high-level code I am using is this, THE PROBLEM IS THAT it Crashes by a Null exception when it gets the child that has no more children. So its object is null in this line:
oUCMRConceptReltn = moTargetConceptList.ConceptReltns.get_ItemByIndex(i, false);
So I thought well let's put a not null check around it, yeah fixes the crash BUT after it sees the first leafe, it doesn't go further and algorithm stops.
So Something is wrong with the way I am calling recursion, but can't figure it out.
private void MyLoadMethod(string sConceptCKI)
{
UCMRConceptLib.UCMRConceptLoadQual oUCMRConceptLoadQual = new UCMRConceptLib.UCMRConceptLoadQual();
//Fill out UCMRConceptLoadQual object to get new list of related concepts
moTargetConceptList.Load(oUCMRConceptLoadQual;
// WHEN IT IS ZERO, THERE ARE NO MORE CHILDREN.
int numberofKids = moTargetConceptList.ConceptReltns.Count();
if (numberofKids == 0)
return ;
for (int i = 1; i <= numberofKids; i++)
{
oUCMRConceptReltn = moTargetConceptList.ConceptReltns.get_ItemByIndex(i, false);
//Get the concept linked to the relation concept
if (oUCMRConceptReltn.SourceCKI == sConceptCKI)
{
oConcept = moTargetConceptList.ItemByKeyConceptCKI(oUCMRConceptReltn.TargetCKI, false);
}
else
{
oConcept = moTargetConceptList.ItemByKeyConceptCKI(oUCMRConceptReltn.SourceCKI, false);
}
//write its name to the file...now recursion: go and find its children.
builder.AppendLine("\t" + oConcept.PrimaryCTerm.SourceString);
MyLoadMethod(oConcept.ConceptCKI);
}
return ;
}
Just as a side note, the check for number of kids being 0 is redundant, because you're never going to enter the loop.
The algorithm looks okay for what you want to do. You don't need to return anything in this case because your algorithm uses a side effect (the appendLine) to give your output.
I don't know C#, but it looks to me as if you're using some variables that are not local to the function, like oUCMRConceptReltn and oConcept. If they're not local to the function, different recursive invocations can change those values in unexpected ways. Recursive functions should almost never write to a variable outside its own scope.
Most indexes in c style languages are 0 based. So don't loop through 1 to numberofKids, loop 0 to numberofKids-1.
for (int i = 0; i < numberofKids; i++)

All the paths between 2 nodes in graph

I have to make an uninformed search (Breadth-first-Search) program which takes two nodes and return all the paths between them.
public void BFS(Nod start, Nod end) {
Queue<Nod> queue = new Queue<Nod>();
queue.Enqueue(start);
while (queue.Count != 0)
{
Nod u = queue.Dequeue();
if (u == end) break;
else
{
u.data = "Visited";
foreach (Edge edge in u.getChildren())
{
if (edge.getEnd().data == "")
{
edge.getEnd().data = "Visited";
if (edge.getEnd() != end)
{
edge.getEnd().setParent(u);
}
else
{
edge.getEnd().setParent(u);
cost = 0;
PrintPath(edge.getEnd(), true);
edge.getEnd().data = "";
//return;
}
}
queue.Enqueue(edge.getEnd());
}
}
}
}
My problem is that i only get two paths instead of all and i don't know what to edit in my code to get them all. The input of my problem is based on this map :
In the BFS algorithm you must not stop after you find a solution. One idea is to set data null for all the cities you visited except the first one and let the function run a little bit longer. I don't have time to write you a snippet but if ou don't get it i will write at least a pseudocode. If you didn't understood my idea post a comment with your question and i will try to explain better.
Breadth first search is a strange way to generate all possible paths for the following reason: you'd need to keep track of whether each individual path in the BFS had traversed the node, not that it had been traversed at all.
Take a simple example
1----2
\ \
3--- 4----5
We want all paths from 1 to 5. We queue up 1, then 2 and 3, then 4, then 5. We've lost the fact that there are two paths through 4 to 5.
I would suggest trying to do this with DFS, though this may be fixable for BFS with some thinking. Each thing queued would be a path, not a single node, so one could see if that path had visited each node. This is wasteful memory wise, thoug
A path is a sequence of vertices where no vertex is repeated more than once. Given this definition, you could write a recursive algorithm which shall work as follows: Pass four parameters to the function, call it F(u, v, intermediate_list, no_of_vertices), where u is the current source (which shall change as we recurse), v is the destination, intermediate_list is a list of vertices which shall be initially empty, and every time we use a vertex, we'll add it to the list to avoid using a vertex more than once in our path, and no_of_vertices is the length of the path that we would like to find, which shall be lower bounded by 2, and upper bounded by V, the number of vertices. Essentially, the function shall return a list of paths whose source is u, destination is v, and whose length of each path is no_of_vertices. Create an initial empty list and make calls to F(u, v, {}, 2), F(u, v, {}, 3), ..., F(u, v, {}, V), each time merging the output of F with the list where we intend to store all paths. Try to implement this, and if you still face trouble, I'll write the pseudo-code for you.
Edit: Solving the above problem using BFS: Breadth first search is an algorithm that could be used to explore all the states of a graph. You could explore the graph of all paths of the given graph, using BFS, and select the paths that you want. For each vertex v, add the following states to the queue: (v, {v}, {v}), where each state is defined as: (current_vertex, list_of_vertices_already_visited, current_path). Now, while the queue is not empty, pop off the top element of the queue, for each edge e of the current_vertex, if the tail vertex x doesn't already exist in the list_of_vertices_already_visited, push the new state (x, list_of_vertices_already_visited + {x}, current_path -> x) to the queue, and process each path as you pop it off the queue. This way you can search the entire graph of paths for a graph, whether directed, or undirected.
Sounds like homework. But the fun kind.
The following is pseudocode, is depth first instead of breath first (so should be converted to a queue type algorithm, and may contain bugs, but the general jist should be clear.
class Node{
Vector[Link] connections;
String name;
}
class Link{
Node destination;
int distance;
}
Vector[Vector[Node]] paths(Node source, Node end_dest, Vector[Vector[Node]] routes){
for each route in routes{
bool has_next = false;
for each connection in source.connections{
if !connection.destination in route {
has_next = true;
route.push(destination);
if (!connection.destination == end_dest){
paths(destination, end_dest, routes);
}
}
}
if !has_next {
routes.remove(route) //watch out here, might mess up the iteration
}
}
return routes;
}
Edit: Is this actually the answer to the question you are looking for? Or do you actually want to find the shortest path? If it's the latter, use Dijkstra's algorithm: http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm

Recursive Tree Mapping

I've been working a lot with tree implementations lately and how we represent and understand trees. My focus has been on turning mathematical expressions into binary trees, I set the problem of representing a tree in a linear form say a string or an array, while still retaining important information about the tree and its sub trees.
As such I have developed a really simple encoding for binary expression trees does just this. However I am having some issues with implementing it effectively in a recursive manor, it seems to be the one failing aspect behind the concept.
The encoding is simple if the node resides as a left child it is given a map of 1 if it resides as a right child it is given a 0. This simple encoding allows me to encode entire balanced and unbalanced trees like this:
## ##
/ \ / \
1 0 OR 1 0
/ \ / \ / \
11 10 01 00 01 00
Etc to trees of depth N
Does anyone have any suggestions as to how to create a recursive function that would create the prefix string representing a mapping of this sort (for example ## 1 11 10 0 01 00).
I was told this would be difficult/impossible due to having to keep track of alternating between 1 and 0 while retaining and concatenating to the value of the parent.
I wondered if anyone had any insight or ideas into how to do this with C# ??
I'm not sure I understand you problem but here is something that might help. One solution might be implementing graph traversal routine on a Graph (remember a Tree is a specialized Graph), where the visit occurs the first time you encounter a node/vertex. I apologize for posting Java code when you asked for C# but I happen know Java...
public void depthFirstSearch(Graph graph, Vertex start){
Set<Vertex> visited = new HashSet<Vertex>(); // could use vertex.isVisited()...
Deque<Vertex> stack = new ArrayDeque<Vertex>(); // stack implies depth first
// first visit the root element, then add it to the stack so
// we will visit it's children in a depth first order
visit(start);
visited.add(start);
stack.push(start);
while(stack.isEmpty() == false){
List<Edge> edges = graph.getEdges(stack.peekFirst());
Vertex nextUnvisited = null;
for(Edge edge : edges){
if(visited.contains(edge.getEndVertex)) == false){
nextUnvisited = edge.getEndVertex();
break; // break for loop
}
}
if(nextUnvisited == null){
// check the next item in the stack
Vertex popped = stack.pop();
} else {
// visit adjacent unvisited vertex
visit(nextUnvisited);
visited.add(nextUnvisited);
stack.push(nextUnvisited); // visit it's "children"
}
}
}
public void visit(Vertex vertex){
// your own visit logic (string append, etc)
}
You can easily modify this to be a breadth first search by using the Deque as a queue instead of stack as follows:
stack.pop() >>>> queue.removeFirst()
stack.push() >>>> queue.addLast()
Note that for this purpose the Graph and Edge classes support the following operations :
public interface Graph {
...
// get edges originating from Vertex v
public List<Edge> getEdges(Vertex v);
...
}
public interface Edge {
...
// get the vertex at the start of the edge
// not used here but kind of implied by the getEndVertex()...
public Vertex getStartVertex();
// get the vertex at the end of the edge
public Vertex getEndVertex();
...
}
Hopefully that gives you some ideas.
Well i don't know if i completely get your question but it seems you want a preorder traversal of the tree. I don't know c#'s syntax but the pseudocode i think will be as follows:
preorder_traversal(node)
if(node != NULL)
print(node)
preorder_traversal(left_sub_child)
preorder_traversal(right_sub_child)
else
return
Building a tree recursively is a difficult challenge even for a seasoned programmer. I realize I'm a bit late to the party on this question considering it was originally posted in March of 2011. Better late than never?
One important factor in creating a tree is just making sure your dataset is formatted correctly. You simply need a way to associate a parent to a child. Once the association is clearly defined, then you can begin to code the solution. I chose to use a simple format like this:
ParentId ChildId
1 2
1 3
2 4
3 5
Etc.
Once that relationship is established, I developed a recursive method to iterate through the dataset to build the tree.
First I identify all the parent nodes and store them in a collection giving them each a unique identifier using a combination of the parent ID and child ID:
private void IdentifyParentNodes()
{
SortedList<string, MyTreeNode> newParentNodes = new SortedList<string,MyTreeNode>();
Dictionary<string, string> parents = new Dictionary<string, string>();
foreach (MyTreeNode oParent in MyTreeDataSource.Values)
{
if (!parents.ContainsValue(oParent.ParentId))
{
parents.Add(oParent.ParentId + "." + oParent.ChildId, oParent.ParentId);
newParentNodes.Add(oParent.ParentId + "." + oParent.ChildId, oParent);
}
}
this._parentNodes = newParentNodes;
}
Then the root calling method would loop through the parents and call the recursive method to build the tree:
// Build the rest of the tree
foreach (MyTreeNode node in ParentNodes.Values)
{
RecursivelyBuildTree(node);
}
Recursive method:
private void RecursivelyBuildTree(MyTreeNode node)
{
int nodePosition = 0;
_renderedTree.Append(FormatNode(MyTreeNodeType.Parent, node, 0));
_renderedTree.Append(NodeContainer("open", node.ParentId));
foreach (MyTreeNode child in GetChildren(node.ParentId).Values)
{
nodePosition++;
if (IsParent(child.ChildId))
{
RecursivelyBuildTree(child);
}
else
{
_renderedTree.Append(FormatNode(MyTreeNodeType.Leaf, child, nodePosition));
}
}
_renderedTree.Append(NodeContainer("close", node.ParentId));
}
Method used to get children of a parent:
private SortedList<string, MyTreeNode> GetChildren(string parentId)
{
SortedList<string, MyTreeNode> childNodes = new SortedList<string, MyTreeNode>();
foreach (MyTreeNode node in this.MyTreeDataSource.Values)
{
if (node.ParentId == parentId)
{
childNodes.Add(node.ParentId + node.ChildId, node);
}
}
return childNodes;
}
Not that complex or elegant, but it got the job done. This was written in 2007 time frame, so it's old code, but it still works. :-) Hope this helps.

C# reference trouble

I'm taking an algorithm course at the university, and for one of my projects I want to implement a red-black tree in C# (the implementation itself isn't the project, yet just something i decided to choose to help me out).
My red-black tree should hold string keys, and the object i created for each node looks like this :
class sRbTreeNode
{
public sRbTreeNode Parent = null;
public sRbTreeNode Right = null;
public sRbTreeNode Left = null;
public String Color;
public String Key;
public sRbTreeNode()
{
}
public sRbTreeNode(String key)
{
Key = key;
}
}
I already added some basic methods for printing the tree, finding the root, min/max key (by alphabet), etc...
I'm having trouble inserting nodes (hence, building the tree).
Whoever's familiar with red-black trees knows that when adding a node to one side, you could have changed the balance of the tree.
To fix this, you need to "rotate" around nodes on the tree in order to balance the tree out.
I wrote a RightRotate and LeftRotate method in pseudo-code, and then when i tried to implement it in C#, i ran into a bunch of reference problems with the sRbTreeNode object i created.
This is the pseudo-code I wrote for the LeftRotate method :
LeftRotate(root, node)
y <- node.Right;
node.Right <- y.Left;
if (y.Left != null)
y.Left.Parent <- node;
y.Parent <- node.Parent;
if (node.Parent = null)
root <- y;
else
if (node = node.Parent.Left)
node.Parent.Left = y;
else
node.Parent.Right = y;
y.Left <- node;
node.Parent <- y
I received a suggestion to implement it straight forward, but without using the 'ref' keyword, which i tried at first.
This is how i did it :
public static void LeftRotate(sRbTreeNode root, sRbTreeNode node)
{
sRbTreeNode y = node.Right;
node.Right = y.Left;
if (y.Left != null)
y.Left.Parent = node;
y.Parent = node.Parent;
if (node.Parent == null)
root = y;
else
if (node == node.Parent.Left)
node.Parent.Left = y;
else
node.Parent.Right = y;
y.Left = node;
node.Parent = y;
}
Now, when i debug, i see that it works fine, but the objects i pass to this method are only rotated within the scope of the method. When it leaves this method, it seems like there was no change to the actual nodes. That is why i thought of using the 'ref' keywords in the first place.
What am i doing wrong ?
Because in the body of your method you do this:
root = y;
you need to pass root in with a ref modifier. node doesn't need one, becausenode itself is never updated to point at a different ndoe.
.
I don't see why you should have had any issues with references - the Left/Right/Parent nodes can be copied just as in this pseudo-code.
You should be able to expand it to C# without too much fuss - unless you're using the 'ref' keyword, in which case you could very well get unpredictable results.
Perhaps if you could show the code you've actually written thus far, and we can help debug that.
My recommendations:
Do not include parent pointers. They are not essential for the insertion or deletion algorithms and will make your code more complex. For example LeftRotate can be written with just one parameter and will be about half as long if you do not use parent pointers.
Use an enum for the Color property rather than a string, and initialise it in the constructor.
Read this article if you haven't already.

Categories

Resources