How to improve nested loop in C#? - c#

I have a function to calculate the costMatrix like this code below.
public double[,] makeCostMatrixClassic(List<PointD> firstSeq, List<PointD> secondSeq)
{
double[,] costMatrix = new double[firstSeq.Count, secondSeq.Count];
costMatrix[0, 0] = Math.Round(this.getEuclideanDistance(firstSeq[0], secondSeq[0]), 3);
// For D(n,1)
for (int i = 0; i < firstSeq.Count; i++)
{
for (int j = 0; j <= i; j++)
{
costMatrix[i, 0] += Math.Round(this.getEuclideanDistance(firstSeq[j], secondSeq[0]), 3);
}
}
// For D(1,m)
for (int i = 0; i < secondSeq.Count; i++)
{
for (int j = 0; j <= i; j++)
{
costMatrix[0, i] += Math.Round(this.getEuclideanDistance(firstSeq[0], secondSeq[j]), 3);
}
}
// For D(n,m)
for (int i = 1; i < firstSeq.Count; i++)
{
for (int j = 1; j < secondSeq.Count; j++)
{
double min = this.findMin(costMatrix[i - 1, j - 1], costMatrix[i - 1, j], costMatrix[i, j - 1]);
costMatrix[i, j] = min + Math.Round(this.getEuclideanDistance(firstSeq[i], secondSeq[j]), 3);
}
}
return costMatrix;
}
For the 3rd loop (n,m), how could i improve its performance if the "count" of each Sequence is 1 million points.

Related

Pascal´s triangle c#

i´d like to build a pascal´s triangle as a square matrix in c# like this.
1 0 0 0 0
1 1 0 0 0
1 2 1 0 0
1 3 3 1 0
1 4 6 4 1
But the following code didn´t perform, could you please help me?
Console.Write("Size of Matrix: ");
int size = Convert.ToInt32(Console.ReadLine());
int[,] pascal = new int[size, size];
for (int i = 0; i < pascal.GetLength(0);i++)
{
for (int j = 0; j < pascal.GetLength(1); j++)
{
if (j > i )
{
pascal[i, j] = 0;
}
if (i == j || j == 0)
{
pascal[i, j] = 1;
}
if (i !=j)
{
pascal[i, j] = pascal[i - 1, j - 1] + pascal[i - 1, j];
}
Console.Write($"{pascal[i,j ],5 }");
}
Console.WriteLine();
}
thx
You are forgot else if and rewrite data if (i != j)
Console.Write("Size of Matrix: ");
int size = Convert.ToInt32(Console.ReadLine());
int[,] pascal = new int[size, size];
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (i == j || j == 0)
{
pascal[i, j] = 1;
}
else if (j > i)
{
pascal[i, j] = 0;
}
else if (i != j)
{
pascal[i, j] = pascal[i - 1, j - 1] + pascal[i - 1, j];
}
Console.Write($"{pascal[i, j],5 }");
}
Console.WriteLine();
}
Your problem is your ifs, need to be else if otherwise you will be trying to reference negative indexes in the array with pascal[i - 1, j - 1] etc.
for (int i = 0; i < pascal.GetLength(0); i++)
{
for (int j = 0; j < pascal.GetLength(1); j++)
{
if (j > i)
pascal[i, j] = 0;
else if (i == j || j == 0)
pascal[i, j] = 1;
else if (i != j)
pascal[i, j] = pascal[i - 1, j - 1] + pascal[i - 1, j];
Console.Write($"{pascal[i, j],5}");
}
Console.WriteLine();
}
Another way you could achieve this is with good old fashioned math
for (var i = 0; i < rows; i++)
for (var j = 0; j <= i; j++)
if (j != 0 && i != 0)
pascal[i, j] = val = val * (i - j + 1) / j;
else
pascal[i, j] = 1;
To Output
for (var i = 0; i < rows; i++)
{
for (var j = 0; j < rows; j++)
Console.Write($"{pascal[i, j]} ");
Console.WriteLine();
}
A new array always contain zeros. You could seed the 1's outside the loops, then only loop through the rest.
I would also separate the construction of the array, from the printing method. If you only wanted to print it, you'd only need one array.
int[,] pascal = new int[size, size];
pascal[0, 0] = 1;
for (int i = 1; i < size; i++)
{
pascal[i, 0] = pascal[i, i] = 1;
for (int j = 1; j <= i - 1; j++)
pascal[i, j] = pascal[i - 1, j - 1] + pascal[i - 1, j];
}
To help to grasp this dynamic programming concept the following is my recursive solution.
for(var i = 0; i < 5; ++i)
{
for(var j = 0; j < i + 1; ++j)
{
Console.Write($"{p(i, j)} ");
}
Console.WriteLine();
}
static int p(int i, int j)
=> (j == 0 || i == j)
? 1
: p(i - 1, j) + p(i - 1, j - 1);

How can i improve this code to find rectangles and not only squares

I have this code and I work finding squares of "0" in 2d arrays.
How can I make find rectangles and not only squares?
I'm having some difficulty doing this.
// Set first column of S[,]
for (i = 0; i < R; i++)
{
S[i, 0] = M[i, 0];
}
// Set first row of S[][]
for (j = 0; j < C; j++)
{
S[0, j] = M[0, j];
}
// Construct other entries of S[,]
for (i = 1; i < R; i++)
{
for (j = 1; j < C; j++)
{
if (M[i, j] == 0)
S[i, j] = Math.Min(S[i, j - 1], Math.Min(S[i - 1, j], S[i - 1, j - 1])) + 1;
}
}
// Find the maximum entry, and indexes of maximum entry in S[,]
max_of_s = S[0, 0];
max_i = 0;
max_j = 0;
for (i = 0; i < R; i++)
{
for (j = 0; j < C; j++)
{
if (max_of_s < S[i, j])
{
max_of_s = S[i, j];
max_i = i;
max_j = j;
}
}
}
Console.WriteLine("Maximum size sub-matrix is: ");
for (i = max_i; i > max_i - max_of_s; i--)
{
for (j = max_j; j > max_j - max_of_s; j--)
{
M[i, j] = 2;
Console.Write(M[i, j] + " ");
}
Console.WriteLine();
}
Find any size rectangles and not only squares.

How to get all possible 2x2 sub matrices in a 3x3 matrix in C#?

If matrix A of size (3x3), then should i use the method of finding determinants, like grabbing the rows and column of first element and removing it from the array 2D array to get the remaining elements and then moving to the next element and repeating the same steps ?
[{1,2,3},
{4,5,6},
{7,8,9}]
I finally was able to do it, here's what I did :
enter image description here
class program
{
public static void Main()
{
int[,] arr = new int[3, 3];
Console.WriteLine("Enter elements of " + (arr.GetUpperBound(0) + 1) + "x" + (arr.GetUpperBound(1) + 1) + " matrix:");
for (int i = 0; i < (arr.GetUpperBound(0) + 1); i++)
{
for (int j = 0; j < (arr.GetUpperBound(1) + 1); j++)
{
arr[i, j] = Convert.ToInt32(Console.ReadLine());
}
}
Console.WriteLine("Matrix entered: ");
for (int i = 0; i < (arr.GetUpperBound(0) + 1); i++)
{
for (int j = 0; j < (arr.GetUpperBound(1) + 1); j++)
{
Console.Write("\t" + arr[i, j]);
}
Console.WriteLine();
}
Console.WriteLine("Possible sub-matrices: ");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j< 3; j++)
{
TrimArray(i,j,arr);
}
}
}
public static int[,] TrimArray(int row, int column, int[,] original)
{
int[,] resultant = new int[original.GetLength(0) - 1, original.GetLength(1) - 1];
for (int i = 0, j = 0; i < original.GetLength(0); i++)
{
if (i == row)
continue;
for (int k = 0, u = 0; k < original.GetLength(1); k++)
{
if (k == column)
continue;
resultant[j, u] = original[i, k];
u++;
}
j++;
}
Console.WriteLine();
for (int i = 0; i < 2; i++)
{
for (int j = 0; j< 2; j++)
{
Console.Write("\t"+resultant[i,j]);
}
Console.WriteLine();
}
return resultant;
}
}
I did this for you yesterday, I created a method that will return a square matrix, given a parent matrix and the length.
static void Main(string[] args)
{
int[][] parentMatrix = new int[][]
{
new int [] { 1, 2, 3 },
new int [] { 4, 5, 6 },
new int [] { 7, 8, 9 }
};
var chunks = GetSubMatrices(parentMatrix, 2);
Console.WriteLine(chunks);
}
static List<int[][]> GetSubMatrices(int[][] parentMatrix, int m)
{
int n = parentMatrix.Length > m ? parentMatrix.Length : throw new InvalidOperationException("You can't use a matrix smaller than the chunk size");
var chunks = new List<int[][]>();
int movLimit = n - m + 1;
var allCount = Math.Pow(movLimit, 2);
for (int selRow = 0; selRow < movLimit; selRow ++)
{
for (int selCol = 0; selCol < movLimit; selCol ++)
{
// this is start position of the chunk
var chunk = new int[m][];
for (int row = 0; row < m; row++)
{
chunk[row] = new int[m];
for (int col = 0; col < m; col++)
{
chunk[row][col] = parentMatrix[selRow + row][selCol + col];
}
}
chunks.Add(chunk);
}
}
return chunks;
}
If you have any problems using it, you can simply comment below.
I needed to solve a problem like and came up with this answer. Hope it adds to your library of answers. If the submatrix specified is not greater than 1, do nothing.
public static void GetSubMatrixes(int[,] arr, int size)
{
int parentMatrixRowLength = arr.GetLength(0);
int parentMatrixColLength = arr.GetLength(1);
var overall = new List<object>();
if(size > 1)
{
for (int i = 0; i < parentMatrixRowLength; i++)
{
//get the columns
for (int j = 0; j < parentMatrixColLength; j++)
{
var subMatrix = new int[size, size];
/*if the new matrix starts from second to the last value in either the row(horizontal or column)
* do not proceed, go to the row or column in the parent matrix
* */
if (j < parentMatrixColLength - (size - 1) && i < parentMatrixRowLength - (size - 1))
{
//add
for (int m = 0; m < subMatrix.GetLength(0); m++)
{
for (int n = 0; n < subMatrix.GetLength(1); n++)
{
/*check the sum of current column value and the sum of the current row value
* of the parent column length and row length if it goes out of bounds
*/
var row = i + m; var col = j + n;
//actual check here
if (row < parentMatrixRowLength && col < parentMatrixColLength)
{
subMatrix[m, n] = arr[i + m, j + n];
}
}
}
overall.Add(subMatrix);
}
}
}
//display the sub matrixes here
for (int i = 0; i < overall.Count; i++)
{
var matrix = overall[i] as int[,];
for (int y = 0; y < matrix.GetLength(0); y++)
{
for (int x = 0; x < matrix.GetLength(1); x++)
{
Console.Write(string.Format("{0} ", matrix[y, x]));
}
Console.Write(Environment.NewLine + Environment.NewLine);
}
Console.WriteLine();
}
}
}

VRP result got infeaslible in Gurobi-C#

I try to solve pricing problem using Gurobi in C#. It's already worked on AMPL and LINGO but got infeasible when I try in C#. Maybe I wrong in indexing or something, please help me
this is my code in C#
static void Main()
{
try
{
// Model
GRBEnv env = new GRBEnv();
GRBModel model = new GRBModel(env);
model.ModelName = "OLRPTW Subproblem";
GRBVar[,] x = new GRBVar[DC1, DC1]; //variable of route
GRBVar[] D = new GRBVar[DC1]; //variable of duration
for (int i = 0; i < DC1; i++)
{
for (int j = 0; j < DC1; j++)
{
x[i, j] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "x" + i + "," + j);
}
}
for (int i = 0; i < DC1; i++)
{
D[i] = model.AddVar(A[i], B[i], 0.0, GRB.CONTINUOUS, "D" + i);
}
for (int i = 0; i < DC1; i++)
{
for (int j = 0; j < DC1; j++)
{
time[i, j] = Distance[i, j] + servicetime[i];
}
}
for (int i = 0; i < DC1; i++)
{
for (int j = 0; j < DC1; j++)
{
ReducedCost[i,j] = Distance[i, j]-DualU[i] + Demand[i]*DualV;
}
}
// Integrate new variables
model.Update();
//objective function
GRBLinExpr sumRC = 0.0;
for (int i = 0; i < DC1; i++)
{
for (int j = 0; j < DC1; j++)
{
sumRC += ReducedCost[i, j] * x[i, j];
}
}
model.SetObjective(sumRC, GRB.MINIMIZE);
//constraint 1
GRBLinExpr sumI = 0.0;
for (int i = 0; i < DC1; i++)
{
int j = 0;
sumI += x[i, j];
}
model.AddConstr(sumI, GRB.EQUAL, 1.0, "C1.1");
GRBLinExpr sumJ = 0.0;
for (int j = 0; j < DC1; j++)
{
int i = 0;
sumI += x[i, j];
}
model.AddConstr(sumJ, GRB.EQUAL,1.0, "C1.2");
//constraint 2
for (int h = 0; h < C; h++)
{
GRBLinExpr sumIH = 0.0;
GRBLinExpr sumHJ = 0.0;
for (int i = 0; i < DC1; i++)
{
sumIH += x[i, h];
}
for (int j = 0; j < DC1; j++)
{
sumHJ += x[h, j];
}
model.AddConstr(sumIH - sumHJ, GRB.EQUAL, 0.0, "C2");
}
//constraint 3
GRBLinExpr sumCap = 0.0;
for (int i = 0; i < DC1; i++)
{
for (int j = 0; j < DC1; j++)
{
sumCap += Demand[i] * x[i, j];
}
}
model.AddConstr(sumCap, GRB.LESS_EQUAL, Capacity, "Cap");
//constraint 4
for (int i = 0; i < C; i++)
{
for (int j = 0; j < C; j++)
if(i!=j)
{
GRBLinExpr Time = D[i] + time[i, j] + D[j];
GRBLinExpr M = 10000 * (1 - x[i, j]);
model.AddConstr(Time <= M, "Time" + i + j);
}
}
for (int i = 0; i < DC1; i++)
{
model.AddConstr(x[i, i], GRB.EQUAL, 0,"C*");
}
// Solve
model.Optimize();

Change 2d array bubble sort to counting sort

The following code sorts rows by the first element using bubble method.
I can't change it to counting sort.
public void SortStack(double[,] n)
{
for (int i = 0; i < n.GetLength(0) - 1; i++)
{
for (int j = i; j < n.GetLength(0); j++)
{
if (n[i, 0] > n[j, 0])
{
for (int k = 0; k < n.GetLength(1); k++)
{
var temp = n[i, k];
n[i, k] = n[j, k];
n[j, k] = temp;
}
}
}
}
}
Please help.
As you do bubble sort based on first element of each row. you should do counting sort like that too. so you just need to count first item of each row.
private static int[,] CountingSort2D(int[,] arr)
{
// find the max number by first item of each row
int max = arr[0, 0];
for (int i = 0; i < arr.GetLength(0); i++)
{
if (arr[i, 0] > max) max = arr[i, 0];
}
// we want to get count of first items of each row. thus we need 1d array.
int[] counts = new int[max + 1];
// do the counting. again on first index of each row
for (int i = 0; i < arr.GetLength(0); i++)
{
counts[arr[i, 0]]++;
}
for (int i = 1; i < counts.Length; i++)
{
counts[i] += counts[i - 1];
}
// result is sorted array
int[,] result = new int[arr.GetLength(0), arr.GetLength(1)];
for (int i = arr.GetLength(0) - 1; i >= 0; i--)
{
counts[arr[i, 0]]--;
// now we need to copy columns too. thus we need another loop
for (int j = 0; j < arr.GetLength(1); j++)
{
result[counts[arr[i, 0]], j] = arr[i, j];
}
}
return result;
}
Here is the test.
static void Main()
{
Random rand = new Random();
int[,] arr = new int[3,3];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
arr[i, j] = rand.Next(0, 100);
}
}
int[,] newarr = CountingSort2D(arr);
for (int i = 0; i < arr.GetLength(0); i++)
{
Console.Write("{ ");
for (int j = 0; j < arr.GetLength(1); j++)
{
Console.Write(arr[i, j] + " ,");
}
Console.Write("} ,");
}
Console.WriteLine();
for (int i = 0; i < newarr.GetLength(0); i++)
{
Console.Write("{ ");
for (int j = 0; j < newarr.GetLength(1); j++)
{
Console.Write(newarr[i, j] + " ,");
}
Console.Write("} ,");
}
Console.WriteLine();
}
Example Output:
{ 49,66,8 },{ 33,39,64 },{ 65,52,76 } // Original array
{ 33,39,64 },{ 49,66,8 },{ 65,52,76 } // Sorted array

Categories