So I have been searching for an answer for this for about an hour now and I was unable to find one so I'm going to try my luck here.
The problem:
I have a 3 dimensional Array that contains Containers. This array is for an algoritm for placing containers on a cargoship. The array consists of Length, width and height. I am trying to split the array at the middle of the width.
The only solution I have been able to sort of make work is making 2, 3 dimensional arrays and then using 6 for loops to copy the big array:
Container[,,] leftSideOfShip = new Container[ship.length, ((ship.width) / 2), ship.height];
Container[,,] rightSideOfShip = new Container[ship.length, ((ship.width) / 2), ship.height];
for(int a = 0; a < ship.length; a++)
{
for(int b = 0; b < ship.width/2; b++)
{
for(int c = 0; c < ship.height; c++)
{
if(ship.position[a,b,c] != null)
{
leftSideOfShip[a, b, c] = ship.position[a, b, c];
}
}
}
}
for (int d = 0; d < ship.length; d++)
{
for (int e = ship.width/2; e < ship.width; e++)
{
for (int f = 0; f < ship.height; f++)
{
if(ship.position[d,e,f] != null)
{
rightSideOfShip[d, e, f] = ship.position[d, e, f];
}
}
}
}
The 3 for loops for the leftSideOfShip work as expected but the second one gives an indexOutOfRangeException.
Is there a better way to split this and if so how?
First of all, you need to be mindful of how you round side width in case the width of the ship is odd. For example, you can always assume, that the left side is wider in case the width of the ship is odd, something like that:
int leftSideWidth = ship.width % 2 == 0 ? ship.width / 2 : (ship.width / 2) + 1;
int rightSideWidth = ship.width / 2;
Second of all, you have an error in your second loop block:
since you are looping for (int e = ship.width/2; e < ship.width; e++) e is greater than second dimension of rightSideOfShip array.
Full solution will look something like this:
Container[,,] leftSideOfShip = new Container[ship.length, leftSideWidth, ship.height];
Container[,,] rightSideOfShip = new Container[ship.length, rightSideWidth, ship.height];
for (int i = 0; i < ship.length; i++)
{
for (int j = 0; j < ship.width; j++)
{
for (int k = 0; k < ship.height; k++)
{
if (j < leftSideWidth)
{
leftSideOfShip[i, j, k] = ship.position[i, j, k];
}
else
{
rightSideOfShip[i, j - leftSideWidth, k] = ship.position[i, j, k];
}
}
}
}
Related
So I wrote bucket sort implementation (I use rnd.NextDouble() to fill my array, so all the elements are in the range between 0 and 1). And I have number of experiments (10 experiments for each array size) and different array sizes (I start with 1000 and then +1000, etc. till 300.000). And sometimes it works fine, but sometimes it gives me OutOfRange exception:
public static void BucketSortImplement(ref int countOfElements, ref float[] array)
{
List<float>[] buckets = new List<float>[countOfElements];
for (int i = 0; i < countOfElements; i++)
{
buckets[i] = new List<float>();
}
for (int i = 0; i < countOfElements; i++)
{
float indexOfElement = array[i] * countOfElements;
buckets[(int)indexOfElement].Add(array[i]); // right here
}
for (int i = 0; i < countOfElements; i++)
{
for (int j = 0; j < buckets[i].Count; j++)
{
float keyElement = buckets[i][j];
int k = j - 1;
while (k >= 0 && buckets[i][k] > keyElement)
{
buckets[i][k + 1] = buckets[i][k];
k -= 1;
}
buckets[i][k + 1] = keyElement;
}
}
int arrayIndex = 0;
for (int i = 0; i < countOfElements; i++)
{
for (int j = 0; j < buckets[i].Count; j++)
{
array[arrayIndex++] = buckets[i][j];
}
}
}
I am a bit confused, because the algorithm itself looks fine, that is I have to calculate array[i] * countOfElements to get the index where I can put my element. Could you please direct me?
If you array contain value '1' it will lead to OutOfRange, because if you have a size of the list equal to 3 (for example) then valid indexes will be in the range [0, 2].
just started to learn programming and I need 2D array without duplicates. This code (well edited for 1D) worked just fine for 1D but doesn't for 2D and have no clue why.
Would be very happy if someone helped me. Thanks.
Random r = new Random();
int[,] array = new int[10, 8];
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
array[i, j] = r.Next(10, 100);
for (int k = 0; k < i; k++)
{
for (int l = 0; l < j; l++)
{
if (array[i,j] == array[k,l])
{
i--;
j--;
break;
}
}
}
}
}
With the nested j loop you are filling the entire second dimension for each i, but in the k and l loops you are only checking the grid to the upper and left of current cell. You could place a number twice because you are not checking every previously filled location.
If we change the code to this:
for (int k = 0; k < array.GetLength(0); k++)
{
for (int l = 0; l < array.GetLength(1); l++)
{
if (i != k && j != l && array[i, j] == array[k, l])
{
i--;
j--;
break;
}
}
}
Then you eliminate that problem, but you very quickly find that you get a IndexOutOfRangeException because you're decrementing both i & j at the same time. That's not moving you to the previous value - it's jumping back a whole row and left one cell - and that's ultimately sending i or j to -1 and that's not good.
If you want to do it like you're attempting then you need to have a way to simply move back to the previously filled cell, regardless of the row or column you're on.
Try this:
for (int x = 0; x < array.GetLength(0) * array.GetLength(1); x++)
{
array[x % array.GetLength(0), x / array.GetLength(0)] = r.Next(10, 100);
for (int y = 0; y < x; y++)
{
if (array[x % array.GetLength(0), x / array.GetLength(0)] == array[y % array.GetLength(0), y / array.GetLength(0)])
{
x--;
break;
};
}
}
However, that's not very efficient. Try this instead:
var values = Enumerable.Range(10, 90).OrderBy(_ => r.Next()).ToArray();
for (int x = 0; x < array.GetLength(0) * array.GetLength(1); x++)
{
array[x % array.GetLength(0), x / array.GetLength(0)] = values[x];
}
So, first of all, that just seems inefficient. Not sure why you want to do it this way, but then again, don't know the reason. Looks like a programming assignment.
My guess, you need a sort of double break going on. When you break finding a match, you don't break out to the "k" for loop, so you continue looking for a match even though you found one. Try setting a boolean value to say it's found, then use that in the criteria for the for loop for k. That'll break it out and let you start over on the outside loops for i and j.
Even then, it won't work because you indescriminately subtracted i and j. So if you're on position 1,2 you will jump back to 0,1 rather than 1,2. So you need to subtract j, if it drops below 0, then subtract from i and add "array.GetLength(1)" to j.
This solution depends on HashSet's property of containing unique elements. It has an Add method that returns false when we try to add existing elements.
Random r = new Random();
int[,] array = new int[10, 8];
var usedValues = new HashSet<int>();
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
int uniqueValue;
while (true)
{
uniqueValue = r.Next(10, 100);
if (usedValues.Add(uniqueValue)) break; // It is unique indeed
// It is not unique, try again.
}
array[i, j] = uniqueValue;
}
}
The above solution is more suitable when the range of the acceptable unique values is large. In this specific case the range is very small (10-99), and the solution offered by #Enigmativity is preferable.
I come looking for general tips about the program I'm writing now.
The goal is:
Use neural network program to recognize 3 letters [D,O,M] (or display "nothing is recognized" if i input anything other than those 3).
Here's what I have so far:
A class for my single neuron
public class neuron
{
double[] weights;
public neuron()
{
weights = null;
}
public neuron(int size)
{
weights = new double[size + 1];
Random r = new Random();
for (int i = 0; i <= size; i++)
{
weights[i] = r.NextDouble() / 5 - 0.1;
}
}
public double output(double[] wej)
{
double s = 0.0;
for (int i = 0; i < weights.Length; i++) s += weights[i] * wej[i];
s = 1 / (1 + Math.Exp(s));
return s;
}
}
A class for a layer:
public class layer
{
neuron[] tab;
public layer()
{
tab = null;
}
public layer(int numNeurons, int numInputs)
{
tab = new neuron[numNeurons];
for (int i = 0; i < numNeurons; i++)
{
tab[i] = new neuron(numInputs);
}
}
public double[] compute(double[] wejscia)
{
double[] output = new double[tab.Length + 1];
output[0] = 1;
for (int i = 1; i <= tab.Length; i++)
{
output[i] = tab[i - 1].output(wejscia);
}
return output;
}
}
And finally a class for a network
public class network
{
layer[] layers = null;
public network(int numLayers, int numInputs, int[] npl)
{
layers = new layer[numLayers];
for (int i = 0; i < numLayers; i++)
{
layers[i] = new layer(npl[i], (i == 0) ? numInputs : (npl[i - 1]));
}
}
double[] compute(double[] inputs)
{
double[] output = layers[0].compute(inputs);
for (int i = 1; i < layers.Length; i++)
{
output = layers[i].compute(output);
}
return output;
}
}
Now for the algorythm I chose:
I have a picture box, size 200x200, where you can draw a letter (or read one from jpg file).
I then convert it to my first array(get the whole picture) and 2nd one(cut the non relevant background around it) like so:
Bitmap bmp2 = new Bitmap(this.pictureBox1.Image);
int[,] binaryfrom = new int[bmp2.Width, bmp2.Height];
int minrow=0, maxrow=0, mincol=0, maxcol=0;
for (int i = 0; i < bmp2.Height; i++)
{
for (int j = 0; j < bmp2.Width; j++)
{
if (bmp2.GetPixel(j, i).R == 0)
{
binaryfrom[i, j] = 1;
if (minrow == 0) minrow = i;
if (maxrow < i) maxrow = i;
if (mincol == 0) mincol = j;
else if (mincol > j) mincol = j;
if (maxcol < j) maxcol = j;
}
else
{
binaryfrom[i, j] = 0;
}
}
}
int[,] boundaries = new int[binaryfrom.GetLength(0)-minrow-(binaryfrom.GetLength(0)-(maxrow+1)),binaryfrom.GetLength(1)-mincol-(binaryfrom.GetLength(1)-(maxcol+1))];
for(int i = 0; i < boundaries.GetLength(0); i++)
{
for(int j = 0; j < boundaries.GetLength(1); j++)
{
boundaries[i, j] = binaryfrom[i + minrow, j + mincol];
}
}
And convert it to my final array of 12x8 like so (i know I could shorten this a fair bit, but wanted to have every step in different loop so I can see what went wrong easier[if anything did]):
int[,] finalnet = new int[12, 8];
int k = 1;
int l = 1;
for (int i = 0; i < finalnet.GetLength(0); i++)
{
for (int j = 0; j < finalnet.GetLength(1); j++)
{
finalnet[i, j] = 0;
}
}
while (k <= finalnet.GetLength(0))
{
while (l <= finalnet.GetLength(1))
{
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * (k - 1); i < (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * k; i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * (l - 1); j < (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * l; j++)
{
if (boundaries[i, j] == 1) finalnet[k-1, l-1] = 1;
}
}
l++;
}
l = 1;
k++;
}
int a = boundaries.GetLength(0);
int b = finalnet.GetLength(1);
if((a%b) != 0){
k = 1;
while (k <= finalnet.GetLength(1))
{
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * finalnet.GetLength(0); i < boundaries.GetLength(0); i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * (k - 1); j < (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * k; j++)
{
if (boundaries[i, j] == 1) finalnet[finalnet.GetLength(0) - 1, k - 1] = 1;
}
}
k++;
}
}
if (boundaries.GetLength(1) % finalnet.GetLength(1) != 0)
{
k = 1;
while (k <= finalnet.GetLength(0))
{
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * (k - 1); i < (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * k; i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * finalnet.GetLength(1); j < boundaries.GetLength(1); j++)
{
if (boundaries[i, j] == 1) finalnet[k - 1, finalnet.GetLength(1) - 1] = 1;
}
}
k++;
}
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * finalnet.GetLength(0); i < boundaries.GetLength(0); i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * finalnet.GetLength(1); j < boundaries.GetLength(1); j++)
{
if (boundaries[i, j] == 1) finalnet[finalnet.GetLength(0) - 1, finalnet.GetLength(1) - 1] = 1;
}
}
}
The result is a 12x8 (I can change it in the code to get it from some form controls) array of 0 and 1, where 1 form the rough shape of a letter you drawn.
Now my questions are:
Is this a correct algorythm?
Is my function
1/(1+Math.Exp(x))
good one to use here?
What should be the topology? 2 or 3 layers, and if 3, how many neurons in hidden layer? I have 96 inputs (every field of the finalnet array), so should I also take 96 neurons in the first layer? Should I have 3 neurons in the final layer or 4(to take into account the "not recognized" case), or is it not necessary?
Thank you for your help.
EDIT: Oh, and I forgot to add, I'm gonna train my network using Backpropagation algorythm.
You may need 4 layers at least to get accurate results using back propagation method. 1 input, 2 middle layers, and an output layer.
12 * 8 matrix is too small(and you may end up in data loss which will result in total failure) - try some thing 16 * 16. If you want to reduce the size then you have to peel out the outer layers of black pixels further.
Think about training the network with your reference characters.
Remember that you have to feed back the output back to the input layer again and iterate it multiple times.
A while back I created a neural net to recognize digits 0-9 (python, sorry), so based on my (short) experience, 3 layers are ok and 96/50/3 topology will probably do a good job. As for the output layer, it's your choice; you can either backpropagate all 0s when the input image is not a D, O or M or use the fourth output neuron to indicate that the letter was not recognized. I think that the first option would be the best one because it's simpler (shorter training time, less problems debugging the net...), you just need to apply a threshold under which you classify the image as 'not recognized'.
I also used the sigmoid as activation function, I didn't try others but it worked :)
I'm trying to make a program that: When given a 4 digit number (for example, 1001) it sums the digits of that number, for 1001 this is 1 + 0 + 0 + 1 = 2, than it finds all sequences of 6 numbers from 1 to 6 (including permutations, i.e. 1*1*1*1*1*2 is different than 2*1*1*1*1*1) whose product is that number.
The result should be printed on the console in the following format: each sequence of 6 numbers, with their Morse representation, separated with a single pipe: 1 is .---- , 2 is ..---: .----|.----|.----|.----|..---|, on a new row the next permutation: .----|.----|.----|..---|.----| and so on.
The problem is, my solution doesn't show the correct answers, not even the correct number of them.
Here's my code (and please, if possible, tell me where my mistake is, and not some one line hack solutions to the problem with LINQ and regex and God knows what):
string n = Console.ReadLine();
string[] digitsChar = new string[n.Length];
for (int i = 0; i < 4; i++)
{
digitsChar[i] = n[i].ToString();
}
int[] digits = new int[digitsChar.Length];
for (int i = 0; i < 4; i++)
{
digits[i] = Convert.ToInt32(digitsChar[i]);
}
int morseProduct = digits.Sum();
Console.WriteLine(morseProduct);
List<int> morseCodeNumbers = new List<int>();
for (int i = 1; i < 6; i++)
{
for (int j = 1; i < 6; i++)
{
for (int k = 1; i < 6; i++)
{
for (int l = 1; i < 6; i++)
{
for (int m = 1; i < 6; i++)
{
for (int o = 1; o < 6; o++)
{
int product = i * j * k * l * m * o;
if (product == morseProduct)
{
morseCodeNumbers.Add(i);
morseCodeNumbers.Add(j);
morseCodeNumbers.Add(k);
morseCodeNumbers.Add(l);
morseCodeNumbers.Add(m);
morseCodeNumbers.Add(o);
}
}
}
}
}
}
}
int numberOfNumbers = morseCodeNumbers.Count;
string[] morseCodes = new string[] { "-----", ".----", "..---", "...--", "....-", "....." };
for (int i = 0; i < numberOfNumbers; i++)
{
int counter = 0;
if (i % 5 == 0)
{
Console.WriteLine();
counter = 0;
}
if (counter < 5)
{
int index = morseCodeNumbers[i];
Console.Write(morseCodes[index] + "|");
counter++;
}
A lot of your for-loop conditions refer to i instead of j,k,l and m. The same for the increment part. For example:
for (int j = 1; i < 6; i++)
should be
for (int j = 1; j < 6; j++)
Furthermore if the range is from 1 to 6 you need to change < to <=, see:
for (int i = 1; i <= 6; i++)
You don't need to convert the string to a string array to get the int array of digits btw, so while this is correct:
for (int i = 0; i < 4; i++)
{
digitsChar[i] = n[i].ToString();
}
int[] digits = new int[digitsChar.Length];
for (int i = 0; i < 4; i++)
{
digits[i] = Convert.ToInt32(digitsChar[i]);
}
you could it do like that (sry for LINQ):
var digits = n.Select(c=>(int)char.GetNumericValue(c) ).ToArray();
I am trying to calculate all the Combinations of a 7 digit number. Each digit can occupy basically two values that's why I am calling it a binary number.
The digit are represented by FNMSDPL. Basically I want all the combinations of values and their sum.
I wrote the below code but its not working.
F[0] = 9.29;
F[1] = -4.47;
N[0] = 9.64;
N[1] = -5.77;
M[0]= -7.48;
M[1] = -2.13;
S[0] = 25.85;
S[1]= -3.55;
D[0]= 12.14;
D[1] = -4.90;
P[0] = 8.65;
P[1]= -0.85;
L[0] = 9.14;
L[1]= -1.73;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
for (int k = 0; k < 2; k++)
{
for (int l = 0; l < 2; k++)
{
for (int m = 0; m < 2; m++)
{
for (int n = 0; n < 2; n++)
{
for (int o = 0; 0 < 2; o++)
{
double count = F[i] + M[j] + L[k] + S[l] + D[m] + P[n] + L[o];
System.Console.WriteLine(count);
}
}
}
}
}
}
}
Error Message:
Index was outside the bounds of the array.
I am getting the above error at "double count =" line.
The font selection on Stack Overflow may have resolved this one
for (int o = 0; 0 < 2; o++)
The condition should be using o instead of 0. (Tip: avoid using o or O as variable names.)
Edit: Another problem here (should be incrementing l, not k):
for (int l = 0; l < 2; k++)
I guess this won't work as expected:
for (int l = 0; l < 2; k++)
You should probably use something more clever than 7 nested for loops (since, as the other answers point out, this is terribly prone to error, especially when you have to make up 14 variable names). A recursive solution would do nicely here.
As for the sum, you don't need to generate all possibilities to know the sum of all 128 possible numbers. Observe that each binary digit (0 or 1) occurs exactly 64 times in each slot, so the sum total is just 64 times the sum of the 14 floats in your arrays.