I need to solve the TSP problem with the branch and bound algorithm. Here's the code. The problem is, the code works only in small instances (i.e. three cities), but also it isn't working every time.
I've been looking for some mistakes but I couldn't find any.
The costs matrix is the macierz in my code and number of cities is stored in variable ileMiast.
I think the rest is clear.
Don't bother to the sort function or the FinalMatrix array. It's just to present the final order.
public double branchibound(int cities)
{
double totalCost = 0;
FinalMatrix = new ArrayList(ileMiast);
/*
* The ReducedCostMatrix calculates the reduced
* cost matrix
* */
totalCost = this.ReducedCostMatrix(cities);
/*
* Now we would work on the reduced cost
* Matrix to check which nodes to be inluded
* yet or not.
* */
int count = 0;
for (int i = 0; i < cities; i++)
for (int j = 0; j < cities; j++)
{
double[][] tempReduceRow = new double[cities][];
for (int l = 0; l < cities; l++)
tempReduceRow[l] = new double[cities];
for (int l = 0; l < cities; l++)
for (int m = 0; m < cities; m++)
tempReduceRow[l][m] = ReducedMatrix[l][m];
double[][] tempReduceCol = new double[cities][];
for (int l = 0; l < cities; l++)
tempReduceCol[l] = new double[cities];
for (int l = 0; l < cities; l++)
for (int m = 0; m < cities; m++)
tempReduceCol[l][m] = ReducedMatrix[l][m];
/*
* We only include those edges with value 0.
* Now, we will have only those with minimum left
* child and maximum right child.
* */
if (ReducedMatrix[i][j] == 0)
{
OmitLeft(i, j, ref tempReduceRow);
double LBound = totalCost + ReducedCostMatrix(cities, ref tempReduceRow);
OmitRight(i, j, ref tempReduceCol);
double RBound = totalCost + ReducedCostMatrix(cities, ref tempReduceCol);
FinalMatrix.Add(new double[] { LBound, RBound, count });
}
}
//sort();
return totalCost;
}
private void sort()
{
double[] values = new double[3];
double[] a = new double[3];
values = (double[])this.FinalMatrix[0];
int i = 0;
int prevIndex = 0;
for (i = 0; i < this.FinalMatrix.Count; i++)
for (int j = 0; j < this.FinalMatrix.Count; j++)
{
a = (double[])this.FinalMatrix[j];
if (a[1] > values[1] || a[0] < values[0])
{
FinalMatrix[prevIndex] = FinalMatrix[j];
FinalMatrix[j] = values;
values = a;
prevIndex = j;
}
}
}
public String getString()
{
String str = new String('A', 20);
str = "";
foreach (double[] a in this.FinalMatrix)
str += (char)(a[2]);
return str;
}
private void OmitLeft(int row, int col, ref double[][] temp)
{
for (int j = 0; j < temp.Length; j++)
temp[row][j] = -1;
for (int j = 0; j < temp.Length; j++)
temp[j][col] = -1;
}
private void OmitRight(int row, int col, ref double[][] temp)
{
temp[row][col] = -1;
}
private double ReducedCostMatrix(int cities)
{
double minBound = 0;
ReducedMatrix = new double[cities][];
for (int i = 0; i < cities; i++)
ReducedMatrix[i] = new double[cities];
/*
* Here we make a new Reduced Matrix
* by copying the original matrix
* into the new one.
* */
for (int i = 0; i < cities; i++)
for (int j = 0; j < cities; j++)
ReducedMatrix[i][j] = macierz[i][j];
minBound = ReducedRows(cities);
minBound += ReducedCols(cities);
return minBound;
}
private double ReducedCostMatrix(int cities, ref double[][] temp)
{
double minBound = 0;
minBound = ReducedRows(cities, ref temp);
minBound += ReducedCols(cities, ref temp);
return minBound;
}
private double ReducedRows(int cities)
{
double min = 65535;
bool flag = false;
double minBound = 0;
for (int i = 0; i < cities; i++)
{
min = 65535;
for (int j = 0; j < cities; j++)
if (this.ReducedMatrix[i][j] < min && this.ReducedMatrix[i][j] != -1)
{
min = this.ReducedMatrix[i][j];
flag = true;
}
if (flag)
{
this.SubtractRow(i, min);
minBound += min;
}
}
return minBound;
}
private double ReducedRows(int cities, ref double[][] temp)
{
double min = 65535;
double minBound = 0;
for (int i = 0; i < cities; i++)
{
min = 65535;
bool flag = true;
for (int j = 0; j < cities; j++)
if (temp[i][j] < min && temp[i][j] != -1)
{
min = temp[i][j];
flag = false;
}
if (!flag)
{
this.SubtractRow(i, min, ref temp);
minBound += min;
}
}
return minBound;
}
private double ReducedCols(int cities)
{
double min = 65535;
double minBound = 0;
for (int j = 0; j < cities; j++)
{
for (int i = 0; i < cities; i++)
if (this.ReducedMatrix[i][j] < min && this.ReducedMatrix[i][j] != -1)
min = ReducedMatrix[i][j];
this.SubtractCol(j, min);
minBound += min;
}
return minBound;
}
private double ReducedCols(int cities, ref double[][] temp)
{
double min = 65535;
double minBound = 0;
for (int j = 0; j < cities; j++)
{
for (int i = 0; i < cities; i++)
if (temp[i][j] < min && temp[i][j] != -1)
min = temp[i][j];
SubtractCol(j, min, ref temp);
minBound += min;
}
return minBound;
}
private void SubtractRow(int row, double sub)
{
for (int j = 0; j < this.ReducedMatrix[0].Length; j++)
if (this.ReducedMatrix[row][j] == -1)
continue;
else
this.ReducedMatrix[row][j] -= sub;
}
private void SubtractRow(int row, double sub, ref double[][] temp)
{
for (int j = 0; j < temp[0].Length; j++)
if (temp[row][j] == -1)
continue;
else
temp[row][j] -= sub;
}
private void SubtractCol(int col, double sub)
{
for (int j = 0; j < this.ReducedMatrix[0].Length; j++)
if (this.ReducedMatrix[j][col] == -1)
continue;
else
this.ReducedMatrix[j][col] -= sub;
}
private void SubtractCol(int col, double sub, ref double[][] temp)
{
for (int j = 0; j < temp.Length; j++)
if (temp[j][col] == -1)
continue;
else
temp[j][col] -= sub;
}
Thanks in advance
Related
I have a neural network in visual studio. for the loss function I am using a basic cost function (pred-target)**2 and after I finish an epoch I optimize the parameter functions afterwards, but the algorithm doesn't work.
No matter what is my network configuration, the predictions are not write (it is the same output for all the inputs) and the loss function is not optimized. It stays the same through all the epochs.
void calc_lyr(int x, int y, int idx, float target) // thus function calculates the neuron value based on the previous layer
{
if (x == -1 || y == 0) // if its the first layer, get the data from input nodes
{
for (int i = 0; i < neurons[y]; i++)
{
float sum = 0;
for (int j = 0; j < inputTypes.Count; j++)
{
sum += weights[x+1][j][i] * training_test[idx][j];
}
sum = relu(sum);
vals[y+1][i] = sum;
}
}
else
{
for(int i = 0; i < neurons[y]; i++)
{
float sum = 0;
for(int j = 0; j < neurons[x]; j++)
{
sum += weights[x+1][j][i] * vals[x+1][j] + biases[y][i];
}
sum = relu(sum);
vals[y+1][i] = sum;
}
}
}
void train()
{
log("Proces de antrenare inceput ----------------- " + DateTime.Now.ToString());
vals = new List<List<float>>();
weights = new List<List<List<float>>>();
biases = new List<List<float>>();
Random randB = new Random(DateTime.Now.Millisecond);
Random randW = new Random(DateTime.Now.Millisecond);
for (int i = 0; i <= nrLayers; i++)
{
progressEpochs.Value =(int)(((float)i * (float)nrLayers) / 100.0f);
vals.Add(new List<float>());
weights.Add(new List<List<float>>());
if (i == 0)
{
for (int j = 0; j < inputTypes.Count; j++)
{
vals[i].Add(0);
}
}
else
{
biases.Add(new List<float>());
for (int j = 0; j < neurons[i-1]; j++)
{
vals[i].Add(0);
float valB = (float)randB.NextDouble();
biases[i-1].Add(valB - ((int)valB));
}
}
}
float valLB = (float)randB.NextDouble();
biases.Add(new List<float>());
biases[nrLayers].Add(valLB - ((int)valLB));
for (int i = 0; i <= nrLayers; i++)
{
if (i == 0)
{
for (int j = 0; j < inputTypes.Count; j++)
{
weights[i].Add(new List<float>());
for (int x = 0; x < neurons[i]; x++)
{
float valW = (float)randW.NextDouble();
weights[i][j].Add(valW);
}
}
}
else if (i == nrLayers)
{
for (int j = 0; j < neurons[i-1]; j++) {
weights[i].Add(new List<float>());
weights[i][j].Add(0);
}
}
else
{
for (int j = 0; j < neurons[i - 1]; j++)
{
weights[i].Add(new List<float>());
for (int x = 0; x < neurons[i]; x++)
{
float valW = (float)randW.NextDouble();
weights[i][j].Add(valW);
}
}
}
}
Random rand = new Random(DateTime.Now.Millisecond);
log("\n\n");
for (int i = 0; i < epochs; i++)
{
log("Epoch " + (i + 1).ToString() + " inceput ---> " + DateTime.Now.ToString());
int idx = rand.Next() % training_test.Count;
float target = outputsPossible.IndexOf(training_labels[idx]);
for (int j = 0; j < nrLayers; j++)
{
calc_lyr(j - 1, j, idx, target);
}
float total_val = 0;
for(int x = 0; x < neurons[nrLayers - 1]; x++)
{
float val = relu(weights[nrLayers][x][0] * vals[nrLayers][x] + biases[nrLayers][0]);
total_val += val;
}
total_val = sigmoid(total_val);
float cost_res = cost(total_val, target);
log("Epoch " + (i+1).ToString() + " terminat ----- " + DateTime.Now.ToString() + "\n");
log("Eroare epoch ---> " + (cost_res<1?"0":"") + cost_res.ToString("##.##") + "\n\n\n");
float cost_der = cost_d(total_val, target);
for (int a = 0; a < weights.Count; a++)
{
for (int b = 0; b < weights[a].Count; b++)
{
for (int c = 0; c < weights[a][b].Count; c++)
{
weights[a][b][c]-=cost_der*learning_rate * sigmoid_d(weights[a][b][c]);
}
}
}
for (int a = 0; a < nrLayers; a++)
{
for (int b = 0; b < neurons[a]; b++)
{
biases[a][b] -= cost_der * learning_rate;
}
}
}
hasTrained = true;
testBut.Enabled = hasTrained;
MessageBox.Show("Antrenament complet!");
SavePrompt sp = new SavePrompt();
sp.Show();
}
How can it be changed to optimize the weights, biases and loss function? For now, when I try to debug, the weights are changing, but it is the same value for the loss function.
I solved it by using AForge.NET: link
Below is the code I wrote for clustering using genetic algorithm. Points are from a picturebox, generated randomly (X,Y) before calling this class. However, the result of this algorithm is much worse than k-means or lbg I'm comparing it to. Can someone take a look for any errors in the algorithm, maybe I omitted something. Thanks.
I did this using arrays, the 2 other I did using lists, but I don't think that should have any impact on result.
public class geneticAlgorithm
{
static int pom = 0;
static PictureBox pb1;
public geneticAlgorithm(PictureBox pb)
{
pb1 = pb;
}
public static void doGA(PointCollection points, int clusterCounter)
//points is a list of points,
//those point have (X,Y) coordinates generated randomly from pictureBox
//coordinates. clusterCounter is how many clusters I want to divide the points into
{
//this part converts list of points into array testtab,
//where each array field hold X,Y of a point
Point[] test = new Point[points.Count];
test = points.ToArray();
double[][] testtab = new double[test.Length][];
for (int i = 0; i < testtab.GetLength(0); i++)
{
testtab[i] = new double[2];
testtab[i][0] = test[i].X;
testtab[i][1] = test[i].Y;
}
//end of converting
int n = testtab.GetLength(0);
int k = clusterCounter;
int chromosomeCount = 500;
int dimensions = 2;
double[][] testClusters = new double[k][];
for (int i = 0; i < k; i++)
{
testClusters[i] = new double[dimensions];
}
double[][] testChromosomes = new double[chromosomeCount][];
for (int i = 0; i < chromosomeCount; i++)
{
testChromosomes[i] = new double[2 * k];
}
int[][] testChromosomesInt = new int[chromosomeCount][];
for (int i = 0; i < chromosomeCount; i++)
{
testChromosomesInt[i] = new int[2 * k];
}
double[] partner = new double[chromosomeCount];
double[][] roulette = new double[chromosomeCount][];
for (int i = 0; i < chromosomeCount; i++)
{
roulette[i] = new double[1];
}
double[][] errors = new double[chromosomeCount][];
for (int i = 0; i < chromosomeCount; i++)
{
errors[i] = new double[1];
}
double crossingPossibility = 0.01;
double mutationPossibility = 0.0001;
int maxIterations = 10000;
//here I create chromosomes and initial clusters
for (int j = 0; j < chromosomeCount; j++)
{
for (int i = 0; i < k; i++)
{
Random rnd = new Random();
int r = rnd.Next(n);
for (int q = 0; q < dimensions; q++)
{
testClusters[i][q] = testtab[r][q];
}
}
int help = 0;
for (int i = 0; i < k; i++)
for (int l = 0; l < dimensions; l++) // here is creation of chromosome
{
testChromosomes[j][help] = testClusters[i][l];
help++;
}
//end
//here I call accomodation function to see which of them are good
errors[j][0] = accomodationFunction(testClusters, testtab, n, k);
//end
//cleaning of the cluster table
testClusters = new double[k][];
for (int i = 0; i < k; i++)
{
testClusters[i] = new double[dimensions];
}
}
//end
for (int counter = 0; counter < maxIterations; counter++)
{
//start of the roulette
double s = 0.0;
for (int i = 0; i < chromosomeCount; i++)
s += errors[i][0];
for (int i = 0; i < chromosomeCount; i++)
errors[i][0] = chromosomeCount * errors[i][0] / s;
int idx = 0;
for (int i = 0; i < chromosomeCount; i++)
for (int j = 0; i < errors[i][0] && idx < chromosomeCount; j++)
{
roulette[idx++][0] = i;
}
double[][] newTab = new double[chromosomeCount][];
for (int i = 0; i < chromosomeCount; i++)
{
newTab[i] = new double[2 * k];
}
Random rnd = new Random();
for (int i = 0; i < chromosomeCount; i++)
{
int q = rnd.Next(chromosomeCount);
newTab[i] = testChromosomes[(int)roulette[q][0]];
}
testChromosomes = newTab;
//end of roulette
//start of crossing chromosomes
for (int i = 0; i < chromosomeCount; i++)
partner[i] = (rnd.NextDouble() < crossingPossibility + 1) ? rnd.Next(chromosomeCount) : -1;
for (int i = 0; i < chromosomeCount; i++)
if (partner[i] != -1)
testChromosomes[i] = crossing(testChromosomes[i], testChromosomes[(int)partner[i]], rnd.Next(2 * k), k);
//end of crossing
//converting double to int
for (int i = 0; i < chromosomeCount; i++)
for (int j = 0; j < 2 * k; j++)
testChromosomes[i][j] = (int)Math.Round(testChromosomes[i][j]);
//end of conversion
//start of mutation
for (int i = 0; i < chromosomeCount; i++)
if (rnd.NextDouble() < mutationPossibility + 1)
testChromosomesInt[i] = mutation(testChromosomesInt[i], rnd.Next(k * 2), rnd.Next(10));
//end of mutation
}
//painting of the found centre on the picture box
int centrum = max(errors, chromosomeCount);
Graphics g = pb1.CreateGraphics();
SolidBrush brush = new SolidBrush(Color.Red);
for (int i = 0; i < 2 * k - 1; i += 2)
{
g.FillRectangle(brush, testChromosomesInt[centrum][i], testChromosomesInt[centrum][i + 1], 20, 20);
}
return;
}
//end of painting
public static int max(double[][] tab, int chromosomeCount)
{
double max = 0;
int k = 0;
for (int i = 0; i < chromosomeCount; i++)
{
if (max < tab[i][0])
{
max = tab[i][0];
k = i;
}
}
return k;
}
public static int[] mutation(int[] tab, int elem, int bit)
{
int mask = 1;
mask <<= bit;
tab[elem] = tab[elem] ^ mask;
return tab;
}
public static double[] crossing(double[] tab, double[] tab2, int p, int k)
{
double[] hold = new double[2 * k];
for (int i = 0; i < p; i++)
hold[i] = tab[i];
for (int i = p; i < 2 * k; i++)
hold[i] = tab2[i];
return hold;
}
//accomodation function, checks to which centre which point belongs based on distance
private static double accomodationFunction(double[][] klastry, double[][] testtab, int n, int k)
{
double Error = 0;
for (int i = 0; i < n; i++)
{
double min = 0;
int ktory = 0;
for (int j = 0; j < k; j++)
{
double dist = distance(klastry[j], testtab[i]);
if (j == 0)
{
min = dist;
}
if (min > dist)
{
min = dist;
ktory = j;
}
}
Error += min;
}
pom++;
return 1 / Error;
}
public static double distance(double[] tab, double[] tab2)
{
double dist = 0.0;
for (int i = 0; i < tab.GetLength(0); i++)
dist += Math.Pow(tab[i] - tab2[i], 2);
return dist;
}
}
The algorithm should work like so: (excuse me if not the best english)
1. Get random points (let's say 100)
2. Check into how many clusters we want to split them (the same thing I would do using k-means for example
3. Get starting population of chromosomes
4. Throu cutting on the roulette, crossing and mutation pick the best x centres, where x is the amount of clusters we want
5. Paint them.
Here are some results, and why I think it's wrong: (it's using 100 points, 5 clusters)
k-means:
lbg:
genetic(without colors now):
I hope this clarifies a bit.
I am trying to solve Gaussian elimination in c# using parallel-processing (in this case Parallel.For). My code is sometimes running fine and sometimes not.
I used as a starting point the code shown on the link: http://www.codeproject.com/Tips/388179/Linear-Equation-Solver-Gaussian-Elimination-Csharp .
I didn't use Parallel.For for back insertion just yet because there is problem with elimination.
Elimination Class:
public static bool Gauss(double[][] M)
{
int rowCount = (M.GetLength(0));
int temp = rowCount - 1;
//elimination
Parallel.For(0, temp, sourceRow =>
//for (int sourceRow = 0; sourceRow + 1 < rowCount; sourceRow++)//diagonal
{
for (int destRow = sourceRow + 1; destRow < rowCount; destRow++)//destination row
{
double df = M[sourceRow][sourceRow];
double sf = M[destRow][sourceRow];
for (int j = 0; j < rowCount + 1; j++) // line
{
M[destRow][j] = (M[destRow][j] * df - M[sourceRow][j] * sf) / df;
}
}
});
//back-insertion
for (int row = rowCount - 1; row >= 0; row--)
{
double f = M[row][row];
if (f == 0) return false;
for (int i = 0; i < rowCount + 1; i++) M[row][i] /= f;
for (int destRow = 0; destRow < row; destRow++)
{
M[destRow][rowCount] -= M[destRow][row] * M[row][rowCount];
M[destRow][row] = 0;
}
}
return true;
}
Generate Array:
public static double[][] GenerateArray2(int n)
{
Random rnd = new Random();
double[][] M = new double[n][];
for (int i = 0; i < n; i++)
{
M[i] = new double[n + 1]; // Create inner array
for (int j = 0; j < n + 1; j++)
M[i][j] = rnd.Next(-20, 20);
}
return M;
}
Print Array
public static string Print2(double[][] M)
{
string str = "";
int rowCount = M.GetUpperBound(0) + 1;
for (int row = 0; row < rowCount; row++)
{
for (int i = 0; i <= rowCount; i++)
{
str += M[row][i];
str += "\t";
}
str += Environment.NewLine;
}
return str;
}
Results are wrong in matrix 16x17 and up. At this point I don't know how to continue, I tried to lock M in elimination, didn't help.
Thanks for any help.
I need to calculate matrix: ( X^(T) * X )^(-1).
Legend for the code&comments:
x is double[,] array;
xT - transposed matrix
^(-1) - inverted matrix
Every time i generate new random matrix to work with it and i found out that program is very unstable, because it isn't working properly with any input data. I'm sure about that because i need to get Identity matrix in the end if everything's fine, but sometimes i get a totally terrible Ineverted matrix so i don't get an Identity matrix. I'm dissappointes because i always use the same type of data and do not convert anything. Compiler is MVS 2010. Hope You will help me.
Here is my Program.cs:
static void Main(string[] args)
{
Matrix x = new Matrix(5, 4);
//Matrix temp = new Matrix(x.Row, x.Col);
//double[] y = new double[x.Row];
//double[] b = new double[x.Row];
//this data isn't calculated correctly. used for debugging
x.MatrixX[0, 0] = 7; x.MatrixX[0, 1] = 6; x.MatrixX[0, 2] = 5; x.MatrixX[0, 3] = 8;
x.MatrixX[1, 0] = 7; x.MatrixX[1, 1] = 5; x.MatrixX[1, 2] = 8; x.MatrixX[1, 3] = 5;
x.MatrixX[2, 0] = 6; x.MatrixX[2, 1] = 8; x.MatrixX[2, 2] = 6; x.MatrixX[2, 3] = 8;
x.MatrixX[3, 0] = 8; x.MatrixX[3, 1] = 5; x.MatrixX[3, 2] = 8; x.MatrixX[3, 3] = 7;
x.MatrixX[4, 0] = 8; x.MatrixX[4, 1] = 5; x.MatrixX[4, 2] = 6; x.MatrixX[4, 3] = 7;
/*
7,00000 6,00000 5,00000 8,00000
7,00000 5,00000 8,00000 5,00000
6,00000 8,00000 6,00000 8,00000
8,00000 5,00000 8,00000 7,00000
8,00000 5,00000 6,00000 7,00000
*/
//random matrix generation
/*
Random rnd = new Random();
for (int i = 0; i < x.Row; i++)
for (int j = 0; j < x.Col; j++)
x.MatrixX[i, j] = rnd.Next(5, 10);
*/
/*i'm going to calculate: ( X^(T) * X )^(-1)
* 1. transpose X
* 2. multiply X and (1)
* 3. invert matrix (2)
* +4. i wanna check the results: Multilate of (2) and (3) = Identity_matrix.
* */
Matrix.Display(x);
//1
Matrix xt = Matrix.Transpose(x);
Matrix.Display(xt);
//2
Matrix xxt = Matrix.Multiply(x, xt);
Matrix.Display(xxt);
//3
Matrix xxtinv = Matrix.Invert(Matrix.Multiply(x, xt));
Matrix.Display(xxtinv);
//4
Console.WriteLine("Invert(xxt) * xxt. IdentityMatrix:");
Matrix IdentityMatrix = Matrix.Multiply(xxtinv, xxt);
Matrix.Display(IdentityMatrix);
Console.ReadKey();
}
And here is Matrix.cs with all functions:
public class Matrix
{
private double[,] matrix;
private int row;
private int col;
#region constructors
public Matrix(int Row, int Col)
{
this.row = Row;
this.col = Col;
matrix = new double[Row, Col];
}
public Matrix()
{
Random rnd = new Random();
Row = rnd.Next(3, 7);
Col = rnd.Next(3, 7);
matrix = new double[Row, Col];
for (int i = 0; i < Row; i++)
for (int j = 0; j < Col; j++)
matrix[i, j] = rnd.Next(5, 10);
}
public Matrix(Matrix a)
{
this.Col = a.Col;
this.Row = a.Row;
this.matrix = a.matrix;
}
#endregion
#region properties
public int Col
{
get { return col; }
set { col = value; }
}
public int Row
{
get { return row; }
set { row = value; }
}
public double[,] MatrixX
{
get { return matrix; }
set { matrix = value; }
}
#endregion
static public Matrix Transpose(Matrix array)
{
Matrix temp = new Matrix(array.Col, array.Row);
for (int i = 0; i < array.Row; i++)
for (int j = 0; j < array.Col; j++)
temp.matrix[j, i] = array.matrix[i, j];
return temp;
}
static public void Display(Matrix array)
{
for (int i = 0; i < array.Row; i++)
{
for (int j = 0; j < array.Col; j++)
Console.Write("{0,5:f2}\t", array.matrix[i, j]);
Console.WriteLine();
}
Console.WriteLine();
}
static public Matrix Multiply(Matrix a, Matrix b)
{
if (a.Col != b.Row) throw new Exception("multiplication is impossible: a.Col != b.Row");
Matrix r = new Matrix(a.Row, b.Col);
for (int i = 0; i < a.Row; i++)
{
for (int j = 0; j < b.Col; j++)
{
double sum = 0;
for (int k = 0; k < b.Row; k++)
sum += a.matrix[i, k] * b.matrix[k, j];
r.matrix[i, j] = sum;
}
}
return r;
}
static public Matrix Invert(Matrix a)
{
Matrix E = new Matrix(a.Row, a.Col);
double temp = 0;
int n = a.Row;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
E.matrix[i, j] = 0.0;
if (i == j)
E.matrix[i, j] = 1.0;
}
for (int k = 0; k < n; k++)
{
temp = a.matrix[k, k];
for (int j = 0; j < n; j++)
{
a.matrix[k, j] /= temp;
E.matrix[k, j] /= temp;
}
for (int i = k + 1; i < n; i++)
{
temp = a.matrix[i, k];
for (int j = 0; j < n; j++)
{
a.matrix[i, j] -= a.matrix[k, j] * temp;
E.matrix[i, j] -= E.matrix[k, j] * temp;
}
}
}
for (int k = n - 1; k > 0; k--)
{
for (int i = k - 1; i >= 0; i--)
{
temp = a.matrix[i, k];
for (int j = 0; j < n; j++)
{
a.matrix[i, j] -= a.matrix[k, j] * temp;
E.matrix[i, j] -= E.matrix[k, j] * temp;
}
}
}
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
a.matrix[i, j] = E.matrix[i, j];
}
return a;
}
}
In your example, the determinant of x * transpose(x) is zero. As a result, there is no inverse, which is probably why you're getting strange results.
I also note that your Inverse function modifies the matrix passed to it. This should probably be modified to avoid that.
I'm doing a class assignment,
I need to create an 2D array of random numbers and sort them either bubble or other sorting codes. I'm fine with single array, but the problem is a 2D array filled with random numbers, I just don't get it.
Random numbers should be made of (-I,I) interval it's a user input. Sorry for bad english, haven't gotten any degree. In working on visual C# windows form.
looking for simple couple cicles method.
example. : A[MxN] ->>> B[MxN] (Sorted 1.....n)
Getting the random numbers is trivial:
Random rnd;
for (int y = 0; y < h; y++)
for (int x = 0; x < w; x++)
array[y][x] = l - rnd.Next(2 * l + 1);
Random.Next() will return a random value between 0 and the given parameter (excluding the parameter; which is the reason for the + 1).
A 2D array can be sorted just like a 1D array, it only depends how you want to handle multiple lines, e.g. is it just for display or do you want to sort every line for itself, etc.
Here's a solution which first sorts each row's columns into order, then sorts each row comparing by first column, then second, etc:
namespace StackOverflow.Demos
{
class Program
{
public static void Main(string[] args)
{
new Program();
Console.WriteLine("Done");
Console.ReadKey();
}
Program()
{
double[,] data = GenerateData();
OutputData(data, "Before");
SortData(ref data);
OutputData(data, "After");
}
double[,] GenerateData()
{
Random randomGenerator = new Random(DateTime.UtcNow.Millisecond);
double[,] data = new double[5, 5];
for (int i = 0; i < data.GetLength(0); i++)
{
for (int j = 0; j < data.GetLength(1); j++)
{
data[i, j] = (randomGenerator.NextDouble() * 2) - 1;
}
}
return data;
}
void OutputData(double[,] data, string message)
{
Console.WriteLine("=====================");
Console.WriteLine(message);
Console.WriteLine("=====================");
for (int i = 0; i < data.GetLength(0); i++)
{
for (int j = 0; j < data.GetLength(1); j++)
{
Console.Write(data[i, j]);
Console.Write("\t");
}
Console.WriteLine();
}
}
void SortData(ref double[,] data)
{
//sort sub arrays
SortDataRows(ref data);
//sort this array
for (int i = 0; i < data.GetLength(0)-1; i++)
{
for (int j = i; j < data.GetLength(0); j++)
{
for (int k = 0; k < data.GetLength(1); k++)
{
if (data[i, k].CompareTo(data[j, k]) < 0) //if already in order exit loop
{
break;
} else if (data[i, k].CompareTo(data[j, k]) > 0) //if out of order switch and loop
{
SwapRows(ref data, i, j);
break;
}//else orders are equal so far; continue to loop
}
}
}
}
void SortDataRows(ref double[,] data)
{
for (int row = 0; row < data.GetLength(0); row++)
{
for (int i = 0; i < data.GetLength(1) - 1; i++)
{
for (int j = i; j < data.GetLength(1); j++)
{
if (data[row, i].CompareTo(data[row, j]) > 0)
{
Swap<double>(ref data[row, i], ref data[row, j]);
}
}
}
}
}
void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
void SwapRows(ref double[,]data, int i, int j)
{
for (int k = 0; k < data.GetLength(1); k++)
{
Swap<double>(ref data[i, k], ref data[j, k]);
}
}
}
}
The code's not the best (haven't had a cup of tea yet), but should do what you're after.
Here's a better solution (not using a 2D array as such, but using a structure which can easily be converted to/from such an array):
sing System.Diagnostics;
namespace StackOverflow.Demos
{
class Program
{
public static void Main(string[] args)
{
new Program();
Console.WriteLine("Done");
Console.ReadKey();
}
Program()
{
List<List<double>> data = GenerateData(5, 5).ToList<List<double>>();
OutputData(data,"Before");
foreach (List<double> item in data)
{
item.Sort();
}
data.Sort(CompareListOfDoubles);
OutputData(data,"After");
}
private IEnumerable<List<double>> GenerateData(int index1, int index2)
{
Random rnd = new Random(DateTime.UtcNow.Millisecond);
List<double> result;
for (int i = 0; i < index1; i++)
{
result = new List<double>(index2);
for (int j = 0; j < index2; j++)
{
result.Add(rnd.NextDouble() * 2 - 1);
}
yield return result;
}
}
private void OutputData(List<List<double>> data, string message)
{
Console.WriteLine(message);
foreach (List<double> list in data)
{
foreach (double datum in list)
{
Console.Write(datum);
Console.Write("\t");
}
Console.WriteLine();
}
}
static int CompareListOfDoubles(List<double> a, List<double> b)
{
for (int i = 0; i < a.Count; i++)
{
if (i > b.Count) return -1;
if (a[i] > b[i]) return -1;
if (a[i] < b[i]) return 1;
}
if (b.Count > a.Count) return 1;
return 0;
}
double[,] ConvertListListDoubleTo2DArray(List<List<double>> data)
{
double[,] result = new double[data.Count, data[0].Count];
for (int i = 0; i < result.GetLength(0); i++)
{
for (int j = 0; j < result.GetLength(1); j++)
{
result[i, j] = data[i][j];
}
}
return result;
}
}