My problem is I have M subproblem. Each subproblem include x (double array) and reduced cost which has different value for each iteration m. I want to show x which has the minimum reduced cost among all subproblems. here is my class:
public class Subproblem
{
public double[,] x { get; set; }
public double ReducedCost { get; set; }
}
So far, I already can get the minimum Reduced Cost and index of it. Now I want to show x value (double array) which on that index. I've code like this:
var sub = new List<Subproblem>();
for (int m = 0; m < M; ++m)
{
Subproblem s = new Subproblem();
s.x = new double[DC1, DC1];
s.ReducedCost = model.ObjVal;
for (int i = 0; i < DC1; ++i)
{
for (int j = 0; j < DC1; ++j)
{
s.x[i, j] = x[i, j].X;
}
}
sub.Add(s);
}
double minRC = sub.Min(a => a.ReducedCost);
int minRCIndex = sub.FindIndex((i) => i.ReducedCost == minRC);
Console.WriteLine(sub.x(minRCIndex));
the last line (Console.WriteLine(sub.x(minRCIndex));) still got red underline, I don't know how to write it
If you are only trying to get the minimum Reduced Costed subproblem you should be doing:
Subproblem minimumReducedCostedSubproblem = sub[minRCIndex];
And you can print the matrix down like this:
for (int i = 0; i < DC1; ++i)
{
for (int j = 0; j < DC1; ++j)
{
Console.Write(minimumReducedCostedSubproblem.x[i, j] + "\t");
}
Console.Write("\n");
}
But you seem a little confused. You are pushing a Subproblem into your sub list with the same object for M times. Because model.ObjVal doesn't change along the first for loop. There is something wierd going on there too.
It should be
var objWithMinReduceCost = sub[minRCIndex];
//Now you have the object of Subproblem derived from your logic.
//You can access x property of it have further logic to process it.
for (int i = 0; i < DC1; ++i)
{
for (int j = 0; j < DC1; ++j)
{
Console.WriteLine(objWithMinReduceCost.x[i, j]);
}
}
If you are interested in obtaining the double array, you could just do this:
double[,] result = sub.First(i => i.ReducedCost == minRC).x;
Although as Tolga mentioned, all your elements will have the same ReducedCost with your current code.
Related
I have a matrix and I want to return an array containing as elements the sum of each row elements of the matrix.
int [] sum;
for (var i = 0; i < m; i++)
{
for (var j = 0; j < result.Pages[i].Actual.Count; j++)
{
sum[i] += result.Pages[i].Actual[j];
}
}
This is how I tried to do it but seems it is not working. Any ideas?
Use var m = a.GetLength(0); to get number of rows, and var n = a.GetLength(1); to get number of columns.
now that looks like a different story after you edit:
Actually the first problem would be a NullreferenceException because int[]sum is not initialized!
Anyway, so it seems that you have an array of arrays. In this case you would need the Length of the Pages array to save your results. The first loop iterates over it using i and will run until result.Pages.Length. For each i you have correctly implemented a second loop where you sum up the result.
int [] sum = new int[result.Pages.Length];
for (var i = 0; i < result.Pages.Length; i++)
{
for (var j = 0; j < result.Pages[i].Actual.Length; j++)
{
sum[i] += result.Pages[i].Actual[j];
}
}
If you collections are List's then you need to use Count instead of Length
The Linq solution would look like this:
int [] sum = result.Pages.Select(x=>x.Sum()).ToArray();
EDIT:
double? means that you have a nullable data type. This is different from the normal double. Furthermore the default value will be null That means that you need to initialize the value at position i in sum before you add up values, otherwise the result will be null.
double? [] sum = new double?[result.Pages.Length];
for (var i = 0; i < result.Pages.Length; i++)
{
sum[i] = 0;
for (var j = 0; j < result.Pages[i].Actual.Length; j++)
{
sum[i] += result.Pages[i].Actual[j];
}
}
In the example below, I found a strange behaviour.
I'm initializing a matrix of Complex (using System.Numerics), assigning a counter value for each position.
But at a certain moment the procedure override the previous cells.
What's wrong there is there any array limit?
it seems the Complex type the issue, with a double array this doesn't happen.
Any suggestion?
private static void Test()
{
Complex[,] m = new Complex[16400, 16400];
long count = 1;
for (int i = 0; i < 16400; i++)
{
for (int j = 0; j < 16400; j++)
{
m[i, j] = new Complex((double)count++, 0);
if (m[0,0] != 1)
Debug.Print(string.Format("({0},{1})> m[0,0] =" + m[0, 0].ToString(), i,j));
}
}
}
What I want to do is compare two of the same variable in a structure.
For example I have a structure like so:
struct player
{
public string name;
public int number;
}
static player[] players = new player[3];
and what I want to do is compare the numbers, so that if two players have the same number, something will happen.
This is what I tried, however it would always say two numbers were the same because it would compare two of the same
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length; j++)
{
if (players[i].number == players[j].number)
{
Console.WriteLine("Same");
Console.ReadLine();
}
else
{
Console.WriteLine("Not");
Console.ReadLine();
}
}
Hopefully you understand what I mean.
Any help would be really appreciated!
Thanks
Problem is in your loop variables i and j starting both at index zero. Then you are comparing element zero to element zero and therefore the condition is true.
Update this line:
for (int j = 0; j < length; j++)
to this:
for (int j = i + 1; j < length; j++)
Edit
To be more precise. The condition evaluates to true not only for the first element, but for each element when i and j are the same. This solution bars both control variables from having the same value in any iteration.
Simple, just add a check to make sure you aren't comparing the same index, because this is the same object:
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length; j++)
{
if (i == j) continue;
if (players[i].number == players[j].number)
{
Console.WriteLine("Same");
Console.ReadLine();
}
else
{
Console.WriteLine("Not");
Console.ReadLine();
}
}
Use a Class, and do it using Linq:
public class Player
{
public string Name { get; set; }
public int Number { get; set; }
}
Then in the other class have this method to cross-check
private void Match()
{
var players = new Player[3].ToList();
foreach (var found in players.ToList().Select(player => players.FirstOrDefault(p => p.Number == player.Number)))
{
if (found != null)
{
Console.WriteLine("Same");
Console.ReadLine();
}
else
{
Console.WriteLine("Not");
Console.ReadLine();
}
}
}
I have written the following code but it looks to be far from efficient.
//Find largest in tempRankingData
int largestIntempRankingData = tempRankingData[0, 0];
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] > largestIntempRankingData)
{
largestIntempRankingData = tempRankingData[i, j];
}
}
}
//Find position of largest in tempRankingData
List<string> positionLargestIntempRankingData = new List<string>();
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] == largestIntempRankingData)
{
positionLargestIntempRankingData.Add(i + "," + j);
}
}
}
//Find largest in each column
int largestInColumn = 0;
List<string> positionOfLargestInColumn = new List<string>();
Dictionary<int, List<string>> position = new Dictionary<int, List<string>>();
for (int i = 0; i < count; i++)
{
largestInColumn = tempRankingData[0, i];
positionOfLargestInColumn = new List<string>();
for (int j = 0; j < count; j++)
{
if (tempRankingData[j, i] > largestInColumn)
{
largestInColumn = tempRankingData[j, i];
}
}
for (int j = 0; j < count; j++)
{
if (tempRankingData[j, i] == largestInColumn)
{
positionOfLargestInColumn.Add(j + "," + i);
}
}
position.Add(i, positionOfLargestInColumn);
}
So, I wanted to check about the most efficient way to do this.
Whilst you're finding the largest in each column, you could also be finding the largest overall. You can also capture the positions as you go:
//Find largest in each column
int largestInColumn = 0;
int largestOverall = int.MinValue;
List<string> positionOfLargestInColumn;
Dictionary<int, List<string>> position = new Dictionary<int, List<string>>();
List<string> positionLargestIntempRankingData = new List<string>();
for (int i = 0; i < count; i++)
{
largestInColumn = tempRankingData[0, i];
positionOfLargestInColumn = new List<string>();
positionOfLargestInColumn.Add("0," + i);
for (int j = 1; j < count; j++)
{
if (tempRankingData[j, i] > largestInColumn)
{
largestInColumn = tempRankingData[j, i];
positionOfLargestInColumn.Clear();
positionOfLargestInColumn.Add(j + "," + i);
}
else if(tempTankingData[j,i] == largestInColumn)
{
positionOfLargestInColumn.Add(j + "," + i);
}
}
position.Add(i, positionOfLargestInColumn);
if(largestInColumn > largestOverall)
{
positionLargestIntempRankingData.Clear();
positionLargestIntempRankingData.AddRange(positionOfLargestInColumn);
largestOverall = largestInColumn;
}
else if(largestInColumn == largestOverall)
{
positionLargestIntempRankingData.AddRange(positionOfLargestInColumn);
}
}
1). You can find largest element and its position in one method and retrieve.
Would be caller of your method concerned about position or actual value, is a matter of concrete case.
2) You can use `yield return' technique in your matrix search (for column based search), so do not compute all column's maximas and push them into the dictionary. Dictionaries are not that fast as arrays, if you can avoid use them, do that.
3) You can keep a matrix in single dimension, long array. Have [] access operator overload, to "emulate" matrix access. Why ? If finding maximum is something frequent you might need to do during program run, having one foreach loop is faster then having 2 nested once. In case of a big matrices, single array search can be easily parallelized among different cores.
If big matrices and/or frequent calls are not your concern, just simplify your code like in points (1), (2).
For your fist two itterations you could replace with this:
//Find largest in tempRankingData
int largestIntempRankingData = tempRankingData[0, 0];
List<KeyValuePair<double,string>> list = new List<KeyValuePair<double,string>>();
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] > largestIntempRankingData)
{
largestIntempRankingData = tempRankingData[i, j];
list.Add(new KeyValuePair<double, string>(largestIntempRankingData, i + "," + j)); //Add the value and the position;
}
}
}
//This gives a list of strings in which hold the position of largestInItemRankingData example "3,3"
//Only positions where the key is equal to the largestIntempRankingData;
list.Where(w => w.Key == largestIntempRankingData).ToList().Select(s => s.Value).ToList();
You can get all these pieces of information in a single scan with a little fiddling around. Something like this (converting the rows and columns to a string is trivial and better done at the end anyway):
int? largestSoFar = null; // you could populate this with myMatrix[0,0]
// but it would fail if the matrix is empty
int largestCol = 0;
int largestRow = 0;
int?[] largestPerColumn = new int?[numOfCols]; // You could also populate this with
// the values from the first row but
// it would fail if there are no rows
int[] largestColumnRow = new int[numOfCols];
for (int i = 0; i < numOfRows; i++)
{
for (int j = 0; j < numOfCols; i++)
{
if (largestSoFar < myMatrix[i,j])
{
largestSoFar = myMatrix[i,j];
largestCol = j;
largestRow = i;
}
if (largestPerColumn[j] < myMatrix[i,j])
{
largestPerColumn[j] = myMatix[i,j];
largestColumnRow[j] = i;
}
}
}
// largestSoFar is the biggest value in the whole matrix
// largestCol and largestRow is the column and row of the largest value in the matrix
// largestPerColumn[j] is the largest value in the jth column
// largestColumnRow[j] is the row of the largest value of the jth column
If you do need to capture all the "maxima" (for want of a better word, because that's not really what you are doing) in a column, you could just change the above code to something like this:
int? largestSoFar = null; // you could populate this with myMatrix[0,0]
// but it would fail if the matrix is empty
int largestCol = 0;
int largestRow = 0;
int?[] largestPerColumn = new int?[numOfCols]; // You could also populate this with
// the values from the first row but
// it would fail if there are no rows
List<int>[] largestColumnRow = new List<int>[numOfCols];
for (int i = 0; i < numOfRows; i++)
{
for (int j = 0; j < numOfCols; i++)
{
if (largestSoFar < myMatrix[i,j])
{
largestSoFar = myMatrix[i,j];
largestCol = j;
largestRow = i;
}
if (largestPerColumn[j] < myMatrix[i,j])
{
largestPerColumn[j] = myMatix[i,j];
largestColumnRow[j].Add(i);
}
}
}
// Now largestColumnRow[j] gives you a list of all the places where you found a larger
// value for the jth column
I have
Cell[,] cells = new Cells[6,6];
I want to initialize it all values to zero
I did something like this
for(int i=1; i<=6;i++) {
for(int j=1; j<=6; j++) {
cells[i,j] = 0;
}
}
The problem is it cant convert int 0 to Cell type. How do I initializze them to zero for first time?? For eg: I have [6,6] array and I want to assign every Cell[2,3].Value = 0
Thanks
The problem is it cant convert int 0 to Cell type. How do I initializze them to zero for first time??
Going by your Class make x and y public first (assuming you are accessing them in methods not in your Cell class:
class Cell
{
public int x;
public int y;
Warrior warrior;
};
Then you should get access to your class members:
Cell[,] cells = new Cells[6,6];
for(int i=0; i<6;i++)
{
for(int j=0; j<6; j++)
{
cells[i,j].x = cells[i,j].y = 0;
}
}
The above is for resetting the values to 0. If you want this on initialization then create a constructor:
Cell(Warrior getWarrior)
{
x = 0;
y = 0;
warrior = getWarrior;
}
Cells[,] cells = new Cells[6, 6];
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 6; j++)
{
cells[i, j]= new Cells(sendWarrior);
Console.WriteLine("\t{0} {1}", cells[i, j].x, cells[i, j].y);
}
}
You can put it like that:
class Cell {
public int x {get; set;}
public int y {get; set;}
Warrior warrior {get; set;}
};
Cell[,] cells = new Cells[6, 6];
// Arrays are zero-based in C#, so they start with 0
for(int i = 0; i < Cells.GetLength(0); i++) // <- Better get length than put "6"
for(int j = 0; j < Cells.GetLength(1); j++)
cells[i, j] = new Cell() { // <- Do not forget to create Cell
x = 0, // <- Overshoot, x will be 0 by default, to show the trick only
y = 0 // <- Overshoot, y will be 0 by default, to show the trick only
};