Traversing binomial tree breadth first - c#

I am trying to traverse what I believe is called a binomial tree. However, there is a problem with traversing the bottom left node.
This is a representation of the data structure
This is the code. I feel it is pretty close to a solution but not quite -- there is something missing and it might be something minor. When the bottom left node is to be traversed, the binomial function has low == high, so it doesn't traverse it.
private State? BFS()
{
State state = new State();
foo(0,items.Count,state);
return bestState;
}
private void foo(int low, int high, State state)
{
int lCount = low;
while (lCount < high)
{
State newState = new State(items[lCount++], state);
if (predicate(newState))
{
bestState = newState;
}
queue.Enqueue(newState);
}
while(low<high)
{
foo(++low, high, queue.Dequeue());
}
}

Related

How to solve memory problem of a quadtree with moving objects?

I am creating a quadtree for a 2D game in C# to make the rendering faster. Some of the objects (planets) are moving and that is why, I created a method called removeAndUpdate to update the tree by deleting and reinserting the specific object from the leaves (so not from the root) as I have already read in link. Unfortunately, I got System.OutOfMemoryException after some time at the reinsertion part. I am quite sure, that the removeAndUpdate method has some problems.
Maybe it is good to mention, that when a quad is subdivided (in case, when the quad's storing capacity is full), the content will not distributed among the subquads. I made this way to improve some performance. However, I don't think it has some connection with the problem above.
I guess, there is an infinite loop somewhere, which causes to run out of memory. If I insert new objects from the root, there is no problem.
I wrote a comment to the place where the exception occurs.
Here you can see the important parts of the QuadTree class:
public class QuadTree
{
BoundingBox boundary;
int capacity;
List<WorldObject> leafContent;
public QuadTree parent;
bool divided;
public List<QuadTree> childQuadTrees;
public QuadTree(BoundingBox _boundary, int _capacity, QuadTree _parent)
{
this.boundary = _boundary;
this.capacity = _capacity;
this.leafContent = new List<WorldObject>();
this.childQuadTrees = new List<QuadTree>();
this.divided = false;
this.parent = _parent;
}
// Subdividing the quad, if its storing capacity is full.
public void subdivide()
{
// North-East
this.childQuadTrees.Add(new QuadTree(new BoundingBox(new Vector3(boundary.Center.X, 0, boundary.Min.Z),
new Vector3(boundary.Max.X, 0, boundary.Center.Z)), this.capacity, this));
// North-West
this.childQuadTrees.Add(new QuadTree(new BoundingBox(new Vector3(boundary.Min.X, 0, boundary.Min.Z),
new Vector3(boundary.Center.X, 0, boundary.Center.Z)), this.capacity, this));
// South-East
this.childQuadTrees.Add(new QuadTree(new BoundingBox(boundary.Center, boundary.Max), this.capacity, this));
// South-West
this.childQuadTrees.Add(new QuadTree(new BoundingBox(new Vector3(boundary.Min.X, 0, boundary.Center.Z), new Vector3(boundary.Center.X, 0, boundary.Max.Z)), this.capacity, this));
this.divided = true;
}
public void insert(WorldObject wO)
{
// Checking, whether the quad contains the box at all.
if (!this.ContainOrOverlap(wO.BoundingBox))
{
return;
}
// If there is space, insert the box.
if (this.leafContent.Count < this.capacity && this.divided == false)
{
/*This is the instruction, where System.OutOfMemoryException occures*/
this.leafContent.Add(wO); // <-------
return;
}
// If not, subdivide the quad then insert the obj to the subquads.
else
{
if (this.divided == false)
{
this.subdivide();
}
this.childQuadTrees[0].insert(wO);
this.childQuadTrees[1].insert(wO);
this.childQuadTrees[2].insert(wO);
this.childQuadTrees[3].insert(wO);
}
}
/* Here is the method to update the moving objects bounding volume.
It first removes the element from the tree, updates the boundingbox, then reinsert the object from the leaves*/
public void removeAndUpdate(WorldObject obj, Vector3 displacement)
{
if (!this.ContainOrOverlap(obj.BoundingBox))
{
return;
}
if (this.divided)
{
this.childQuadTrees[0].removeAndUpdate(obj, displacement);
this.childQuadTrees[1].removeAndUpdate(obj, displacement);
this.childQuadTrees[2].removeAndUpdate(obj, displacement);
this.childQuadTrees[3].removeAndUpdate(obj, displacement);
}
/* if the obj is found, remove it, the try to reinsert it to its parent. If its parent does not contain it, move upwards in the hierarchy and try again to insert*/
if (leafContent.Contains(obj))
{
this.leafContent.Remove(obj);
QuadTree q = this.parent;
while (q.ContainOrOverlap(obj.BoundingBox) == false)
{
q = q.parent;
}
obj.BoundingBox.Translate(displacement);
q.insert(obj);
}
}
public void query(BoundingBox range, List<WorldObject> resultList)
{
if (!this.ContainOrOverlap(range))
{
return;
}
if (this.divided)
{
this.childQuadTrees[0].query(range, resultList);
this.childQuadTrees[1].query(range, resultList);
this.childQuadTrees[2].query(range, resultList);
this.childQuadTrees[3].query(range, resultList);
}
resultList.AddList(this.leafContent);
}
}
Here is some info from the debug at the break of the exception:

Algorithm needed to determine heirarchy of geometric shapes

I've been trying without much luck to develop an algorithm to sort a collection of closed geometric figures based on whether one shape is completely enclosed within the perimeter of another. When completely analyzed, I should end up with a tree structure that defines the hierarchy.
I can take care of the actual comparison, which is whether one shape is completely within the perimeter of another. I'm having difficulty though with the sorting of unorganized input. I suspect that the solution involves binary tree structures and recursive code, which I've never been strong with.
Geometric data will have already been sanitized prior to generating the sorted hierarchy data, so issues like open paths, overlapping, partially overlapping and self-intersecting shouldn't be an issue.
Below is a group of test figures I've been working with that may help to illustrate my question.
As a human, I can see that the yellow shape is not within the blue one, nor is the blue within the yellow. They are both within the green shape, which is within the red... and so on. (Apologies to those who are color blind)
The resultant tree would be as follows:
I'm working in C# but don't figure it's relevant to the question.
Thank you
EDIT 1
A more concise question might be "How do I generate this tree with the correct order?" (given data in no particular order). Is this just your basic textbook "binary search tree insertion" that I'm over-thinking maybe?
EDIT 2
Attempting to convert Norlesh's pseudo-code into c# and tie it into my existing code, I ended up with the following:
// Return list of shapes contained within container contour but no other
private List<NPContour> DirectlyContained(NPContour container, List<NPContour> contours)
{
List<NPContour> result = new List<NPContour>();
foreach (NPContour contour in contours)
{
if (container.Contains(contour))
{
foreach (NPContour other in contours)
{
if (other.Contains(contour))
break;
result.Add(contour);
}
}
}
return result;
}
// Recursively build tree structure with each node being a list of its children
private void BuildTree(NPContourTreeNode2 parent, List<NPContour> contours)
{
List<NPContour> children = DirectlyContained(parent.Contour, contours);
if (children.Count > 0)
{
// TODO: There's probably a faster or more elegant way to do this but this is clear and good enough for now
foreach (NPContour child in children)
{
contours.Remove(child);
parent.Children.Add(new NPContourTreeNode2(child));
}
foreach (NPContourTreeNode2 child in parent.Children)
{
BuildTree(child, contours);
}
}
}
... And the calling code ....
List<NPContour> contours = new List<NPContour>();
List<NPContour> _topLevelContours = new List<NPContour>();
bool contained = false;
foreach (NPChain chain in _chains)
{
if (chain.Closed)
{
NPContour newContour = new NPContour(chain);
contours.Add(newContour);
}
}
//foreach (NPContour contour in contours)
for (int i = 0; i < contours.Count(); i++)
{
contained = false;
foreach (NPContour container in contours)
{
if (container.Contains(contours[i]))
{
contained = true;
continue;
}
}
if (contained == false)
{
_topLevelContours.Add(contours[i]);
contours.Remove(contours[i]);
}
}
foreach (NPContour topLevelContour in _topLevelContours)
{
NPContourTreeNode2 topLevelNode = new NPContourTreeNode2(topLevelContour);
BuildTree(topLevelNode, contours);
}
I'm thinking I must have misinterpreted something in the translation because it isn't working. I'm going to keep plugging away at it but thought I'd post the code here in hopes someone may help point out my error.
Note that there was a discrepancy in the pseudocode in that buildTree didn't return anything, but in the calling code a return value is appended to ... well, I got a bit confused where exactly it was supposed to be going there anyway. I got the general idea of the example but I think there may have been some important points that were lost on me.
So far in my brief debugging, I seem to get more than one top level shape from the example below (whereas there should only be one) and multiples of the various children (something like 55?). I hope to be able to give more debugging information later.
Here is some pseudo code that should achieve what your trying to do:
// return true if shape is enclosed completely inside container
function contains(container, shape);
// return list of shapes contained within container shape but no other.
function directlyContained(container, shapes) {
result = []
for (shape in shapes) {
if (contains(container, shape)) {
// check its not further down hierarchy
for (other in shapes) {
if (contains(other, shape)) {
break // not the top level container
}
result.append(shape)
}
}
}
return result;
}
// recursively build tree structure with each node being a list of its children
// - removes members of shapes list as they are claimed.
function buildTree(parent, shapes) {
children = directlyContained(parent, shapes)
if (children.length > 0) {
shapes.remove(children);
parent.append(children);
for (child in children) { // recall on each child
buildTree(child, shapes);
}
}
}
function findTopLevel(shapes) {
result = []
// find the one or more top level shapes that are not contained
for shape in shapes {
contained = false;
for (container in shapes) {
if (contains(container, shape)) {
contained = true;
continue;
}
}
if (contained = false) {
scene.append(shape);
shapes.remove(shape);
}
}
return result;
}
shapes = <...>; // list initialized with the unsorted shapes
scene = findTopLevel(shapes);
shapes.remove(scene);
for (top in scene) {
buildTree(top, shapes);
}

NAudio fft result gives intensity on all frequencies C#

I have a working implementation of NAudio's wasapi loopback recording and the FFT of the data.
Most of the data I get is just as it should be but every once in a while (10 sec to minutes intervals) it shows amplitude on almost all frequencies.
Basicly the picture is rolling from right to left with time and frequencies going on logarithmic scale from lowest frequencies on the bottom. The lines are the errors. As far as i can tell those are not supposed to be there.
I get the audio buffer and send the samples to an aggregator (applies Hamming window) which implements the NAudio FFT. I have checked the data (FFT result) before I modify it in any way (the picture is not from the raw FFT output, but desibel scaled) confirming the FFT result is giving those lines. I could also point out the picture is modified with LockBits so I thought I had something wrong with the logic there, but that's why I checked the FFT output data which shows the same problem.
Well I could be wrong and the problem might be somewhere I said it isn't but it really seems it originates from the FFT OR the buffer data (data itself or the aggregation of samples). Somehow I doubt the buffer itself is corrupted like this.
If anyone has any idea what could cause this I would greatly appreciate it!
UPDATE
So I decided to draw the whole FFT result range rather than half of it. It showed something strange. I'm not sure of FFT but I thought Fourier transformation should give a result that is mirrored around the middle. This certainly is not the case here.
The picture is in linear scale so the exact middle of the picture is the middle point of the FFT result. Bottom is the first and top is the last.
I was playing a 10kHz sine wave which gives the two horizontal lines there but the top part is beyond me. It also seems like the lines are mirrored around the bottom quarter of the picture so that seems strange to me as well.
UPDATE 2
So I increased the FFT size from 4096 to 8192 and tried again. This is the output with me messing with the sine frequency.
It would seem the result is mirrored twice. Once in the middle and then again on the top and bottom halves. And the huge lines are now gone.. And it would seem like the lines only appear on the bottom half now.
After some further testing with different FFT lengths it seems the lines are completely random in that account.
UPDATE 3
I have done some testing with many things. The latest thing I added was overlapping of samples so that I reuse the last half of the sample array in the beginning of the next FFT. On Hamming and Hann windows it gives me massive intensities (quite like in the second picture I posted) but not with BlackmannHarris. Disabling overlapping removes the biggest errors on every window function. The smaller errors like in the top picture still remain even with BH window. I still have no idea why those lines appear.
My current form allows control over which window function to use (of the three previously mentioned), overlapping (on/off) and multiple different drawing options. This allows me to compare all the affecting parties effects when changed.
I shall investigate further (I am quite sure I have made a mistake at some point) but good suggestions are more than welcome!
The problem was in the way I handled the data arrays. Working like a charm now.
Code (removed excess and might have added mistakes):
// Other inputs are also usable. Just look through the NAudio library.
private IWaveIn waveIn;
private static int fftLength = 8192; // NAudio fft wants powers of two!
// There might be a sample aggregator in NAudio somewhere but I made a variation for my needs
private SampleAggregator sampleAggregator = new SampleAggregator(fftLength);
public Main()
{
sampleAggregator.FftCalculated += new EventHandler<FftEventArgs>(FftCalculated);
sampleAggregator.PerformFFT = true;
// Here you decide what you want to use as the waveIn.
// There are many options in NAudio and you can use other streams/files.
// Note that the code varies for each different source.
waveIn = new WasapiLoopbackCapture();
waveIn.DataAvailable += OnDataAvailable;
waveIn.StartRecording();
}
void OnDataAvailable(object sender, WaveInEventArgs e)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new EventHandler<WaveInEventArgs>(OnDataAvailable), sender, e);
}
else
{
byte[] buffer = e.Buffer;
int bytesRecorded = e.BytesRecorded;
int bufferIncrement = waveIn.WaveFormat.BlockAlign;
for (int index = 0; index < bytesRecorded; index += bufferIncrement)
{
float sample32 = BitConverter.ToSingle(buffer, index);
sampleAggregator.Add(sample32);
}
}
}
void FftCalculated(object sender, FftEventArgs e)
{
// Do something with e.result!
}
And the Sample Aggregator class:
using NAudio.Dsp; // The Complex and FFT are here!
class SampleAggregator
{
// FFT
public event EventHandler<FftEventArgs> FftCalculated;
public bool PerformFFT { get; set; }
// This Complex is NAudio's own!
private Complex[] fftBuffer;
private FftEventArgs fftArgs;
private int fftPos;
private int fftLength;
private int m;
public SampleAggregator(int fftLength)
{
if (!IsPowerOfTwo(fftLength))
{
throw new ArgumentException("FFT Length must be a power of two");
}
this.m = (int)Math.Log(fftLength, 2.0);
this.fftLength = fftLength;
this.fftBuffer = new Complex[fftLength];
this.fftArgs = new FftEventArgs(fftBuffer);
}
bool IsPowerOfTwo(int x)
{
return (x & (x - 1)) == 0;
}
public void Add(float value)
{
if (PerformFFT && FftCalculated != null)
{
// Remember the window function! There are many others as well.
fftBuffer[fftPos].X = (float)(value * FastFourierTransform.HammingWindow(fftPos, fftLength));
fftBuffer[fftPos].Y = 0; // This is always zero with audio.
fftPos++;
if (fftPos >= fftLength)
{
fftPos = 0;
FastFourierTransform.FFT(true, m, fftBuffer);
FftCalculated(this, fftArgs);
}
}
}
}
public class FftEventArgs : EventArgs
{
[DebuggerStepThrough]
public FftEventArgs(Complex[] result)
{
this.Result = result;
}
public Complex[] Result { get; private set; }
}
And that is it I think. I might have missed something though.
Hope this helps!

Changing GameState based on an if statement?

I'll get to the point. Having an issue with a beginner level game im coding at the moment. I have 2 lists to store "Objects" that are in the game. One is for "diamonds" pushable blocks that are to be moved onto the "Goals". Once all diamonds are on the goals, the level should change. I'm currently using "GameStates" to load each level. Here is the snippet of my code I'm having issues with. What happens currently is the game will allow me to push the "diamonds" onto the "goals", but the gamestate will not change once I do this. Not sure what I am missing - any help is appreciated. Thankyou for your time!
void Level1Update(KeyboardState cKB, KeyboardState oKB)
{
for (int i = 2; i < diamondlist.Count; i++)
{
if ((Goallist[i].Position == diamondlist[i].Position))
{
CurrentGameState = GameState.Level2;
}
}
}
If I understood correctly, you want to set current game state to the next level only if all the diamonds and goals are on the same tiles. The following code ensures that.
void Level1Update(KeyboardState cKB, KeyboardState oKB)
{
int i;
for (i = 0; i < diamondlist.Count; ++i)
{
if (Goallist[i].Position != diamondlist[i].Position)
break;
}
// When breaked off the loop, i is never equal to list count
if (i == diamondList.Count)
CurrentGameState = GameState.Level2;
}

How to use Thread.Sleep to animate a Binary Tree?

I've been working on a program that visually outputs the contents of a binary tree (represented in turn by classes that I wrote myself). The last feature I want to include in this program is an animation of the postorder, inorder, and preorder construction of the tree.
This has proven much more challenging than I thought. Here's the original Draw Method:
private void DrawNode(int x, int y, BinaryTreeNode<T> node, int nodeLevel, int maxDepth, int connectX = -1, int connectY = -1, )
{
//calculate distance between the node's children
int distance = CalculateDistance(nodeLevel, maxDepth);
//draw the node at the specified coordinate
node.Draw(x, y, this.device);
if (node.Left != null)
{
DrawNode(x - distance / 2, y + 50, node.Left, nodeLevel + 1, maxDepth, x, y, node);
}
if (node.Right != null)
{
DrawNode(x + distance / 2, y + 50, node.Right, nodeLevel + 1, maxDepth, x, y, node);
}
//connect the node to its parent
if ((connectX != -1) && (connectY != -1))
{
node.Connect(connectX, connectY, device);
}
this.display.Image = surface;
}
My original idea was to simply put Thread.Sleep(1000) inside each of the first two if clauses - all I really needed to do was pause the execution of the program for 1 second before each drawing of a node.
I realized that the Sleep method was blocking the execution of the drawing code, so I gave up on that method.. I then tried to use Timers, but found it impossibly difficult when dealing with the tree.
My goal is to simply find a way to pause program execution without disrupting the GUI's responsiveness and without overly complicating the code..
Any help would be appreciated :).
Edit: Some potentially relevant information: The program runs on Winforms, all graphics are handled via GDI+. If you need any other information, just ask :)
Edit: For SLaks,
//draw the node's children
if (drawChildren)
{
if (node.Left != null)
{
if (this.timer2.Enabled)
{
this.timer2.Stop();
}
if (!this.timer1.Enabled)
{
this.timer1.Start();
}
this.count1++;
this.timer1.Tick += (object source, EventArgs e) =>
{
this.count1--;
DrawNode(x - distance / 2, y + 50, node.Left, nodeLevel + 1, maxDepth, x, y, node);
if (this.count1 == 0)
{
this.timer1.Stop();
}
};
}
else
{
this.timer1.Stop();
this.timer2.Start();
}
if (node.Right != null)
{
this.count2++;
this.timer2.Tick += (object source, EventArgs e) =>
{
this.count2--;
DrawNode(x + distance / 2, y + 50, node.Right, nodeLevel + 1, maxDepth, x, y, node);
if (this.count2 == 0)
{
this.timer2.Stop();
}
};
}
}
Use a timer and set an appropriate interval for updates. In the Tick event perform the next step of drawing and display it.
First, write yourself a DrawNodesForLevel(int level) function. Then start at the top level, start the timer, every time it ticks, call DrawNodesForLevel() with the appropriate level, and increment the level. When you get to the end, stop the timer.
EDIT: Updated with the understanding that you want to pause between each node, not each level.
Move the variables in your function to their own DrawNodeState class, and pass the instance of that class whenever you call DrawNode(). Then, instead of having DrawNode() call itself, have DrawNode() start a timer (also part of the DrawNodeState class). When that timer ticks, the tick function calls DrawNode() and passes it the state structure.
The state structure is also going to have to track whether it last drew the left or right node, so it can draw the appropriate node next.
Split your code into 2 parts - one traversing the tree, another rendering (which you already have).
Rewrite your "traverse tree" code to be IEnumerable<node> so you can pick nodes one by one. There are non-recursive verions of tree traversal for any order, so you can use "yield return" to make iterator. You should be able to create simple tests to verify the code (no UI necessary for this).
Than in the timer callback simply take next item from the iterator till all done.
One possible solution would be to spawn a separate thread, then use that thread to invoke the DrawNode function at a periodic interval. This way the UI thread will not be blocked.
Since the thread you spawned will not be the UI thread, you will need to explicitly invoke the DrawNode function on the UI thread. Here's one potential way of doing that:
How to update the GUI from another thread in C#?

Categories

Resources