Why can't get matrix what I passed to Thread? - c#

I want to do some basic stuff: get a matrix, and iterate on it with multiple threads. For example, if I have a 20x20 sized matrix, and I have 4 threads, then the first Thread have to iterate on the 5x20 sized matrix, the second one has to iterate on the same size, but from the 6th row to the 10th one, and so on. But, my program gets only the first part, the second, and third, fourth threads can't see their submatrixes. Why? Can anyone help me with this?
using System;
using System.Diagnostics;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace multi_thred_test
{
class thredData
{
public int my_simulation_size;
public int[,] my_simulation;
public string my_path;
public int my_nrOfAvailableThreads;
public int my_oneThreeadSubsimulationSize;
public thredData(ref int simsize, ref int[,] simu, ref string path, ref int availabelthrd, ref int subsimsize )
{
my_simulation_size = simsize;
my_simulation = new int[simsize, simsize];
for (int i = 0; i < simsize; i++)
{
for (int j = 0; j < simsize; j++)
{
my_simulation[i, j] = simu[i, j];
}
}
my_path = path;
my_nrOfAvailableThreads = availabelthrd;
my_oneThreeadSubsimulationSize = subsimsize;
}
}
class Program
{
public static int simulation_size = 20;
public static int[,] simulation = new int[20, 20];
public static string path = Directory.GetCurrentDirectory();
public static int nrOfAvailableThreads = Environment.ProcessorCount;
public static int oneThreeadSubsimulationSize = simulation_size / nrOfAvailableThreads;
public static thredData tmp;
public static void Main(string[] args)
{
for (int idx = 0; idx < simulation_size; idx++)
{
for (int jdx = 0; jdx < simulation_size; jdx++)
{
simulation[idx, jdx] = idx * 100 + jdx;
}
}
StreamWriter sw = new StreamWriter(path + "_matrix.txt");
for (int idx = 0; idx < simulation_size; idx++)
{
for (int jdx = 0; jdx < simulation_size; jdx++)
{
sw.Write(simulation[idx, jdx]+" ");
}
sw.WriteLine(" ");
}
sw.Close();
tmp = new thredData(ref simulation_size, ref simulation, ref path, ref nrOfAvailableThreads, ref oneThreeadSubsimulationSize);
//generate threads
for (int thrdnr = 0; thrdnr < nrOfAvailableThreads; thrdnr++)
{
Thread newThread = new Thread(ThreadMethod);
newThread.Name = Convert.ToString(thrdnr);
newThread.Start();
}
Console.ReadKey();
}
private static void ThreadMethod()
{
Thread thr = Thread.CurrentThread;
int simulationSize = Convert.ToInt32(thr.Name);
int thrd_simulation_size;
int[,] thrd_simulation;
string thrd_path;
int thrd_nrOfAvailableThreads;
int thrd_oneThreeadSubsimulationSize;
lock (tmp)
{
thrd_simulation_size = tmp.my_simulation_size;
thrd_simulation = new int[thrd_simulation_size, thrd_simulation_size];
for (int i = 0; i < tmp.my_simulation_size; i++)
{
for (int j = 0; j < tmp.my_simulation_size; j++)
{
thrd_simulation[i, j] = tmp.my_simulation[i, j];
}
}
thrd_path = tmp.my_path;
thrd_nrOfAvailableThreads = tmp.my_nrOfAvailableThreads;
thrd_oneThreeadSubsimulationSize = tmp.my_oneThreeadSubsimulationSize;
}
for (int i = thrd_simulation_size * simulationSize; i < thrd_oneThreeadSubsimulationSize; i++)
{
for (int j = 0; j < thrd_simulation_size; j++)
{
Console.Write(thr.Name +":"+ thrd_simulation[i,j] + " ");
}
Console.Write("\n");
}
}
}
}

Problem solved, the log part was wrong:
for (int i = thrd_oneThreeadSubsimulationSize * simulationSize; i < (thrd_oneThreeadSubsimulationSize * simulationSize) +thrd_oneThreeadSubsimulationSize; i++)
{
for (int j = 0; j < thrd_simulation_size; j++)
{
Console.Write(thr.Name + ":" + thrd_simulation[i, j] + " ");
}
Console.Write("\n");
}

Related

Problem with UnitTest(Method doesn`t work properly)

I have a matrix calculator
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp11
{
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("Введите размерность первой матрицы: ");
int[,] A = new int[Convert.ToInt32(Console.ReadLine()), Convert.ToInt32(Console.ReadLine())];
for (int i = 0; i < A.GetLength(0); i++)
{
for (int j = 0; j < A.GetLength(1); j++)
{
Console.Write("A[{0},{1}] = ", i, j);
A[i, j] = Convert.ToInt32(Console.ReadLine());
}
}
Console.WriteLine("Введите размерность второй матрицы: ");
int[,] B = new int[Convert.ToInt32(Console.ReadLine()), Convert.ToInt32(Console.ReadLine())];
for (int i = 0; i < B.GetLength(0); i++)
{
for (int j = 0; j < B.GetLength(1); j++)
{
Console.Write("B[{0},{1}] = ", i, j);
B[i, j] = Convert.ToInt32(Console.ReadLine());
}
}
Console.WriteLine("\nМатрица A:");
Print(A);
Console.WriteLine("\nМатрица B:");
Print(B);
Console.WriteLine("\nМатрица C = A * B:");
int[,] C = Multiplication(A, B);
Print(C);
}
static int[,] Multiplication(int[,] a, int[,] b)
{
if (a.GetLength(1) != b.GetLength(0)) throw new Exception("Матрицы нельзя перемножить");
int[,] r = new int[a.GetLength(0), b.GetLength(1)];
for (int i = 0; i < a.GetLength(0); i++)
{
for (int j = 0; j < b.GetLength(1); j++)
{
for (int k = 0; k < b.GetLength(0); k++)
{
r[i, j] += a[i, k] * b[k, j];
}
}
}
return r;
}
static void Print(int[,] a)
{
for (int i = 0; i < a.GetLength(0); i++)
{
for (int j = 0; j < a.GetLength(1); j++)
{
Console.Write("{0} ", a[i, j]);
}
Console.WriteLine();
}
}
static int[,] Multiplication_test(int[,] a_test, int[,] b_test) // типо забыл поменять что-то
{
int[,] r = new int[a_test.GetLength(0), b_test.GetLength(1)];
for (int i = 0; i < a_test.GetLength(0); i++)
{
for (int j = 0; j < b_test.GetLength(1); j++)
{
for (int k = 0; k < b_test.GetLength(0); k++)
{
r[i, j] -= a_test[i, k] * b_test[k, j];
}
}
}
return r;
}
}
}
And I have a UnitTest Program
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using ConsoleApp11;
using System.Threading.Tasks;
namespace UnitTestProject2
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
int[,] A = { { 1, 2, 3 }, { 3, 4, 5 } };
int[,] B = { { 3, 4 }, { 1, 2 }, { 3, 5 } };
int[,] expected = { { 14, 23 }, { 28, 45 } };
int [,] actual = Multiplication_test(A, B);
Assert.AreEqual(expected, actual, "Multiplication_test1 isn`t correct ");
}
}
}
All in all is fine , but i have a problem
Severity Code Description Project File Line Suppression State
Error CS0103 The name 'Multiplication_test' does not exist in the current context UnitTestProject
I did more things but nothing changed...
I tried change static method to public but nothing changed. Please help me !!!
Multiplication_test is a static method on Program, so it should be Program.Multiplication_test(...)

I got a stack overflow error and I can't figure out what causes it

I am trying to generate a maze and I faced a stack overflow error while trying to do divide and conquer kind of approach to my 2D array.I will have to post the whole code since I have no idea what causes it and i am very inexperienced in the subject.
this is the details : System.StackOverflowException
HResult=0x800703E9
Message=
this is where the exception happens
!https://imgur.com/a/iwX8pKY
https://www.robinsnyder.com/MazeStaticGif I got the idea from here.
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Linq;
namespace labirentVize2
{
class labirentOlustur
{ public static int delik;
public static int x=0;
public static int y;
public static int N = 30;
public static int boy = 30;
int[,] uret = new int[N, N];
public Array girisCikis(int[,] uret)
{
int en1=1;
Random giris = new Random();
int gir = giris.Next(1, 29);
if (gir > 14)
{
int gir2 = giris.Next(15, 28);
int gir3 = (gir + gir2)/2;
uret[0, gir] = 1;
uret[0, gir2] = 1;
uret[0, gir3] = 1;
}
else
{
int gir2 = giris.Next(1, 15);
int gir3 = (gir + gir2)/2;
uret[0, gir] = 1;
uret[0, gir2] = 1;
uret[0, gir3] = 1;
}
Random cikis = new Random();
int cik = cikis.Next(1, 28);
if (cik > 14)
{
int cik2 = cikis.Next(1, 28);
int cik3 = (cik + cik2)/2;
uret[29, cik] = 1;
uret[29, cik2] = 1;
uret[29, cik3] = 1;
}
else
{
int cik2 = cikis.Next(15, 28);
int cik3 = (cik + cik2)/2;
uret[29, cik] = 1;
uret[29, cik2] = 1;
uret[29, cik3] = 1;
}
labYap(uret, en1, x, boy);
return uret;
}
void labGoster(int[,] uret)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
Console.Write(" " + uret[i, j] + " ");
Console.WriteLine();
}
}
public void labYap(int[,] uret, int en1, int x, int boy)
{
int total1 = 0;
Random rand2 = new Random();
for (int i = 0; i < uret.GetLength(0); i++)
{
for (int j = 0; j < uret.GetLength(1); j++)
{
total1 += uret[i, j];}
}
if(total1 > 800)
{
labGoster(uret);
}
else if (total1 == 784)
{
Random rand1 = new Random();
en1 = rand1.Next(2, 29);
x = 30;
delik = rand2.Next(1, 29);
}
else
{
Random rand = new Random();
en1 = rand.Next(1, en1);
boy = boy - en1;
delik = rand2.Next(1, en1);
}
if (diziUstToplam(uret, en1) >= diziAltToplam(uret, en1))
{
y = en1;
for (int j = 0; j < x ; j++)
{
uret[en1, j] = 0;
}
uret[en1, delik] = 1;
labYap(uret, en1, x, boy);
labYap(uret, boy, x, boy);
}
else
{ x = en1;
for (int j = 0; j < en1; j++)
{
uret[j, en1] = 0;
}
uret[delik, en1] = 1;
labYap(uret, en1, x, boy);
labYap(uret, en1, x, boy);
}
int diziUstToplam(int[,] uret, int en1)
{
int total = 0;
// Dizinin ilk boyutu için
for (int i = 0; i < en1; i++)
{
// Dizinin ikinci boyutu için
for (int j = 0; j < uret.GetLength(1); j++)
{
total += uret[i, j];
}
}
return total;
}
int diziAltToplam(int[,] uret, int en1)
{
int total = 0;
// Dizinin ilk boyutu için
for (int i = en1; i < 30; i++)
{
// Dizinin ikinci boyutu için
for (int j = 0; j < uret.GetLength(1); j++)
{
total += uret[i, j];
}
}
return total;
}
int rastgeleSayi()
{
Random rand = new Random();
int en1 = rand.Next(1, 29);
return en1;
}
}
}
}
The stack overflow error is because you call labYear() too many times from within itself. You need to ensure that you have some escape condition where the function can return.
See more here: https://learn.microsoft.com/en-us/dotnet/api/system.stackoverflowexception?view=net-6.0

Read array 2D and output as table C#

I am new at programming in C# and I'm trying to display to whole content of a matrix in the format of a table, however what I got so far is to read the enum and read one line from the matrix. Instead I need to read multiple lines from the matrix and output as a table.
when I run the program I get to insert data twice in row and the output should've been this data inside a table, but only one line is being shown.
Here's the code:
static int getInsertIndex(string[,] matrix)
{
for (int j = 0; j < matrix.GetLength(0); j++)
{
if (string.IsNullOrEmpty(matrix[j, 0])) return j;
}
return -1;
}
private static void InsertData<T>(string[,] matrix)
{
// int newId = generateId(ref id);
int n = getInsertIndex(matrix), id = 1;
matrix[n, 0] = Convert.ToString(id++);
int x = matrix.GetLength(1) - 1;
matrix[n, x] = "true";
for (var j = 1; j < matrix.GetLength(1); j++)
{
do
{
Console.Write($"\nInsert {GetHeader<T>(j)}: ");
matrix[0, j] = Console.ReadLine();
} while (string.IsNullOrEmpty(matrix[0, j]));
}
}
private static void ListData<T>(string[,] matrix)
{
var array = new string[matrix.GetUpperBound(1)];
for (var l = 0; l < matrix.GetLength(0); l++)
{
for (var i = 0; i < array.Length; i++)
{
array[i] = matrix[0, i];
}
}
PrintRow(array);
PrintLine();
}
private static string GetHeader<T>(int i) => Enum.GetName(typeof(T), i);
private static void ShowHeader<T>(string[,] matrix)
{
var array = new string[matrix.GetUpperBound(1)];
for (var i = 0; i < array.Length; i++)
{
array[i] = GetHeader<T>(i);
}
PrintLine();
PrintRow(array);
PrintLine();
}
private static void PrintLine()
{
Console.WriteLine(new string('-', Console.WindowWidth - 1));
}
private static void PrintRow(IReadOnlyCollection<string> columns)
{
var width = (Console.WindowWidth - 1 - columns.Count) / columns.Count;
var row = columns.Aggregate("|", (current, column) => current + AlignCentre(column, width) + "|");
Console.WriteLine(row);
}
static string AlignCentre(string text, int width)
{
text = text.Length > width ? text.Substring(0, width - 3) + "..." : text;
return string.IsNullOrEmpty(text)
? new string(' ', width)
: text.PadRight(width - (width - text.Length) / 2).PadLeft(width);
}
enum ClientHeader { Id, Name, Surname, Addres, CodPostal, Telephone, Email, State };
private static void Main()
{
var client = new string[4, 7];
InsertData<ClientHeader>(client);
Console.Clear();
InsertData<ClientHeader>(client);
ShowHeader<ClientHeader>(client);
ListData<ClientHeader>(client);
}
}
}
There are 2 issues:
1) In the InsertData() function, you want to update the n th row.
Replace
matrix[0, j] = Console.ReadLine();
by
matrix[n, j] = Console.ReadLine();
2) In the ListData() function you want to show each row, so you need to move the array variable into the first for loop. Replace array[i] = matrix[0, i] with array[i] = matrix[l, i] because you are displaying the l th row.
private static void ListData<T>(string[,] matrix)
{
for (var l = 0; l < matrix.GetLength(0); l++)
{
var array = new string[matrix.GetUpperBound(1)];
for (var i = 0; i < array.Length; i++)
{
array[i] = matrix[l, i];
}
PrintRow(array);
}
PrintLine();
}
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
public class Program
{
private static void Main()
{
List<List<string>> data = new List<List<string>>() {
new List<string>() { "Name", "Age", "Weight"},
new List<string>() { "John", "33", "180"},
new List<string>() { "Mary", "32", "125"},
new List<string>() { "Harry", "40", "200"}
};
DataTable dt = new DataTable();
for (int i = 0; i < data.Count; i++)
{
if (i == 0)
{
foreach (string col in data[i])
{
dt.Columns.Add(col);
}
}
else
{
dt.Rows.Add(data[i].ToArray());
}
}
}
}
}

Bug fix in a matrix

I am doing a unity project and I use mapMatrix(matrix of chars) as a map tool to tell which gameObject to instantiate as an environment.
Firstly, I call function populateMapMatrix and writeTextFile to create a txt file with content of a matrix. But now, I need to read from that file into a matrix and then instantiate the environment. I debugged the project and some elements of matrix get '\n' even if I have a way of dealing with that chars. Can someone help me?
Here's the code:
using UnityEngine;
using System.Collections;
using System.IO;
public class EnviromentBuilder : MonoBehaviour {
const int NUMBER_OF_ROWS = 50;
const int NUMBER_OF_COLUMNS = 50;
const char GRASS_MATRIX_FIELD = 'G';
const char TREE_MATRIX_FIELD = 'T';
const string pathToFile = "C:\\Users\\Darko\\Desktop\\Unity\\WAR GAME\\enviromentMapMatrix.txt";
public char[,] mapMatrix;
public GameObject grass;
public GameObject tree;
// Use this for initialization
void Start ()
{
mapMatrix = new char[NUMBER_OF_ROWS, NUMBER_OF_COLUMNS];
//populateMapMatrix ();
readTextFile();
InstantiateEnviroment ();
//writeTextFile ();
}
bool isGrassMatrixField(int i, int j)
{
return mapMatrix [i, j] == GRASS_MATRIX_FIELD ? true : false;
}
bool isTreeMatrixField(int i, int j)
{
return mapMatrix [i, j] == TREE_MATRIX_FIELD ? true : false;
}
void populateMapMatrix()
{
for (int i = 0; i < NUMBER_OF_ROWS; i++)
for (int j = 0; j < NUMBER_OF_COLUMNS; j++)
{
mapMatrix[i,j] = 'G';
if (i > 28 && i < 45 && j > 20 && j < 38) {
mapMatrix[i,j] = 'T';
}
}
}
void InstatiateGrassField(int i, int j)
{
if (isGrassMatrixField(i,j))
{
Instantiate (grass, new Vector3 (i, 0, j), Quaternion.identity);
}
}
void InstantiateTreeField(int i, int j)
{
if (isTreeMatrixField(i,j)) {
Instantiate (tree, new Vector3 (i, 0, j), Quaternion.identity);
}
}
void InstantiateEnviroment()
{
for (int i = 0; i < NUMBER_OF_ROWS; i++)
for (int j = 0; j < NUMBER_OF_COLUMNS; j++)
{
//Instantiate a grass prefab
InstatiateGrassField(i, j);
//Instantiate a tree prefab
InstantiateTreeField(i, j);
}
}
void writeTextFile()
{
using (StreamWriter streamWriter = new StreamWriter (pathToFile))
{
for (int i = 0; i < NUMBER_OF_ROWS; i++)
{
for (int j = 0; j < NUMBER_OF_COLUMNS; j++)
{
streamWriter.Write (mapMatrix [i, j]);
//streamWriter.Write (' ');
}
streamWriter.WriteLine();
}
}
}
void readTextFile()
{
using (StreamReader streamReader = new StreamReader(pathToFile))
{
for (int i = 0; i < NUMBER_OF_ROWS; i++)
for (int j = 0; j < NUMBER_OF_COLUMNS; j++)
{
char karakter = (char)streamReader.Read ();
if (karakter == '\n')
{
karakter = (char)streamReader.Read ();
}
mapMatrix [i, j] = karakter;
}
}
}
}

Combining arrays created via multiple threads

I have been trying to create couple of 2-D arrays via multi-threading. Each threading will generate a small 2-D array. All of the 2-D will be consolidated and that is where I am having issue. I commented "//!this is causing error" towards the bottom of SimulatingMethod method. Please share your insight. Thank you.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ThreadExample
{
class Program
{
static void Main(string[] args)
{
double[,] randSims;
randSims = SimulatingClass.SimulatingMethod();
}
}
class SimulatingClass
{
public static double[,] SimulatingMethod()
{
int rowCount = 9;
int columnCount = 1;
int NumberOfCores = System.Environment.ProcessorCount;
int RowsForEachThread = rowCount / NumberOfCores;
Thread[] arrayOfThread = new Thread[NumberOfCores];
DataStuff[] dataStuff= new DataStuff[NumberOfCores];
for (int i = 0; i < NumberOfCores; i++)
{
dataStuff[i] = new DataStuff(RowsForEachThread, columnCount);
arrayOfThread[i] = new Thread(new ThreadStart(dataStuff[i].UpdateMatrixData));
arrayOfThread[i].Name = "Thread" + i;
arrayOfThread[i].Start();
}
for (int i = 0; i < NumberOfCores; i++)
{
arrayOfThread[i].Join();
}
//start combining arrays from different threads
var list = new List<double[,]>();
for (int m = 0; m < NumberOfCores; m++)
{
list.AddRange(dataStuff[m]); //!this is causing error
}
//trying to convert list back to array
double[,] array3 = list.ToArray(); //!this is causing error
return array3;
}
}
class DataStuff
{
public double G;
public double[,] M;
public long steps, trials;
public DataStuff(long _steps, long _trials)
{
M = new Double[_steps, _trials]; // <- M is created in the constructor
G = 60;
steps = _steps;
trials = _trials;
}
public void UpdateMatrixData()
{
for (int i = 0; i < steps; i++)
{
for (int j = 0; j < trials; j++)
{
M[i, j] = i + j;
}
}
}
}
}
You should specify the property as follows:
list.Add(dataStuff[m].M);
It's because the dataStuff[m] is of type DataStuff, but the type double[,] expected as the list item.
If I understood you correctly, you need a consolidated 2D array. Try to declare it initially with desired dimensions:
double[,] array3 = new double[rowCount, columnCount];
And copy data from dataStuff array to it after processing:
for (int m = 0; m < NumberOfCores; m++)
{
Array.Copy(dataStuff[m].M, 0, array3, m * columnCount * RowsForEachThread, dataStuff[m].M.Length);
}
return array3;
And you don't need list at all.
Please note, that you have possible problems related to the rounding:
int RowsForEachThread = rowCount / NumberOfCores;
You should handle the situation when the rowCount is not divisible by the NumberOfCores.

Categories

Resources