For loop that evaluates all values at once? - c#

So i have a cellular automaton, where i can place pixels on an image and they just move down one pixel each "tick". Now the problem is since the for loop is like this:
for(int x = 0; x < 100; x++){
for(int y = 0; y < 100; y++){
//Check if nothing below (x,y) pixel and move it down if so
}
}
Then the pixels get teleported to the bottom because they get moved down every iteration of the y loop. I solved it by making the y loop go from 100 down to 0 instead of 0 to 100, so its iterating upwards but it wont work if i want to make my pixels move upwards in certain situations.
Maybe a double loop where it makes a list of which pixels to move and where in the first one and actually do it in the second but that seems quite performance heavy and im sure there is a better solution
PS: if you have a better title for the question, let me know

You need two copies of the cells. In pseudo code:
int[] currentCells = new int[...];
int[] nextCells = new int[...];
Initialize(currentCells);
while (true) {
Draw(currentCells);
Calculate next state by using currentCells as source and store result into nextCells;
// exchange (this copies only references and is fast).
var temp = currentCells;
currentCells = nextCells;
nextCells = temp;
}
Note that we loop through each cell of the destination (nextCells) to get a new value for it. Throughout this process we never look at the cells in nextCells, because these could be moved ones already. Our source is strictly currentCells which now represents the previous (frozen) state.
// Calculate next state.
for(int x = 0; x < 100; x++){
for(int y = 0; y < 100; y++){
if(currentCells[x, y] == 0 && y > 0) { // Nothing here
// Take value from above
nextCells[x, y] = currentCells[x, y - 1];
} else {
// Just copy
nextCells[x, y] = currentCells[x, y];
}
}
}
In Conway's Game of Life, for instance, you calculate the state of a cell by analyzing the values of the surrounding cells. This means that neither working upwards nor downwards will work. By having 2 buffers, you always have a source buffer that is not changed during the calculation of the next state.

Would something like this work, assuming you've got what you want to do inside the inner for loop correct?
static void MovePixels(bool moveUp)
{
for (int x = 0; x < 100; x++)
{
if (moveUp)
{
for (int y = 0; y < 100; y++)
{
}
}
else
{
for (int y = 100; y > 0; y--)
{
}
}
}
}

Related

C# - Searching for a Point on Lists

I'm creating a List of points for each quadcopter to create a safe area around it and avoid other quadcopters to go near each other.
My code already creates a list of points to create a safe area around it (since distance is going from -20 to +20 it creates 1600 points (40*40)).
Now I want to compare if the drone[k].posicao_atual (actual position) is inside the safe area of other drones. If it does I just want a debug message for now.
I asked for a code to search every other list except the list created by the drone itself (the last If statement and it never goes true. Even when the drone is inside the safe area it never enters the if statement).
Any help?
PointF posicao_desejada = new Point(0, 0);
PointF posicao_atual = new Point(0, 0);
List<PointF>[] lista_colisoes;
int distancia = 20;
for (int i = 0; i < drone.Length; i++)
{
lista_colisoes[i] = new List<PointF>();
}
for (int k = 0; k < drone.Length; k++)
{
lista_colisoes[k].Clear();
for (int i = (int)posicao_atual.X - distancia; i <= (int)posicao_atual.X + distancia; i++)
{
for (int j = (int)posicao_atual.Y - distancia; j <= (int)posicao_atual.Y + distancia; j++)
{
lista_colisoes[k].Add(new PointF(i, j));
}
}
if (Enumerable.Range(0, drone.Length).Where(i => i != k).
Any(list => lista_colisoes.Any(ponto => ponto.Equals(drone[k].posicao_atual))))
{
Debug.WriteLine("Entered Safe Area")
//never enters here
}
}
The Green drone is inside the Red's drone safe area and it doesnt enter the if statement.
Image

go through matrix and get the lowest sum only going from left to right and from up to down only

I'm stuck with a college project and I wonder if you can help me have a hint on how to do this, I have to do it on c#.
Using an 80x80 matrix I have to go through it only from left to right and from up to down so I can find the path that gives me the lowest number when sum all the values from top left corner to bottom right corner.
As an example on this case the numbers that should be picked up are:
131,201,96,342,746,422,121,37,331 = 2427 the lowest number
It does not matter how many times you move to the right or down but what matters is to get the lowest number.
This is an interesting project in that it illustrates an important technique called dynamic programming: a solution to the entire problem can be constructed from a solution to a smaller sub-problem with a simple computation step.
Start with a recursive solution that wouldn't work for large matrix:
// m is the matrix
// R (uppercase) is the number of rows; C is the number of columns
// r (lowercase) and c are starting row/column
int minSum(int[,] m, int R, int C, int r, int c) {
int res;
if (r == R-1 && c == C-1) {
// Bottom-right corner - one answer
res = m[r,c];
} else if (r == R-1) {
// Bottom row - go right
res = m[r,c] + minSum(m, R, C, r, c+1);
} else if (c == C-1) {
// Rightmost column - go down
res = m[r,c] + minSum(m, R, C, r+1, c);
} else {
// In the middle - try going right, then try going down
int goRight = m[r,c] + minSum(m, R, C, r, c+1);
int goDown = m[r,c] + minSum(m, R, C, r+1, c);
res = Math.Min(goRight, goDown);
}
return res;
}
This will work for a 10×10 matrix, but it would take too long for a 80×80 matrix. However, it provides a template for a working solution: if you add a separate matrix of results you obtained at earlier steps, you would transform it into a faster solution:
// m is the matrix
// R (uppercase) is the number of rows; C is the number of columns
// known is the matrix of solutions you already know
// r (lowercase) and c are starting row/column
int minSum(int[,] m, int R, int C, int?[,] known, int r, int c) {
if (known[r,c].HasValue) {
return known[r,c];
}
int res;
... // Computation of the result goes here
known[r,c] = res;
return res;
}
This particular technique of implementing dynamic programming solutions is called memoization.
First step is always analysis, in particular to try to figure out the scale of the problem.
Ok assuming you can only ever step down or to the right, you will have 79 steps down and 79 steps to the right. 158 steps total of the form 011100101001 (1=move right, 0=move down) etc. Note that the solution space is not as much as 2^158 since not all binary numbers are possible... you must have exactly 79 downs and 79 rights. From combinatorics, this limits the number of possible correct answers to 158!/79!79!, which evaluates to still a very large number, something like 10^46.
You should realize is that this is quite large to brute-force, which methodology otherwise should definitely be a consideration for you if the project does not specifically rule it out, since it invariably makes the algorithm simpler (e.g. by simply iterating all the solution possibilities). I imagine the question has been designed this way in order to require you to use an algorithm that does not brute-force the correct answer.
The way to solve this problem without iterating the whole solution space is to realize that the best path to the lower right corner is the better of the two best paths to the squares immediately to the left of, and above, the lower right corner, and the best path to those is the best path to the next diagonal (numbers 524, 121, 111 in your diagram), and so on.
What you need to do is to treat each cell as a node in a graph and implement shortest path algorithm.
Dijkstra algorithm is one of them. You can find more information here https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
It is really simple, because You can divide the problem into solved and unsolved part and move items from unsolved into solved one by one. Start on top left and move through all "/" diagonals towards bottom right.
int size = 5;
int[,] matrix = new int[,] {
{131,673,234,103,18},
{201,96,342,965,150},
{630,803,746,422,111},
{537,699,497,121,956},
{805,732,524,37,331}
};
//Random rand = new Random();
//for (int y = 0; y < size; ++y)
//{
// for (int x = 0; x < size; ++x)
// {
// matrix[y, x] = rand.Next(10);
// }
//}
int[,] distance = new int[size, size];
distance[0, 0] = matrix[0, 0];
for (int i = 1; i < size * 2 - 1; ++i)
{
int y = Math.Min(i, size - 1);
int x = i - y;
while (x < size && y >= 0)
{
distance[y, x] = Math.Min(
x > 0 ? distance[y, x - 1] + matrix[y, x] : int.MaxValue,
y > 0 ? distance[y - 1, x] + matrix[y, x] : int.MaxValue);
x++;
y--;
}
}
for (int y = 0; y < size; ++y)
{
for (int x = 0; x < size; ++x)
{
Console.Write(matrix[y, x].ToString().PadLeft(5, ' '));
}
Console.WriteLine();
}
Console.WriteLine();
for (int y = 0; y < size; ++y)
{
for (int x = 0; x < size; ++x)
{
Console.Write(distance[y, x].ToString().PadLeft(5, ' '));
}
Console.WriteLine();
}
Console.WriteLine();

Populate listbox using for loop of year starting with 1913 and ending with 2013

I cannot get a listbox of years 1913-2013 using a for loop to work. This is the code I have so far..
lstYear.Items.Clear();
int[] year;
year = new int[100];
for (int y = 100; y > 1913; y++)
{
year[y] = y + 1;
lstYear.Items.Add(year[y]);
}
to add a list of DateTime objects from 1/1/1913 to 1/1/2013:
lstYear.Items.AddRange(Enumerable.Range(1913,101)
.Select(x => new DateTime(x,1,1)));
to add a list of ints from 1913 to 2013:
lstYear.Items.AddRange(Enumerable.Range(1913,101));
This loop:
for (int y = 100; y > 1913; y++)
{
year[y] = y + 1;
lstYear.Items.Add(year[y]);
}
Will never actually execute, since 100 is not greater than 1913. In a for loop, the loop will continue until the expression in the middle evaluates to false. You probably want:
for (int y = 0; y < 100; y++)
{
year[y] = y + 1913; // Start at 1913
lstYear.Items.Add(year[y]);
}
Also, I must ask, is there a need for the array at all? Why not just add the numbers directly into lstYear.Items? I'd probably write this as:
for (int y = 1913; y < 2014; y++)
{
lstYear.Items.Add(y.ToString()); // Not sure if .ToString is needed, but I think .Add() takes a string
}
Since you are new here is the structure you want.
You can also do it using a range, but that's out of question.
This question is how to populate using a "For" loop.
In your for loop you are starting at 100
for (int y = 1913; y <= 2013; y++)
lstYear.Items.Add(y);

Image processing task: Erosion C#

I am doing an image processing assignment where I want to implement erosion and dilation algorithm. It needs to look for each pixel in all directions (in this case up, down, left and right), so i'm using a plus structuring element. Here is my problem: I've got 4 for loops nested, which makes this operation very slow.
Can anyone tell me how to make the erosion process quicker without using unsafe method?
Here is what I have:
colorlistErosion = new List<Color>();
int colorValueR, colorValueG, colorValueB;
int tel = 0;
for (int y = 0; y < bitmap.Height; y++)
{
for (int x = 0; x < bitmap.Width; x++)
{
Color col = bitmap.GetPixel(x, y);
colorValueR = col.R; colorValueG = col.G; colorValueB = col.B;
//Erosion
for (int a = -1; a < 2; a++)
{
for (int b = -1; b < 2; b++)
{
try
{
Color col2 = bitmap.GetPixel(x + a, y + b);
colorValueR = Math.Min(colorValueR, col2.R);
colorValueG = Math.Min(colorValueG, col2.G);
colorValueB = Math.Min(colorValueB, col2.B);
}
catch
{
}
}
}
colorlistErosion.Add(Color.FromArgb(0 + colorValueR, 0+colorValueG, 0+colorValueB));
}
}
for (int een = 0; een < bitmap.Height; een++)
for (int twee = 0; twee < bitmap.Width; twee++)
{
bitmap.SetPixel(twee, een, colorlistErosion[tel]);
tel++;
}
how to make the erosion process quicker without using unsafe method?
You can turn the inner loops into Parallel.For().
But I'm not 100% sure if GetPixel() and especially SetPixel() are thread-safe. That is a deal-breaker.
Your algorithm is inherently slow due to the 4 nested loops. You're also processing the bitmap using the slowest approach possible bitmap.GetPixel.
Take a look at SharpGL. If they don't have your filters you can download the source code and figure out how to make your own.

finding maximum in a 3d matrix

I have matrix with 3 dimension (n*m*k). I am trying to fined the maximum number for each n and m by searching in k dimension.((I try to find the maximum number in k dimension for each n and m)) and at last i have a 2d matrix (n*m). i have the following code but it is so slow. Is there any new code or any changes to the current code that do this more quickly.
thanks.
my c# code: note: li is the 3 dimension matrix and they are grater or equal to zero.
int[,] array2 = new int[n, m];
int[,] array = new int[n, m];
List<Array> li = new List<Array>();
for(int k = 0; k <'not a specific value, change each time' ; k++)
{
li.Add(array);
%% changing array
} %% so li will became a (n*m*k) matrix
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
int ma = -2;
int d = 0;
while (d <= k)
{
ma = Math.Max(ma, Convert.ToInt32(li[d].GetValue(i, j)));
d++;
}
array2[i, j] = ma;
}
The biggest performance issue is that you use Array objects as elements of your list. This makes it so that every element access using GetValue boxes the value, i.e. allocates a new tiny object to hold the element value.
Your code will run a lot faster if you replace
List<Array> li = new List<Array>();
with
List<int[,]> li = new List<int[,]>();
and
ma = Math.Max(ma, Convert.ToInt32(li[d].GetValue(i, j)));
with
ma = Math.Max(ma, li[d][i, j];
Since you don't know the 3rd dimension in advance, it is harder to use 3D arrays.
An entirely different approach would be to compute the maximum as you're building the list li. This will help in two ways: 1. You avoid indexing into the list of arrays and 2. as long as m and n aren't too large, you improve locality. That is: the values you're working with are closer together in memory, and more likely to be in the processor cache.
This should do the trick (even though it could be kinda slower than your approach):
// put this at the top of your source file
using System.Linq;
// put this where you calculate the maxima
for(int i = 0; i < array2.GetLength(0); ++i)
for(int j = 0; j < array2.GetLength(1); ++j)
{
array2[i, j] = Convert.ToInt32(li.Max(x => x.GetValue(i, j)));
}
You could use a three-dimensional array like this:
int xRange = 10;
int yRange = 10;
int zRange = 10;
int[, ,] matrix = new int[xRange, yRange, zRange];
// set up some dummy values
for (int x = 0; x < xRange; x++)
for (int y = 0; y < yRange; y++)
for (int z = 0; z < zRange; z++)
matrix[x, y, z] = x * y * z;
// calculate maximum values
int[,] maxValues = new int[xRange, yRange];
/* LINQ version of maximum calculation
for (int x = 0; x < xRange; x++)
for (int y = 0; y < yRange; y++)
maxValues[x, y] = Enumerable.Range(0, zRange).Select(z => matrix[x, y, z]).Max();
*/
// longhand version of maximum calculation
for (int x = 0; x < xRange; x++)
for (int y = 0; y < yRange; y++)
for (int z = 0; z < zRange; z++)
maxValues[x, y] = Math.Max(maxValues[x, y], matrix[x, y, z]);
// display results
for (int x = 0; x < xRange; x++)
{
for (int y = 0; y < yRange; y++)
Console.Write("{0}\t", maxValues[x, y]);
Console.WriteLine();
}
From an algorithm perspective, there's no more efficient way to evaluate the maximum value for fixed n,m for all k. It will take O(n*m*k) operations.
Now, the only way to improve performance is to find improvements in your implementation, particularly in your storage of the 3D matrix.
Using List<Array> is a major area for improvement. You are prone to boxing issues (conversion of primitive types to objects) and making more function calls than are necessary.
Reduce your 3D matrix to an array of primitives:
int[] my3DArray = new int[n * m * l]; // Note I'm using l where you use k
Now index into your array at [i, j, k] using the following offset:
int elementAtIJK = my3DArray[i + (n * j) + (m * n * k)];
If you just use arrays of primitives you should see a definite improvement.
Edit:
In fact, in C# (and several other languages) it's very easy to implement 3D arrays directly, e.g.:
int[,,] my3DArray = new int[n,m,l];
int elementAtIJK = my3DArray[i,j,k];
Which is much simpler than I first described (but at the end of the day is internally translated in the 1D form).
What to do if the 3rd dimension varies in size...
Now, it gets more interesting if the size of the 3rd dimension varies significantly. If it has a known maximum and isn't too big, you can simply set it to the maximum and fill the empty values with zeroes. This is simple and may meet your needs.
However, if the 3rd dimension can be very big, all these extra stored zeroes could waste a lot of valuable space and what you need is a Sparse Matrix representation.
There are different storage mechanisms for sparse matrices. For your purposes, you could consider your 3D array to be a 2D matrix, with (n*m) rows and max(k) columns. As the 3rd dimension varies in length, there are lots of empty spaces in your columns. This is called a sparse row and the standard data storage for this is "Compressed Sparse Row". Again, for performance this can be represented just by three primitive arrays, a data array, a row index array and a column pointer array. There are resources elsewhere on the web that describe the CSR implementation better than I can, but hopefully this will point you in the right direction.

Categories

Resources