for(int i = 0; i <= 3; i++)
{
float offsetFraction = ((float)(i+1))/(4);
}
gives 0.25, 0.5, 0.75, 1 respectively.
What I would like to get is in the order;
1, 0.75, 0.5, 0.25
I could not figure out the required code to get it. Can somebody have an idea how to get these values respectively? Thanks.
Use:
for(int i = 3; i >= 0; i--)
{
float offsetFraction = ((float)(i+1))/(4);
}
This starts with the value 3 for i and decrements it at each loop iteration.
Unless you are using i for something else, this is simpler to understand:
for(int i = 4; i >= 1; i--)
{
float offsetFraction = ((float)i)/(4);
}
As you commented that you are using i for something else, perhaps you want the value 0 for i correspond to 0.75 for offsetFraction, 1 correspond to 0.5, and so on:
for(int i = 0; i <= 3; i++)
{
float offsetFraction = ((float)(4-i))/(4);
}
Related
I am trying to create a simple Bingo game and want to make sure the numbers are not repeating on the bingo card. I have a random number generator, but for some reason the code I'm using doesn't work as the same numbers will constantly repeat. Could somebody please take a look at my code below and either tell me what I need to fix or fix the code for me?
public Grid(int width, int height, float cellSize)
{
this.width = width;
this.height = height;
this.cellSize = cellSize;
gridArray = new int[width, height];
debugTextArray = new TextMesh[width, height];
for (int x = 0; x < gridArray.GetLength(0); x++)
{
for (int y = 0; y < gridArray.GetLength(1); y++)
{
debugTextArray[x, y] = UtilsClass.CreateWorldText(gridArray[x, y].ToString(), null, GetWorldPosition(x, y) + new Vector3(cellSize, cellSize) * .5f, 20, Color.white, TextAnchor.MiddleCenter);
Debug.DrawLine(GetWorldPosition(x, y), GetWorldPosition(x, y + 1), Color.white, 100f);
Debug.DrawLine(GetWorldPosition(x, y), GetWorldPosition(x + 1, y), Color.white, 100f);
}
}
Debug.DrawLine(GetWorldPosition(0, height), GetWorldPosition(width, height), Color.white, 100f);
Debug.DrawLine(GetWorldPosition(width, 0), GetWorldPosition(width, height), Color.white, 100f);
for (int x = 0; x <= 4; x++)
{
RandomValue(0, x);
RandomValue(1, x);
RandomValue(2, x);
RandomValue(3, x);
RandomValue(4, x);
}
}
private Vector3 GetWorldPosition(int x, int y)
{
return new Vector3(x, y) * cellSize;
}
public void RandomValue(int x, int y)
{
if (x >= 0 && y >= 0 && x < width && y < height)
{
list = new List<int>(new int[Lenght]);
for (int j = 0; j < 25; j++)
{
Rand = UnityEngine.Random.Range(1, 50);
while (list.Contains(Rand))
{
Rand = UnityEngine.Random.Range(1, 50);
}
list[j] = Rand;
gridArray[x, y] = list[j];
}
debugTextArray[x, y].text = gridArray[x, y].ToString();
debugTextArray[2, 2].text = "Free";
}
}
Basically your concept in function RandomValue() is correct, but problem is it only check in same column, so you have to bring the concept of RandomValue() to Grid() level. You need a List contain all approved value, then check Contains() at Grid().
But in fact you can do it in all one go.
Make sure your width*height not larger than maxValue.
Dictionary<Vector2Int, int> CreateBingoGrid(int width, int height, int maxValue)
{
var grid = new Dictionary<Vector2Int, int>();
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
var num = Random.Range(1, maxValue);
while (grid.ContainsValue(num))
{
num = Random.Range(1, maxValue);
}
grid.Add(new Vector2Int(x, y), num);
}
}
return grid;
}
As mentioned in the comment on your question, it's probably the easiest to just shuffle the numbers in the range [1,50] and then take the first 25 or however many you want.
The reason your code isn't working properly and you see a lot of repeats is because you're calling the RandomValue() function multiple separate times and the list variable you're comparing against if a value is already on the chart is inside of that function. Meaning that it will only ever check the values it has generated in that call, in this case meaning only for one row.
Also, if you make a list that you know will always be the same size, you should use an array instead. Lists are for when you want the size to be adjustable.
Solution 1:
A very simple way to generate an array with the numbers 1-50 would be to do this:
//Initialize Array
int[] numbers = new int[50];
for (int i = 1; i <= numbers.Length; i++)
{
numbers[i] = i;
}
//Shuffle Array
for (int i = 0; i < numbers.Length; i++ )
{
int tmp = numbers[i];
int r = Random.Range(i, numbers.Length);
numbers[i] = numbers[r];
numbers[r] = tmp;
}
//Get first 'n' numbers
int[] result = Array.Copy(numbers, 0, result, 0, n);
return result;
I'm not sure if it's the most efficient way, but it would work.
Solution 2:
To change your code to check against the entire list, I would change this section:
for (int x = 0; x <= 4; x++)
{
RandomValue(0, x);
RandomValue(1, x);
RandomValue(2, x);
RandomValue(3, x);
RandomValue(4, x);
}
To something like this:
List<int> values = new List<int>();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int r = RandomValue(1, 50);
while (values.Contains(r))
{
r = RandomValue(1, 50);
}
values[y * width + x].Add(r);
gridArray[x, y] = r;
}
}
int RandomValue(int min, int max) {
return UnityEngine.Random.Range(min, max);
}
Hope this helps!
I made a Noise class using the Perlin Noise from Unity like this:
public static float[,] GetNoise(Vector2Int initialOffset, float scale, float persistance, float lacunarity, int octaves)
{
float[,] noiseMap = new float[Chunk.width, Chunk.height];
float maxHeight = 0;
float minHeight = 0;
for (int y = 0; y < Chunk.height; y++)
{
for (int x = 0; x < Chunk.width; x++)
{
float amplitude = 1;
float frequency = 1;
float noiseHeight = 0;
for (int oc = 0; oc < octaves; oc++)
{
float coordX = (x + initialOffset.x) / scale * frequency;
float coordY = (y + initialOffset.y) / scale * frequency;
float perlin = Mathf.PerlinNoise(coordX, coordY) * 2 - 1;
noiseHeight += perlin * amplitude;
amplitude *= persistance;
frequency *= lacunarity;
}
if (noiseHeight < minHeight)
{
minHeight = noiseHeight;
}
if (noiseHeight > maxHeight)
{
maxHeight = noiseHeight;
}
noiseMap[x, y] = noiseHeight;
}
}
for (int y = 0; y < Chunk.height; y++)
{
for (int x = 0; x < Chunk.width; x++)
{
noiseMap[x, y] = Mathf.InverseLerp(minHeight, maxHeight, noiseMap[x, y]);
}
}
return noiseMap;
}
However this code is giving me repeating patterns like this:
What am I doing wrong? Or there is no way to get rid of the patterns?
I got it working, not very well, but working. The way I did was I generate the height map for every tile in the chunk, then I did some random placing of tiles, while having in account the height map. Something like this:
if (heightMap[x, y] < 0.3 && Random.value < 0.5)
// Add tile
This way I got this result:
EDIT:
Doing some more research about Perlin Noise I found out that it just doesn't like negative coords for some reason, so I did this way, hope this helps someone!
so .. fixed the negative coords like this:
//account for negatives (ex. -1 % 256 = -1, needs to loop around to 255)
if (noiseOffset.x < 0)
noiseOffset = new Vector2(noiseOffset.x + noiseRange.x, noiseOffset.y);
if (noiseOffset.y < 0)
noiseOffset = new Vector2(noiseOffset.x, noiseOffset.y + noiseRange.y);
Hello everyone This is the code of iRPROP+ algo for my MLP. When I try to train my network, standart deviation decreases for 1500 epoches (so slow: from ~0.5 to 0.4732) but suddenly it starts to increase.
Can someone say what did I do wrong?
public void RPROP()
{
double a = 1.2, b = 0.5, nMax = 50, nMin = 0.000001;
for (int l = Network.Length - 1; l > 0; l--)
{
for (int i = 0; i < Network[l].getSize(); i++)
{
Neuron n = Network[l].Neurons[i];
double sum = 0;
if (l == Network.Length - 1) n.Delta = (n.Output - DesiredOutput[i]) * ActFunc.calcDeprivateFunction(n.Output);
else
{
for (int k = 0; k < Network[l + 1].getSize(); k++)
{
sum += Network[l + 1].Neurons[k].getWeight(i) * Network[l + 1].Neurons[k].Delta;
}
n.Delta = sum * ActFunc.calcDeprivateFunction(n.Output);
}
}
}
for (int l = 1; l < Network.Length; l++)
{
for (int i = 0; i < Network[l].getSize(); i++)
{
Neuron n = Network[l].Neurons[i];
if ((n.PrevDelta * n.Delta) > 0)
{
n.N = Math.Min(a * n.PrevN, nMax);
n.Bias -= n.N * Math.Sign(n.Delta);
for (int j = 0; j < Network[l - 1].getSize(); j++)
{
n.setWeight(j, n.getWeight(j) - n.N * Math.Sign(n.Delta));
}
n.PrevDelta = n.Delta;
}
else if ((n.PrevDelta * n.Delta) < 0)
{
n.N = Math.Max(b * n.PrevN, nMin);
if (this.CurrentError > this.LastError)
{
n.Bias += n.PrevN * Math.Sign(n.PrevDelta);
for (int j = 0; j < Network[l - 1].getSize(); j++)
{
n.setWeight(j, n.getWeight(j) + n.PrevN * Math.Sign(n.PrevDelta));
}
}
n.Delta = 0;
}
else if ((n.PrevDelta * n.Delta) == 0)
{
n.Bias -= n.N * Math.Sign(n.Delta);
for (int j = 0; j < Network[l - 1].getSize(); j++)
{
n.setWeight(j, n.getWeight(j) - n.N * Math.Sign(n.Delta));
}
n.PrevDelta = n.Delta;
}
n.PrevN = n.N;
}
}
}
For the first view, you calculate one train element error and you instantly teach it to the network. try to run over the full train set, without change the weights, and just summarize the Delta. After that, update the weights once, set the prev delta and start over.
Also, there is no update for neuron threshold.
I want to generate the random numbers using this loop. When i runs the apps at everytime, i want to generate the random numbers without duplicates.
Eg:
for(int i = 0; i < 5; i++)
{
// int d = random() % i;
NSLog(#"The Value %d",i);
NSLog(#"The random Number %d",i);
}
Actual Number Random Number
1 4
2 5
3 2
4 1
5 3
It's Random Permutation Generation problem. Read this: http://www.techuser.net/randpermgen.html
The main idea is (in pseudo code):
for (i=1 to n) ar[i] = i;
for (i=1 to n) swap(ar[i], ar[Random(i,n)]);
In your case:
int ar[5],i,d,tmp;
for(i = 0; i < 5; i++) ar[i] = i+1;
for(i = 0; i < 5; i++) {
d = i + (random()%(5-i));
tmp = ar[i];
ar[i] = ar[d];
ar[d] = tmp;
NSLog(#"%d",ar[i]);
}
Can be something like this,
int rand[5] = {0};
int max = 5;
for(int i = 0; i < max; i++){
int r = random() % max + 1;
while([self foundNumber:r inArray:rand limit:i){
r = random() % max + 1;
}
rand[i] = r;
}
- (BOOL) foundNumber:r inArray:rand limit:l {
for(int i = 0; i < l; i++){
if(rand[i] == r) return YES;
}
return NO;
}
I'm trying to to teach a neural net of 2 inputs, 4 hidden nodes (all in same layer) and 1 output node. The binary representation works fine, but I have problems with the Bipolar. I can't figure out why, but the total error will sometimes converge to the same number around 2.xx. My sigmoid is 2/(1+ exp(-x)) - 1. Perhaps I'm sigmoiding in the wrong place. For example to calculate the output error should I be comparing the sigmoided output with the expected value or with the sigmoided expected value?
I was following this website here: http://galaxy.agh.edu.pl/~vlsi/AI/backp_t_en/backprop.html , but they use different functions then I was instructed to use. Even when I did try to implement their functions I still ran into the same problem. Either way I get stuck about half the time at the same number (a different number for different implementations). Please tell me if I have made a mistake in my code somewhere or if this is normal (I don't see how it could be). Momentum is set to 0. Is this a common 0 momentum problem? The error functions we are supposed to be using are:
if ui is an output unit
Error(i) = (Ci - ui ) * f'(Si )
if ui is a hidden unit
Error(i) = Error(Output) * weight(i to output) * f'(Si)
public double sigmoid( double x ) {
double fBipolar, fBinary, temp;
temp = (1 + Math.exp(-x));
fBipolar = (2 / temp) - 1;
fBinary = 1 / temp;
if(bipolar){
return fBipolar;
}else{
return fBinary;
}
}
// Initialize the weights to random values.
private void initializeWeights(double neg, double pos) {
for(int i = 0; i < numInputs + 1; i++){
for(int j = 0; j < numHiddenNeurons; j++){
inputWeights[i][j] = Math.random() - pos;
if(inputWeights[i][j] < neg || inputWeights[i][j] > pos){
print("ERROR ");
print(inputWeights[i][j]);
}
}
}
for(int i = 0; i < numHiddenNeurons + 1; i++){
hiddenWeights[i] = Math.random() - pos;
if(hiddenWeights[i] < neg || hiddenWeights[i] > pos){
print("ERROR ");
print(hiddenWeights[i]);
}
}
}
// Computes output of the NN without training. I.e. a forward pass
public double outputFor ( double[] argInputVector ) {
for(int i = 0; i < numInputs; i++){
inputs[i] = argInputVector[i];
}
double weightedSum = 0;
for(int i = 0; i < numHiddenNeurons; i++){
weightedSum = 0;
for(int j = 0; j < numInputs + 1; j++){
weightedSum += inputWeights[j][i] * inputs[j];
}
hiddenActivation[i] = sigmoid(weightedSum);
}
weightedSum = 0;
for(int j = 0; j < numHiddenNeurons + 1; j++){
weightedSum += (hiddenActivation[j] * hiddenWeights[j]);
}
return sigmoid(weightedSum);
}
//Computes the derivative of f
public static double fPrime(double u){
double fBipolar, fBinary;
fBipolar = 0.5 * (1 - Math.pow(u,2));
fBinary = u * (1 - u);
if(bipolar){
return fBipolar;
}else{
return fBinary;
}
}
// This method is used to update the weights of the neural net.
public double train ( double [] argInputVector, double argTargetOutput ){
double output = outputFor(argInputVector);
double lastDelta;
double outputError = (argTargetOutput - output) * fPrime(output);
if(outputError != 0){
for(int i = 0; i < numHiddenNeurons + 1; i++){
hiddenError[i] = hiddenWeights[i] * outputError * fPrime(hiddenActivation[i]);
deltaHiddenWeights[i] = learningRate * outputError * hiddenActivation[i] + (momentum * lastDelta);
hiddenWeights[i] += deltaHiddenWeights[i];
}
for(int in = 0; in < numInputs + 1; in++){
for(int hid = 0; hid < numHiddenNeurons; hid++){
lastDelta = deltaInputWeights[in][hid];
deltaInputWeights[in][hid] = learningRate * hiddenError[hid] * inputs[in] + (momentum * lastDelta);
inputWeights[in][hid] += deltaInputWeights[in][hid];
}
}
}
return 0.5 * (argTargetOutput - output) * (argTargetOutput - output);
}
General coding comments:
initializeWeights(-1.0, 1.0);
may not actually get the initial values you were expecting.
initializeWeights should probably have:
inputWeights[i][j] = Math.random() * (pos - neg) + neg;
// ...
hiddenWeights[i] = (Math.random() * (pos - neg)) + neg;
instead of:
Math.random() - pos;
so that this works:
initializeWeights(0.0, 1.0);
and gives you initial values between 0.0 and 1.0 rather than between -1.0 and 0.0.
lastDelta is used before it is declared:
deltaHiddenWeights[i] = learningRate * outputError * hiddenActivation[i] + (momentum * lastDelta);
I'm not sure if the + 1 on numInputs + 1 and numHiddenNeurons + 1 are necessary.
Remember to watch out for rounding of ints: 5/2 = 2, not 2.5!
Use 5.0/2.0 instead. In general, add the .0 in your code when the output should be a double.
Most importantly, have you trained the NeuralNet long enough?
Try running it with numInputs = 2, numHiddenNeurons = 4, learningRate = 0.9, and train for 1,000 or 10,000 times.
Using numHiddenNeurons = 2 it sometimes get "stuck" when trying to solve the XOR problem.
See also XOR problem - simulation