neural network doesn't work correctly - c#

I'm using (ENCOG library) to create and train neural network. It must find real fault vector(it has 12 numbers - like vector = signature of fault) from modeling dictionary (it has 70 faults, identifying on 12 frequencies).
In NN i have input(12 neuron = len of one input fault vector), hidden (14 neuron = 2* output neurons) and output(7 neuron - to recognise by '0\1' 70 faults) layers.
This is it code (on C#) with NN:
public static double[][] XORInput =
{
new double[] { 1, 1, 1, 1,1,1,1,2,2,2,2,2 },
new double[] { 5, 5, 5, 5,5,5,5,6,6,7,7,7 },
new double[] { 6, 6,6,6,6,6,5,5,5,1,2,3 },
new double[] { 3, 3, 3, 3,3,3,3,3,2,2,1,1 } ,
new double[] { 1, 1, 2, 2,2,3,3,3,3,3,3,3 },
new double[] { 1, 4, 2, 7,2,5,6,7,8,8,8,8 },
new double[] { 2, 3, 3, 3,3,3,3,3,3,3,2,2 },
new double[] { 7,7, 7, 7,7,8,8,8,7,7,7,7 },
new double[] { 6, 7, 7, 8,8,8,8,8,8,7,7,6 },
new double[] { 3, 3, 3, 4 ,4,4,4,4,4,3,3,3 },
new double[] { 1, 1, 1, 1,1,2,2,2,2,2,2,2 },
new double[] { 5, 5, 5, 5,5,6,6,6,6,6,6,7 },
new double[] { 1,2,3,4,5,6,7,8,1,2,3,1 },
new double[] { 1, 1, 1, 1,1,1,1,1,1,2,4,1 },
new double[] { 1, 1, 1, 1,1,1,1,1,1,1,1,1 },
new double[] { 5, 5, 5,5,5,5,5,5,5,5,5,5 },
new double[] {7, 8, 8, 8,8,7,6,4,1,2,2,2 },
new double[] { 2, 3, 3, 3,3,4,4,4,4,3,3,3 },
new double[] { 8, 8,8, 8,8,5,6,7,8,8,8,8 },
new double[] { 5, 5, 5, 5,5,6,8,6,1,1,1,1 },
new double[] { 1, 1, 1, 1,1,1,1,4,4,6,3,5 },
new double[] { 2, 2, 2, 2,2,2,2,2,3,3,3,3 },
new double[] { 6, 6, 6, 6,7,7,7,7,7,8,8,8 },
new double[] { 1, 16, 2, 6,71,72,73,27,74,81,81,58 },
new double[] { 2, 36, 3, 67,87,7,17,27,37,2,1,1 },
new double[] { 3, 46, 4, 8,4,5,6,7,22,8,18,2 },
new double[] { 4, 56, 12, 9,1,2,4,12,4,44,1,8 },
new double[] { 5, 66, 5, 6,17,4,5,11,5,7,8,9 },
new double[] { 6, 86, 6, 6, 10,2,5,8,1,3,5,1 },
new double[] { 66, 16, 14, 11,1,1,1,2,1,4,1,6 },
new double[] { 67, 6,11 , 16,2,2,2,7,21,2,1,9 },
new double[] { 7, 6, 10, 62,12,3,4,54,1,1,3,3 },
new double[] { 8, 16,9, 6,17,7,1,2,7,5,1,4 },
new double[] { 9, 26,11, 6,73,6,2,3,4,5,5,2 },
new double[] { 61, 21, 85, 61,5,2,5,1,6,3,4,5 },
new double[] { 31, 1, 11, 1,1,1,1,2,2,2,2,2 },
new double[] { 15, 5, 15, 5,5,5,5,6,6,7,7,7 },
new double[] { 36, 6,16,6,6,6,5,5,5,1,2,3 },
new double[] { 53, 3, 13, 3,3,3,3,3,2,2,1,1 } ,
new double[] { 71, 1, 22, 2,2,3,3,3,3,3,3,3 },
new double[] { 81, 4, 21, 7,2,5,6,7,8,8,8,8 },
new double[] { 12, 3, 13, 3,3,3,3,3,3,3,2,2 },
new double[] { 97,7, 71, 7,7,8,8,8,7,7,7,7 },
new double[] { 5, 7, 17, 8,8,8,8,8,8,7,7,6 },
new double[] { 13, 3, 13, 4,4,4,4,4,4,3,3,3 },
new double[] { 11, 1, 11, 1,1,2,2,2,2,2,2,2 },
new double[] { 55, 5, 51, 5,5,6,6,6,6,6,6,7 },
new double[] { 16,2,19,4,5,6,7,8,1,2,3,1 },
new double[] { 17, 1, 11, 1,1,1,1,1,1,2,4,1 },
new double[] { 19, 1, 21, 1,1,1,1,1,1,1,1,1 },
new double[] { 25, 5, 25,5,5,5,5,5,5,5,5,5 },
new double[] {27, 8, 28, 8,8,7,6,4,1,2,2,2 },
new double[] { 22, 3, 23, 3,3,3,3,3,3,2,1,7 },
new double[] { 32, 3, 27, 3,3,4,4,4,4,3,3,3 },
new double[] { 18, 8,2, 8,8,5,6,7,8,8,8,8 },
new double[] { 31, 1, 4, 1,1,1,1,4,4,6,3,5 },
new double[] { 23, 2, 6, 2,2,2,2,2,3,3,3,3 },
new double[] { 36, 6, 16, 6,7,7,7,7,7,8,8,8 },
new double[] { 31, 16, 5, 6,71,72,73,27,74,81,81,58 },
new double[] { 12, 36, 14, 67,87,7,17,27,37,2,1,1 },
new double[] { 31, 46, 41, 8,4,5,6,7,22,8,18,2 },
new double[] { 14, 56, 1, 9,1,2,4,12,4,44,1,8 },
new double[] { 15, 66, 59, 6,17,4,5,11,5,7,8,9 },
new double[] { 16, 86, 16, 6, 10,2,5,8,1,3,5,1 },
new double[] { 16, 16, 10, 11,1,1,1,2,1,4,1,6 },
new double[] { 17, 6,114, 16,2,2,2,7,21,2,1,9 },
new double[] { 71, 6, 1, 62,12,3,4,54,1,1,3,3 },
new double[] { 18, 16,19, 6,17,7,1,2,7,5,1,4 },
new double[] { 19, 26,1, 6,73,6,2,3,4,5,5,2 },
new double[] { 6, 21, 5, 61,5,2,5,1,6,3,4,5 } //70
};
/// <summary>
/// Array of numbers, which equal to squares of two
/// </summary>
static int[] powOfTwo = {2, 4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536 };
private static void Main(string[] args)
{
double[][] XORIdeal = computeOutputVector(XORInput);
// normalizing input data
double[][] input = normalizeData(XORInput);
// create a neural network, without using a factory
var network = new BasicNetwork();
network.AddLayer(new BasicLayer(null, true, 12));
network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, 14));
network.AddLayer(new BasicLayer(new ActivationSigmoid(), false, 7));
network.Structure.FinalizeStructure();
network.Reset();
// create training data
IMLDataSet trainingSet = new BasicMLDataSet(input, XORIdeal);
//IMLDataSet trainingSet = new BasicMLDataSet(XORInput, XORIdeal);
// train the neural network
//IMLTrain train = new ResilientPropagation(network, trainingSet);
//var train = new Backpropagation ( network , trainingSet , 0.3 , 0.7 ) ;
var train = new Backpropagation(network, trainingSet, 0.2, 0.15); // speed and influence of backpropogation algorithm
int epoch = 1;
do
{
train.Iteration();
Console.WriteLine(#"Epoch #" + epoch + #" Error:" + train.Error);
epoch++;
} while (train.Error > 0.05 && epoch < 2000);
train.FinishTraining();
// test the neural network
Console.WriteLine(#"Neural Network Results:");
double[] data = new double[] { 1, 1, 1, 1,1,1,1,2,2,2,2,2 }; //{ 5.1, 5.4, 5.5, 5.5, 5.8, 5.6, 5.6, 6.5, 6.6, 7.1, 7.1, 7.1 }; // 0000001
double[] realSignature22 = new double[] { 6.21, 4.2, 6.6, 6.6, 6.6, 5.56, 6.5, 7, 7, 6.89, 6.8, 8 }; // 0010110
double[] realSignature34 = new double[] { 58, 24, 90, 55, 4.5, 1.82, 5.4, 1.1, 6.4, 3.1, 3.4, 5.3 }; // 0100010
IMLData example1 = new BasicMLData(normilizeRow(data));
IMLData output1 = network.Compute(example1);
Console.WriteLine("\nactual : 0 0 0 0 0 0 0 = #0 ");
findNumber(output1);
IMLData example = new BasicMLData(normilizeRow(realSignature34));
IMLData output = network.Compute(example);
Console.WriteLine("\nactual : 0 1 0 0 0 1 0 = #34 ");
findNumber(output);
IMLData example2 = new BasicMLData(normilizeRow(realSignature22));
IMLData output2 = network.Compute(example2);
Console.WriteLine("\nactual : 0 0 1 0 1 1 0 = #22 ");
findNumber(output2);
EncogFramework.Instance.Shutdown();
}
/// <summary>
/// Returns degree of two which cowers number of mistakes in the input vector
/// </summary>
/// <param name="XORInput"></param>
/// <returns></returns>
static int calcSizeOfOutputVector(double[][] XORInput)
{
int size = 0;
int len = XORInput.GetLength(0);
foreach (int number in powOfTwo)
{
size++;
if (len <= number) return size;
}
return -1;
}
static double[][] computeOutputVector(double[][] XORInput)
{
double[][] output;
int sizeOfOut = calcSizeOfOutputVector(XORInput);
int numOfFaults = XORInput.GetLength(0);
output = new double[numOfFaults][];
// convert decimal number into corresponding array from 0 and 1 (equal to decimal number)
for (int i = 0; i < numOfFaults; i++)
{
output[i] = new double[sizeOfOut];
convertDecToByteAndSaveInDoubleArray(output[i], i);
}
return output;
}
static double[] convertDecToByteAndSaveInDoubleArray(double[] outArray, int number ){
// convert number into binary representation
string binaryCode = Convert.ToString(number, 2);
int size = outArray.GetLength(0);
// Initially fill with zeros
for (int i = 0; i < size; i++) outArray[i] = 0;
//
for (int i = 0; i < binaryCode.Length; i++)
{
double d = Double.Parse(binaryCode.Substring(binaryCode.Length - i - 1, 1));
outArray[size - 1 - i] = d;
}
return outArray;
}
static void printOutputResults(IMLData output){
Console.WriteLine("\nFrom NN ");
for (int i = 0; i < output.Count; i++ )
Console.Write(" " + output[i] + " " );
}
static int[] findNumber(IMLData output)
{
int len = output.Count;
// Round to 0 and 1 numbers, which is received from NN
int[] outAr = new int[len];
for (int i = 0; i < output.Count; i++)
{
outAr[i] = (int)Math.Round(output[i]);
}
// Display output vectors
// Bug for number 1 and length 7 in the input vector looks like : 0[0] 0[1] 0[2] 0[3] 0[4] 0[5] 1[6] (in binary system) = 1 (in decimal system)
Console.WriteLine("\nFrom NN ");
for (int i = 0; i < len; i++)
Console.Write(" " + outAr[i] + " ");
// Convert binary vector into decimal
Console.WriteLine("\nFrom NN (converted number)" + convertBinArrayToDecNumber(outAr));
return outAr;
}
static int convertBinArrayToDecNumber(int[] binaryArray)
{
int n = 0;
int maxIndex = binaryArray.Length - 1;
for (int i = maxIndex; i >= 0; i--)
n += (int)Math.Pow(2, maxIndex - i) * binaryArray[i];
return n;
}
static double[][] normalizeData(double[][] data)
{
int numOfRows = data.Length;
int lenOfRow = data[0].GetLength(0);
double[][] result = new double[numOfRows][];
for (int i = 0; i < numOfRows; i++)
result[i] = normilizeRow(data[i]);
return result;
}
static double[] normilizeRow(double[] row)
{
int lenOfRow = row.GetLength(0);
double[] result = new double[lenOfRow];
for (int i = 0; i < lenOfRow; i++) result[i] = 0;
double N = 0;
foreach (double num in row) N += num * num;
if (N != 0) {
for (int j = 0; j < lenOfRow; j++)
{
result[j] = (row[j] / Math.Sqrt(N));
}
}
return result;
}
I try to edit params of training by backpropogation, but almost everytime i have high train.error level.
But the most problem in this code is results. Each run of code has different (and not correct!!!) results. For ex:
actual : 0 0 0 0 0 0 0 = #0
From NN
0 0 0 0 0 0 1
From NN (converted number)1
actual : 0 1 0 0 0 1 0 = #34
From NN
0 1 0 0 0 1 0
From NN (converted number)34
actual : 0 0 1 0 1 1 0 = #22
From NN
0 0 0 0 0 1 0
From NN (converted number)2
Or another:
Neural Network Results:
actual : 0 0 0 0 0 0 0 = #0
From NN
0 0 0 0 1 0 1
From NN (converted number)5
actual : 0 1 0 0 0 1 0 = #34
From NN
0 1 0 0 0 1 0
From NN (converted number)34
actual : 0 0 1 0 1 1 0 = #22
From NN
0 0 0 1 1 1 1
From NN (converted number)15
Can anyone tell me:
1) how can I train the network more efficiently
2) why rows like '{ 1, 1, 1, 1,1,1,1,2,2,2,2,2 }' (which are in train data) doesn't correctly recognized by NN ?
//-------------------------------------------------------------------
I Try to normilize data with Encog function. Code:
public static void readCSVFileToNN(){
int numOfCol = 12;
// Define the format of the data file.
// This area will change, depending on the columns and
// format of the file that you are trying to model.
IVersatileDataSource source = new CSVDataSource("c:\\test.txt", false,
CSVFormat.DecimalPoint);
var data = new VersatileMLDataSet(source);
for (int i = 0; i < numOfCol; i++ )
data.DefineSourceColumn("freq#" +i , i, ColumnType.Nominal);
// Define the column that we are trying to predict.
ColumnDefinition outputColumn = data.DefineSourceColumn("faultNumbers", 12,
ColumnType.Nominal);
// Analyze the data, determine the min/max/mean/sd of every column.
data.Analyze();
// Map the prediction column to the output of the model, and all
// other columns to the input.
data.DefineSingleOutputOthersInput(outputColumn);
// Create feedforward neural network as the model type. MLMethodFactory.TYPE_FEEDFORWARD.
// You could also other model types, such as:
// MLMethodFactory.SVM: Support Vector Machine (SVM)
// MLMethodFactory.TYPE_RBFNETWORK: RBF Neural Network
// MLMethodFactor.TYPE_NEAT: NEAT Neural Network
// MLMethodFactor.TYPE_PNN: Probabilistic Neural Network
var model = new EncogModel(data);
model.SelectMethod(data, MLMethodFactory.TypeFeedforward);
// Send any output to the console.
model.Report = new ConsoleStatusReportable();
// Now normalize the data. Encog will automatically determine the correct normalization
// type based on the model you chose in the last step.
data.Normalize();
// Hold back some data for a final validation.
// Shuffle the data into a random ordering.
// Use a seed of 1001 so that we always use the same holdback and will get more consistent results.
model.HoldBackValidation(0.3, true, 1001);
// Choose whatever is the default training type for this model.
model.SelectTrainingType(data);
// Use a 5-fold cross-validated train. Return the best method found.
var bestMethod = (IMLRegression)model.Crossvalidate(2, true);
// Display the training and validation errors.
Console.WriteLine(#"Training error: " + model.CalculateError(bestMethod, model.TrainingDataset));
Console.WriteLine(#"Validation error: " + model.CalculateError(bestMethod, model.ValidationDataset));
// Display our normalization parameters.
NormalizationHelper helper = data.NormHelper;
Console.WriteLine(helper.ToString());
// Display the final model.
Console.WriteLine(#"Final model: " + bestMethod);
source.Close();
// test work of model on the example:
IMLData input = helper.AllocateInputVector();
var line = new String[numOfCol];
var result = new StringBuilder();
// в качестве примера возьмем сигнатуру [5,5,..,5] под номером 15
for (int i = 0; i < numOfCol; i++)
line[i] = 5.ToString();
String correct = 15.ToString();
// нормализуем входной вектор
helper.NormalizeInputVector(line, ((BasicMLData) input).Data, false);
// производим поиск по НС
IMLData output = bestMethod.Compute(input);
// выводим результат
String faultChosen = helper.DenormalizeOutputVectorToString(output)[0];
result.Append(line);
result.Append(" -> predicted: ");
result.Append(faultChosen);
result.Append("(correct: ");
result.Append(correct);
result.Append(")");
Console.WriteLine(result.ToString());
}
But results are still bad. I do this function ~10 times and no one of results were not correct

Your problem is that each row normalization is independent from other rows. For example the first row will be division of each value at 27, second row will be division of each number at 394. Another source of problems can be You need to normalize not each row independently, but all rows should be normalized according to some rule. Then you should apply the same normalization rule for your input. I propose you to look at function normalize in Encog.

Related

Remove row from multidimensional array in jagged array

I have a jagged array with a multidimensional array and want to remove an array inside the multidimensional array. My code is:
int[][,] arr = new int[4][,];
arr[0] = new int[,] {
{ 1, 2, 3 }, // <- I want to remove this row
{ 4, 5, 6 },
{ 5, 6, 7 },
{ 8, 9, 10 } };
arr[1] = new int[,] {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 } };
arr[2] = new int[,] {
{ 1, 2, 3, 4, 5 },
{ 5, 6, 7, 8, 9 },
{ 10, 11, 12, 13, 14 },
{ 15, 16, 17, 18, 19 } };
arr[3] = new int[,] {
{ 1, 2, 3, 4, 5, 6},
{ 5, 6, 7, 8, 9, 10},
{ 11, 12, 13, 14, 15, 16 },
{ 17, 18, 19, 20, 21, 22 } };
int[,] removeArray = { { 1, 2, 3 } };
I tried to remove {1, 2, 3} from arr[0] by using Linq:
arr = arr
.Where((val, i) => i != 0)
.ToArray();
but this removes the whole arr[0] row. Does anyone know how I can get to remove {1,2,3} using Linq?
Unlike jagged arrays, multidimensional ones doesn't consist of arrays:
int[][] jagged = new int[][] {
new[] { 1, 2, 3 }, // <- this is an array
new[] { 4, 5 }, // <- this is another array
};
int[,] array2D = new int[,] {
{ 1, 2, 3 }, // <- not an array
{ 4, 5, 6 }, // <- not an array
};
So if you want to "remove" row from 2d array, you have to recreate it; something like this:
private static T[,] RemoveRows<T>(T[,] source, T[] row) {
if (row.Length != source.GetLength(1))
return source;
var keepRows = new List<int>();
for (int r = 0; r < source.GetLength(0); ++r)
for (int c = 0; c < row.Length; ++c)
if (!object.Equals(source[r, c], row[c])) {
keepRows.Add(r);
break;
}
if (keepRows.Count == source.Length)
return source;
T[,] result = new T[keepRows.Count, source.GetLength(1)];
for (int r = 0; r < keepRows.Count; ++r)
for (int c = 0; c < result.GetLength(1); ++c)
result[r, c] = source[keepRows[r], c];
return result;
}
and then
// we remove row; let it be 1d array, not 2d one
int[] removeArray = { 1, 2, 3 };
arr = arr
.Select(array => RemoveRows(array, removeArray))
.ToArray();
please, fiddle yourself

How to remove all occurrences in array and shift leftovers left?

We have two arrays of integers a1 and a2 as parameters and we should remove all occurrences of a2 values from a1. Element is "removed" by shifting all subsequent elements one index to the left to cover it up, placing a 0 into the last index. The original relative ordering of a1 elements should be retained.
i'm having problem with shifting it's element.
Example:
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1};
int[] a2 = { 42, 2222, 9};
the final result should be like this:
{3, 0, 17, 8, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
so here is my code:
for(int i = 0; i < a1.Length; i++)
{
foreach(var element in a2)
{
if (element == a1[i])
{
for(int j = i; j < a1.Length-1; j++)
{
a1[j] = a1[j+1];
}
a1[a1.Length - 1] = 0;
}
}
}
You need to use i--; when your item matches. Because you're shifting your entire array. Also you need to use break; your inner foreach loop after i--;.
Explanation
1) With your arrays, for i = 0 and first element in foreach(var element in a2) both will be 42. So first your array will be shifted one index. Now if you are not using i-- then it will check for i=1 which should be 3 but as we already shifted our array so 3 value is at index 0. So this value will never getting checked for match.
2) And use of break, as your match already found and array is shifted there is no requirement for check further.
Your code should be like below.
for(int i = 0; i < a1.Length; i++)
{
foreach(var element in a2)
{
if (element == a1[i])
{
for(int j = i; j < a1.Length-1; j++)
{
a1[j] = a1[j+1];
}
a1[a1.Length - 1] = 0;
i--;
break;
}
}
}
If You can use Linq then try as below, First get filters elements first. Then add 0 for rest indexes.
int[] a1= { 42,3,9,42,42,0,42,9,42,42,17,8,2222,4,9,0,1};
int[] a2= { 42,2222,9};
var a3 = a1.Where(x => !a2.Contains(x)).ToArray();
for (int i = 0; i < a1.Length; i++) {
if (i < a3.Length)
a1[i] = a3[i];
else
a1[i] = 0;
}
You can do this without creating any extra arrays like so:
static void Main()
{
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1 };
int[] a2 = { 42, 2222, 9 };
int j = 0;
for (int i = 0; i < a1.Length; ++i)
if (Array.IndexOf(a2, a1[i]) < 0) // Don't remove this value.
a1[j++] = a1[i];
Array.Clear(a1, j, a1.Length-j);
Console.WriteLine(string.Join(", ", a1));
}
We make two passes: Firstly to remove all the elements of a1 that are contained in a2 (via the explicit loop) and then to overwrite all the "removed" values with 0 (via Array.Clear().
Just a different approach by first filtering and then adding the needed zeros:
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1 };
int[] a2 = { 42, 2222, 9 };
var zeros = Enumerable.Repeat(0, int.MaxValue);
var valids = a1.Where(v => !a2.Contains(v));
var result = valids.Concat(zeros).Take(a1.Length);
Console.WriteLine(String.Join(", ", result));
Yet another approach, using Array.Copyfor shifting:
public static void Main()
{
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1 };
int[] a2 = { 42, 2222, 9 };
for(int i = 0; i < a1.Length; i++)
{
if(a2.Contains(a1[i]))
{
//notice i-- here because iterating array shifted to left
ShiftToLeft(a1, i--+1);
}
}
Console.WriteLine(string.Join(",", a1));
}
private static void ShiftToLeft(int[] array, int fromIndex)
{
Array.Copy(array, fromIndex, array, fromIndex-1, array.Length - fromIndex);
array[array.Length-1] = 0;
}
Try This:
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1 };
int[] a2 = { 42, 2222, 9 };
var result = a1.Where(x => !a2.Contains(x)).Concat(new int[a1.Length]).Take(a1.Length);
Console.WriteLine(String.Join(", ", result));

Program Throw Out of Bounds Exception Regardless of Array Size and Iterates Erratically

I'm writing a method that sums two one-dimensional arrays and returns the result in a single array. I then have a test main which accepts or rejects the results but I'm having an issue with my try-catch blocks and the iteration of the loop. I have been unsuccessful in pinpointing the source of these errors. The try catch block is simple:
try {
For (loop that compares arrays named op1 & op2 based on the length of op1) {
}
} catch (System.IndexOutOfRangeException) { Console.WriteLine("*****OutOfBounds Exception"); } // Catch out of range exception
I have tried using an arrayList in place of a fixed array to solve these issue, as well as basing the loop iteration on a fixed value and the length of op2. Any hints or idea on how to fix this would be greatly appreciated.
/// <summary>
/// Add two binary numbers stored in int arrays: op1 + op2
/// </summary>
/// <param name="op1">Operand #1</param>
/// <param name="op2">Operand #2</param>
/// <returns>the sum of op1 and op2</returns>
public static int[] AddBinary(int[] op1, int[] op2) {
//ArrayList tempResult = new ArrayList(); // Temporary ArrayList to combine the two arrays.
int[] result = new int[4];
try {
for (int i = 0; i <= op1.Length; i++) // Loop through int[] op1 (starts at 0)
{
Console.WriteLine("op1: " + op1[i]);
Console.WriteLine("op2: " + op2[i]);
if (op1[i] < 0 || op2[i] < 0) // Terminate if int[] op1 or int[] opt2 are less than 0.
{
Console.WriteLine("Binary digits cannot be less than 0.");
//break;
}
if (op1[i] > 1 || op2[i] > 1) // Terminate if int[] op1 or int[] opt2 are greater than 1.
{
Console.WriteLine("Binary digits cannot be greater than 1.");
//break;
}
/*
* Handles the carry by assigning the value of 1 to
* opt at I and 0 to op2 in the index value after op1[i]
* Should cause overflow
*/
if (op1[i] == 1 && op2[i] == 1)
{
result[i] = 1;
result[i++] = 0;
//tempResult.Add(op1[i] == 1);
//tempResult.Add(op1[i++] == 0);
}
if (op1[i] == 0 && op2[i] == 0)
{
result[i] = 0;
}
// Adds the current value of op1 and op2 into the list
/*
* assigns the value of 1 to result if op1 is equal to one or
* zero and the opposite is true of op2.
*/
else
{
//tempResult.Add(op1[i]);
//tempResult.Add(op2[j]);
result[i] = 1;
}
}
} catch (System.IndexOutOfRangeException) { Console.WriteLine("*****OutOfBounds Exception"); } // Catch out of range exception
Console.WriteLine("Result: ");
for (int j = 0; j <= 4; j++ )
{
Console.WriteLine(result[j]);
}
/*
* Convert Array list to a traditional array for return
int[] result = (int[])tempResult.ToArray(typeof(int));
*/
return result;
}
The following are the parameters passed to the method, though not given the main tests the output of the method.
new TestCase(new int[] { 1, 1, 1, 1, 1 }, new int[] { 1, 1, 1, 1, 1 }, new int[] { 0, 0, 0, 0, 0 }, true), //01 // Should cause overflow and throw an exception
new TestCase(new int[] { 0 }, new int[] { 1 }, new int[] { 1 }, false),//02
new TestCase(new int[] { 0, 1 }, new int[] { 0, 1 }, new int[] { 1, 0 }, false),//03
new TestCase(new int[] { 0, 0 }, new int[] { 0, 0 }, new int[] { 0, 0 }, false),//04
new TestCase(new int[] { 0, 0, 0, 0, 0 }, new int[] { 1, 1, 1, 1, 1 }, new int[] { 1, 1, 1, 1, 1 }, false),//05
new TestCase(new int[] { 1, 1, 1, 1, 1 }, new int[] { 0, 0, 0, 0, 0 }, new int[] { 1, 1, 1, 1, 1 }, false),//06
new TestCase(new int[] { 2 }, new int[] { 1 }, new int[] { 1 }, true), //07 // should detect an invalid char and throw an exception
new TestCase(new int[] { 2, 2, 2, 2, 2 }, new int[] { 1, 1, 1, 1, 1 }, new int[] { 1, 1, 1, 1, 1 }, true), //08 // should detect an invalid char and throw an exception
new TestCase(new int[] { 1, 0, 0, 0, 0 }, new int[] { 0, 1, 1, 1, 1 }, new int[] { 1, 1, 1, 1, 1 }, false),//09
new TestCase(new int[] { 0, 1, 1, 1, 1 }, new int[] { 1, 0, 0, 0, 0 }, new int[] { 1, 1, 1, 1, 1 }, false),//10

Implementing FCFS CPU Scheduler (Wait time function)

Process Data:
process goes {CPU burst, I/O time, CPU burst, I/O time, CPU burst, I/O time,…….., last CPU burst}
I split the data into two arrays. cpu burst and io_burst
P1 {4,24,5,73,3,31,5,27,4,33,6,43,4,64,5,19,2}
P2 {18,31,19,35,11,42,18,43,19,47,18,43,17,51,19,32,10}
P3 {6,18,4,21,7,19,4,16,5,29,7,21,8,22,6,24,5}
P4 {17,42,19,55,20,54,17,52,15,67,12,72,15,66,14}
P5 {5,81,4,82,5,71,3,61,5,62,4,51,3,77,4,61,3,42,5}
P6 {10,35,12,41,14,33,11,32,15,41,13,29,11}
P7 {21,51,23,53,24,61,22,31,21,43,20}
P8 {11,52,14,42,15,31,17,21,16,43,12,31,13,32,15}
I'm mostly having a hard time calculating the wait time for this. I made a class process which is here
class Process
{
//public Process(string name, int arrival, int cpuburst,int ioburst, int priority)
//{
// this.name = name;
// this.arrival = arrival;
// this.cpuburst = cpuburst;
// this.ioburst = ioburst;
// this.priority = priority;
//}
public Process()
{
}
public string name;
public int arrival;
public int[] cpuburst;
public int []ioburst;
public int priority;
public int totburst;
public int wait;
public int end;
public int start;
public int contextswitch;
public int response;
public int turnAround;
//public int contextswitch;
public double cpu_utilization;
public double avwaitingtime;
public double avturnaroundtime;
public double avresponse;
}
}
heres how I'm initializing, I made cpuburst and io_burst the same size by adding some zeroes to the end of the array
void initialize_process()
{
List<Process> processes = new List<Process>();
Process p1 = new Process();
p1.arrival = 0;
p1.end = 0;
p1.name = "P1";
p1.cpuburst = new int[] { 4, 5, 3, 5, 4, 6, 4, 5, 2 ,0};
p1.ioburst = new int[] { 24, 73, 31, 27, 33, 43, 64, 19, 0, 0 };
p1.totburst = 38;
processes.Add(p1);
Process p2 = new Process();
p2.arrival = 0;
p2.name = "P2";
p2.end = 0;
p2.cpuburst = new int[] { 18, 19, 11, 18, 19, 18, 17, 19, 10, 0 };
p2.ioburst = new int[] { 31, 35, 42, 43, 47, 43, 51, 32, 0, 0 };
p2.totburst = 149;
processes.Add(p2);
Process p3 = new Process();
p3.arrival = 0;
p3.end = 0;
p3.name = "P3";
p3.cpuburst = new int[]{ 6, 4, 7, 4, 5, 7, 8, 6, 5 ,0};
p3.ioburst = new int[] { 18, 21, 19, 16, 29, 21, 22, 24, 0, 0 };
p3.totburst = 52;
processes.Add(p3);
Process p4 = new Process();
p4.arrival = 0;
p4.end = 0;
p4.name = "P4";
p4.cpuburst = new int[] { 17, 19, 20, 17, 15, 12, 15, 14,0,0 };
p4.ioburst = new int[] { 42, 55, 54, 52, 67, 72, 66, 0, 0, 0 };
p4.totburst = 129;
processes.Add(p4);
Process p5 = new Process();
p5.arrival = 0;
p5.end = 0;
p5.name = "P5";
p5.cpuburst = new int[]{ 5, 4, 5, 3, 5, 4, 3, 4, 3, 5 };
p5.ioburst = new int[] { 81, 82, 71, 61, 62, 51, 77, 61, 42, 0 };
p5.totburst = 41;
processes.Add(p5);
Process p6 = new Process();
p6.arrival = 0;
p6.end = 0;
p6.name = "P6";
p6.cpuburst = new int[] { 10, 12, 14, 11, 15, 13, 11,0,0,0 };
p6.ioburst = new int[] { 35, 41, 33, 32, 41, 29, 0, 0, 0, 0 };
p6.totburst = 86;
processes.Add(p6);
Process p7 = new Process();
p7.arrival = 0;
p7.end = 0;
p7.name = "P7";
p7.cpuburst = new int[]{ 21, 23, 24, 22, 21, 20,0,0,0,0 };
p7.ioburst = new int[] { 51, 53, 61, 31, 43, 0, 0, 0, 0, 0 };
p7.totburst = 131;
processes.Add(p7);
Process p8 = new Process();
p8.arrival = 0;
p8.end = 0;
p8.name = "P8";
p8.cpuburst = new int[] { 11, 14, 15, 17, 16, 12, 13, 15, 0, 0 };
p8.ioburst = new int[] { 52, 42, 31, 21, 43, 31, 32, 0, 0, 0 };
p8.totburst = 113;
processes.Add(p8);
FCFS(processes);
SJF(processes);
}
In my FCFS function I call other functions to perform the calculations
void FCFS(List<Process> p)
{
output.Items.Add("After FCFS");
output.Items.Add("-------------------------------------------------------");
wait(p);
turnaroundtime(p);
responsetime(p);
completeoutputlist(p);
}
my attempts at wait time have failed and I really don't know how to best approach this. I want to get these values calculated here so then I can call them in my other functions.
I'm mostly stuck on how to take I/o time into account when calculating the clock
the processes are doing I/O at the same time one other process is running. So, I/O should be decremented as timer is incremented for every process doing I/O.
multiple processes can be doing i/o at the same time. So you would need a list of processes that are doing i/o.
really just need some guidance in this part.
void wait(List<Process> p)
{
/* Goal keep track of context switches. - p.contextswitch
* Keep track of the first time it enters to get response time - p.start
* Keep track of when the process ends - so later we can calc turnaround time p.end
* then tweak some functions so it works again
*
*/
}
Before I was doing something like this
void wait(List<Process> p)
{
/* Goal keep track of context switches. - p.contextswitch
* Keep track of the first time it enters to get response time - p.start
* Keep track of when the process ends - so later we can calc turnaround time p.end
* then tweak some functions so it works again
*
*/
int k = 0;
int i = 0;
int clock = 0;
int contextswitch = 0;
int cpuready = 0;
int ioready = 0;
double avwaitingtime = 0;
for (k = 0; k < 10; k++)
{
for (i = 0; i < p.Count; i++)
{
//cpuready = p[i].cpuburst[k];
//ioready = p[i].ioburst[k];
clock += p[i].cpuburst[k];
//sets arrival time P1
if (i == 0 && k == 0)
{
p[0].arrival = 0;
}
//sets arrival time P2
if (i == 1 && k == 0)
{
p[1].arrival = clock;
}
//sets arrival time P3
if (i == 2 && k == 0)
{
p[2].arrival = clock;
}
//sets arrival time P4
if (i == 3 && k == 0)
{
p[3].arrival = clock;
}
//sets arrival time P5
if (i == 4 && k == 0)
{
p[4].arrival = clock;
}
//sets arrival time P6
if (i == 5 && k == 0)
{
p[5].arrival = clock;
}
//sets arrival time P7
if (i == 6 && k == 0)
{
p[6].arrival = clock;
}
//sets arrival time P8
if (i == 7 && k == 0)
{
p[7].arrival = clock;
}
//ADDS TO THE CONTEXT SWITCH CONTER
contextswitch += 1;
//Checks the first row and the last column
if (i == 0 && k == 8)
{
p[0].end = clock;
}
//Checks the 2nd row and the last column
if (i == 1 && k == 8)
{
p[1].end = clock;
}
//Checks the 3rd row and the last column
if (i == 2 && k == 8)
{
p[2].end = clock;
}
//Checks the 4th row and the last column
if (i == 3 && k == 7)
{
p[3].end = clock;
}
//Checks the 5th row and the last column
if (i == 4 && k == 9)
{
p[4].end = clock;
}
//Checks the 6th row and the last column
if (i == 5 && k == 6)
{
p[5].end = clock;
}
//Checks the 7th row and the last column
if (i == 6 && k == 5)
{
p[6].end = clock;
}
//Checks the 8th row and the last column
if (i == 7 && k == 7)
{
p[7].end = clock;
}
}
}
output.Items.Add(clock);
double waitsum = 0;
for (i = 0; i < 8; i++)
{
//CALCS THE WAIT TIME
p[i].wait = (p[i].end- p[i].totburst);
// output.Items.Add(p[i].wait);
//CALCS THE WAITSUM
waitsum += p[i].wait;
}
//calcs avg wait time
avwaitingtime = (waitsum / 8.0);
//output.Items.Add(avg);
output.Items.Add(contextswitch);
cpu_utilization(p, contextswitch,clock);
for (i = 0; i < 8; i++)
{
p[i].avwaitingtime = avwaitingtime;
}
}
any sort of ideas on how to approach this would be tons of help, thanks!

Get the value of a specific array number in relation to a given value

I am trying to determine what the neighbour bets would be for a given number on a roulette wheel.
At the moment I pass a pocket number to a function and below is my code. "pocket_number()[0]" is the value of the number I want to determine the neighbours of.
int[] neightbourbets = neighbourbets(pocket_number()[0]);
neighbourbets() is as follows (this outputs an array of element numbers so elsewhere in my program I can extract them from the same array structure). At the moment I have a crude way of determining the the neighbour bets and getting the function to state which numbers are 6 numbers either side of it.
Is there a better way to do this? I've found one of the problems (that I've overcome with the below) is if I want to know the neighbours for "0" for example which means the code needs to get the numbers from the end of the array.
public int[] neighbourbets(int x)
{
int[] pocket_array = new[] {0, 32, 15, 19, 4, 21, 2, 25, 17, 34, 6, 27, 13, 36, 11, 30, 8, 23, 10, 5, 24, 16, 33, 1, 20, 14, 31, 9, 22, 18, 29, 7, 28, 12, 35, 3, 26};
int predictednum = Array.IndexOf(pocket_array,x); //element number of pocket_array for chosen number
int[] neighbourbets = new[] {0,0,0,0,0,0,0,0,0,0,0,0,0};
neighbourbets[0] = predictednum;
neighbourbets[1] = predictednum+1;
neighbourbets[2] = predictednum+2;
neighbourbets[3] = predictednum+3;
neighbourbets[4] = predictednum+4;
neighbourbets[5] = predictednum+5;
neighbourbets[6] = predictednum+6;
neighbourbets[7] = predictednum-1;
neighbourbets[8] = predictednum-2;
neighbourbets[9] = predictednum-3;
neighbourbets[10] = predictednum-4;
neighbourbets[11] = predictednum-5;
neighbourbets[12] = predictednum-6;
for (int i = 0; i < neighbourbets.Length; i++)
{
//clockwise neighours
if (neighbourbets[i] == -1) {
neighbourbets[i] = 36;
}
if (neighbourbets[i] == -2) {
neighbourbets[i] = 35;
}
if (neighbourbets[i] == -3) {
neighbourbets[i] = 34;
}
if (neighbourbets[i] == -4) {
neighbourbets[i] = 33;
}
if (neighbourbets[i] == -5) {
neighbourbets[i] = 32;
}
if (neighbourbets[i] == -6) {
neighbourbets[i] = 31;
}
//anticlockwise neighbours
if (neighbourbets[i] == 37) {
neighbourbets[i] = 0;
}
if (neighbourbets[i] == 38) {
neighbourbets[i] = 1;
}
if (neighbourbets[i] == 39) {
neighbourbets[i] = 2;
}
if (neighbourbets[i] == 40) {
neighbourbets[i] = 3;
}
if (neighbourbets[i] == 41) {
neighbourbets[i] = 4;
}
if (neighbourbets[i] == 42) {
neighbourbets[i] = 5;
}
}
return neighbourbets;
}
Any helps or guidence is appreciated! :)
Write a small helper function to wrap around the index:
private int GetPocketIndex( int start, int offset, int count )
{
int pos = ( start + offset ) % count;
if( pos >= 0 )
return pos;
else
return count + pos; // pos is negative so we use +
}
The modulus there will help it wrap around when it goes above the maximum, and the if will do it for the minimum. This could probably be done easier though, but it eludes me at the moment.
Then, if you need that specific order, perhaps something like this:
int[] offsets = new int[] { 0,
1, 2, 3, 4, 5, 6,
-1, -2, -3, -4, -5, -6 };
int[] neighbourbets = new int[offsets.Length];
for( int i = 0; i < offsets.Length; i++ )
neighbourbets[i] = GetPocketIndex( predictednum, offsets[i], pocket_array.Length );
Or, if any order will do:
int count = 6;
int[] neighbourbets = new int[count * 2 + 1];
for( int i = 0; i < neighbourbets.Length; i++ )
neightbourbets[i] = GetPocketIndex( predictednum, i - count, pocket_array.Length );
The following would give you the result with the x in the middle of the result array and the neighbours to the left and right of it:
public static int[] neighbourbets2(int x, int neighborCount)
{
int[] pocket_array = new[] { 0, 32, 15, 19, 4, 21, 2, 25, 17, 34, 6, 27, 13, 36, 11, 30, 8, 23, 10, 5, 24, 16, 33, 1, 20, 14, 31, 9, 22, 18, 29, 7, 28, 12, 35, 3, 26 };
int predictednum = Array.IndexOf(pocket_array, x);
// Initialize the result array. Its size is double the neighbour count + 1 for x
int[] result = new int[neighborCount * 2 + 1];
// Calc the start index. We begin at the most left item.
int startAt = predictednum - neighborCount;
// i - position in the result array
// j - position in the pocket_array
for (int i = 0, j = startAt; i < result.Length; i++, j++)
{
// Adjust j if it's less then 0 to wrap around the array.
result[i] = pocket_array[j < 0 ? j + pocket_array.Length : j];
// If we are at the end then start from the beginning.
if (j == pocket_array.Length)
{
j = 0;
}
}
return result;
}

Categories