In my current project I have an algorythm that generats data, this data will be shown in a Linechart, however the chart only updates once the algorythm has ended rather than after each "step".
private void simulate(share[] shares)
{
int k = 0;
Random r = new Random(); //random values just for testing
while (k < 10)//10 steps (10 values for each share)
{
for (int i = 0; i < shares.Length; i++)
{
shares[i].value = r.Next(0, 10000);//random a new value
shares[i].history.Add(shares[i].value);//add the value to the value history
}
//now update the chart so that it first shows only one x point than two and so on
drawchart(shares);
k++;
}
}
private void drawchart(share[] shares)
{
cHshares.Series.Clear();//clear the chart
for (int i = 0; i < shares.Length; i++)//for each share
{
cHshares.Series.Add(shares[i].name);//add a new share to the chart
cHshares.Series[shares[i].name].ChartType = SeriesChartType.FastLine;
int j = 0;
//draw the lines with each value that exists for each share
foreach (double value in shares[i].history)
{
cHshares.Series[shares[i].name].Points.AddXY(j, value);
j++;
}
}
}
Since I call the drawchart funktion every step why is it that it only shows after all steps are finished?
you have put your code in a loop like for loop
After each drawchart, update your chart. i.e.
drawchart(shares);
cHshares.Update();
k++;
I hope this will be useful.
Related
I have a textbox to write the position of an array and a textbox to write the value of that position. Every time I want to add a value and a position I click the button btnStoreValue
I created a function (CompareTwoNumbers) for another exercise that compares two numbers and returns the biggest
Using that function and avoiding the use of comparison characters like > and < I'm supposed to get the biggest value of the array
public partial class Form1 : ExerciseArray
{
int[] numbers = new int[10];
private int CompareTwoNumbers(int i, int j)
{
if (i < j)
{
return j;
}
return i;
}
private void btnBiggestValue_Click(object sender, EventArgs e)
{
//int n=1;
int counter = 0;
int highestPosition = CompareTwoNumbers(0, 1);
for(int i=0; i<10; i++){
//int j = CompareTwoNumbers(numbers[i], numbers[i+1])
//n = CompareTwoNumbers(numbers[n], numbers[i+1]
counter = CompareTwoNumbers(highestPosition, i);
}
txtBiggestValuePosition.Text= n.ToString();
txtBiggestValue.Text=numbers[n].ToString();
}
I've tried multiple things, using multiple variables, I tried to write it on paper to try to understand things better and I'm stuck. I don't know how is it possible to find that value using the function I created on the previous exercise (assuming the function I created is correct)
So, the core part of your question is that you want to know how to find the biggest number in an array using your helper function CompareTwoNumbers and then figure out what the value and position of the biggest number is.
Based on my understanding above, you have the framework almost set up correctly.
First off, CompareTwoNumbers should be updated to return a bool. Doing this will let you conditionally update your variables holding the biggest number value and position.
private int CompareTwoNumbers(int i, int j)
{
if (i < j)
{
return true;
}
return false;
}
To know what the largest value in an (unsorted) array is, you will need to iterate through every value. While doing so, you need to keep track of the value and position of the biggest value, only updating it when a bigger value is found.
private void btnBiggestValue_Click(object sender, EventArgs e)
{
// Store the bigget number's index and value
// We start with the first index and corresponding
// value to give us a starting point.
int biggestNumberIndex = 0;
int biggestNumber = numbers[0];
// Iterate through the array of numbers to find
// the biggest number and its index
for(int i=0; i<10; i++)
{
// If the current number is larger than the
// currently stored biggest number...
if(CompareTwoNumbers(biggestNumber, numbers[i])
{
// ...then update the value and index with
// the new biggest number.
biggestNumber = number[i];
biggestNumberIndex = i;
}
}
// Finally, update the text fields with
// the correct biggest value and biggest
// value position.
txtBiggestValuePosition.Text= biggestNumberIndex.ToString();
txtBiggestValue.Text=numbers[biggestNumberIndex].ToString();
}
This uses a Tuple to give you both the max index and max value from the same method:
public (int, int) FindMaxValue(int[] items)
{
int maxValue = items[0];
int maxIndex = 0;
for(int i=1;i<items.Length;i++)
{
if (items[i] > maxValue)
{
maxValue = items[i];
maxIndex = i;
}
}
return (maxIndex, maxValue);
}
So I'm currently working on a project for my C# class where we have to recreate Minesweeper using the Console. I'm fairly new to C# but have worked with other code languages before so I've been able to sort out most problems. The newest one i'm having is I've made two functions (one that creates cells and stores them in a list, the other to print them in a grid pattern), one of them works (GenerateCells) but the other doesn't output anything when ran.
//PrintGrid Function
public static void PrintGrid(int gsize, List<Cell> cells)
{
for (int x = 0; x > gsize; x++)
{
//testing output
Console.WriteLine(cells[0].Name);
}
}
class Program
{
static void Main(string[] args) {
//Set Default Grid Size
int gsize = 6;
//Create List of Cells
var cells = new List<Cell>
{
//Generate "Ghost Cell" preventing exception
new Cell { Name = "Ghost Cell", XCord = 0, YCord = 0 }
};
//Generate Cells for grid
Cell.GenerateCells(gsize, cells);
//Print Cells in grid
Cell.PrintGrid(gsize, cells);
}
}
I'm not sure what I'm doing wrong since there are no errors that pop up. All I can figure is I've either called it wrong or set up the method wrong, but I can't figure it out. Any and all help is appreciated.
You just have '>' instead of '<'. So this is what it should look like:
public static void PrintGrid(int gsize, List<Cell> cells)
{
for (int x = 0; x < gsize; x++)
{
//testing output
//This one has to have the index instead of 0.
Console.WriteLine(cells[x].Name);
}
}
So I am trying to figure out why filling sudoku board in order of how I generate fields is many times faster then filling it which shuffled order, and I can't come to any reasonable conclusions.
Speed of filling and checking should be about the same no matter if fields are shuffled or not, only noticeable difference is the fact that filling boxes in a shuffled order causes the main loop to easily go for 60.000.000+ iterations not sure how many on average as I am not patient enough to check. And filling them in order of how they were generated gets finished in usually < 1.000 iterations rarely going over it and basically never going over 5.000.
I do understand that code doesn't follow C# standards too strictly but it's a project I am supposed to make and it's not my main language there are probably some possible optimizations but it's not what I am interested in all i want to know why shuffling the order of fill the boxes causes the process to take this much longer.
Edit: forgot to attach order of creating/filling boxes order of filling/creating boxes:
Edit2: more concise rephrased question:
The question is why generating an valid fully filled sudoku board in order from image creates a lot less invalid boards from which there is required backtracking, as compared to generating a board in a random order of choosing fields?
example of random order
Here is the code used for the project https://github.com/Piterm21/sudoku
And here are all the parts used in generation.
filledBox class:
public class filledBox
{
public int textBoxIndex;
public int value;
public int nextIndexToTry;
public int[] values;
public int lineIndex;
public int columnIndex;
public int groupIndex;
}
Here is a main loop:
filledBox[] boxes = this.shuffleBoxesCreateCheckingLists();
long iter = 0;
int nextIndexToFill = 0;
while (nextIndexToFill != 81) {
for (; boxes[nextIndexToFill].nextIndexToTry < 9; boxes[nextIndexToFill].nextIndexToTry++) {
// check if is valid
if (!createsError(boxes[nextIndexToFill])) {
boxes[nextIndexToFill].value = boxes[nextIndexToFill].values[boxes[nextIndexToFill].nextIndexToTry];
nextIndexToFill++;
break;
}
if (boxes[nextIndexToFill].nextIndexToTry == 8) {
boxes[nextIndexToFill].nextIndexToTry = 0;
boxes[nextIndexToFill].value = 0;
nextIndexToFill--;
boxes[nextIndexToFill].nextIndexToTry++;
while (boxes[nextIndexToFill].nextIndexToTry == 9) {
boxes[nextIndexToFill].nextIndexToTry = 0;
boxes[nextIndexToFill].value = 0;
nextIndexToFill--;
boxes[nextIndexToFill].nextIndexToTry++;
}
break;
}
}
iter++;
}
System.Diagnostics.Debug.WriteLine(iter);
Generation of boxes with setting of lists used for checking for errors:
List<filledBox>[] generationLines;
List<filledBox>[] generationColumns;
List<filledBox>[] generationGroups;
public filledBox[] shuffleBoxesCreateCheckingLists()
{
filledBox[] boxes = new filledBox[81];
for (int i = 0; i < 81; i++) {
boxes[i] = new filledBox();
boxes[i].values = new int[9]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
boxes[i].values = shuffle(boxes[i].values, true);
}
generationLines = new List<filledBox>[9];
generationColumns = new List<filledBox>[9];
generationGroups = new List<filledBox>[9];
for (int i = 0; i < 9; i++) {
generationLines[i] = new List<filledBox>();
generationColumns[i] = new List<filledBox>();
generationGroups[i] = new List<filledBox>();
}
int boxIndex = 0;
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
for (int innerY = 0; innerY < 3; innerY++) {
for (int innerX = 0; innerX < 3; innerX++) {
int subPanelIndex = x + y * 3;
int lineIndex = innerY + y * 3;
int columnIndex = innerX + x * 3;
boxes[boxIndex].textBoxIndex = boxIndex;
boxes[boxIndex].groupIndex = subPanelIndex;
boxes[boxIndex].columnIndex = columnIndex;
boxes[boxIndex].lineIndex = lineIndex;
boxes[boxIndex].nextIndexToTry = 0;
boxes[boxIndex].value = 0;
generationLines[lineIndex].Add(boxes[boxIndex]);
generationColumns[columnIndex].Add(boxes[boxIndex]);
generationGroups[subPanelIndex].Add(boxes[boxIndex]);
boxIndex++;
}
}
}
}
#if !fast
boxes = shuffle(boxes);
#endif
return boxes;
}
Shuffling code:
public T[] shuffle<T> (T[] array)
{
int i = array.Length;
while (i > 1) {
i--;
int j = rnd.Next(0, i - 1);
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
And code responsible for checking for errors:
public bool hasError (List<filledBox> list, filledBox box)
{
bool result = false;
foreach (filledBox filledBoxToCheck in list) {
if (filledBoxToCheck.value == box.values[box.nextIndexToTry]) {
if (box.lineIndex != filledBoxToCheck.lineIndex ||
box.columnIndex != filledBoxToCheck.columnIndex) {
result = true;
break;
}
}
}
return result;
}
public bool createsError (filledBox box)
{
bool result = false;
if (hasError(generationGroups[box.groupIndex], box)) {
result = true;
} else if (hasError(generationLines[box.lineIndex], box)) {
result = true;
} else if (hasError(generationColumns[box.columnIndex], box)) {
result = true;
}
return result;
}
The reason the shuffled order of visiting boxes is worse is that, for the first few boxes, you've increased the odds of filling them in independently. I'm calling a 3x3 region a box. You could visit each little square randomly, but I'll confine my analysis to fillng in one 3x3 box at a time. It should illustrate the problem.
Lets assume, whether you used the in-order or random method, you filled in the top left box first.
VISITING BOXES IN ORDER:
Now consider filling in the box next to it, that is, the top middle box. Just look at filling in the top row of that box, there are 6x5x4 = 120 ways to fill it in.
VISITING BOXES RANDOMLY:
Now consider instead choosing any box to fill in next. If you happen to choose a box that is not in the top row or left column, filling it in is unaffected by the way the first box was filled. The top row of that box can be filled in 9x8x7 = 504 ways.
Taking this further, if you fill in the boxes sequentially, say, across the top, the third box (the top right one), begins with only 3x2x1 = 6 ways to fill in the top row of it. Whereas, if you select the next box randomly, you might, at worst, select a box that is not in the same row or column of either of the first 2 boxes, which means that the top row of that box has yet again 9x8x7 = 504 ways of being filled in.
If you tried randomly selecting the order for each little square to be filled in, the first few might all be in different rows and columns. At worst, none of the first 9 squares will align meaning there will be 9^9 = 387,420,489 options. But filling them in across the top row, the choices are guaranteed to be 9! = 362,880.
This illustrates one of the strategies for how to approach backtracking. Ideally, you first solve parts of the problem that most tightly constrain the rest of the problem. For some problems sequential is better, and for some random is better.
im frenchi so sorry first sorry for my english .
I have an error on visual studio (index out of range) i have this problem only with a Parallel.For not with classic for.
I think one thread want acces on my array[i] and another thread want too ..
It's a code for calcul Kmeans clustering for building link between document (with cosine similarity).
more information :
IndexOutOfRange is on similarityMeasure[i]=.....
I have a computer with 2 Processor (12logical)
with classic for , cpu usage is 9-14% , time for 1 iteration=9min..
with parallel.for , cpu usage is 70-90% =p, time for 1 iteration =~1min30
Sometimes it works longer before generating an error
My function is :
private static int FindClosestClusterCenter(List<Centroid> clustercenter, DocumentVector obj)
{
float[] similarityMeasure = new float[clustercenter.Count()];
float[] copy = similarityMeasure;
object sync = new Object();
Parallel.For(0, clustercenter.Count(), (i) => //for(int i = 0; i < clustercenter.Count(); i++) Parallel.For(0, clustercenter.Count(), (i) => //
{
similarityMeasure[i] = SimilarityMatrics.FindCosineSimilarity(clustercenter[i].GroupedDocument[0].VectorSpace, obj.VectorSpace);
});
int index = 0;
float maxValue = similarityMeasure[0];
for (int i = 0; i < similarityMeasure.Count(); i++)
{
if (similarityMeasure[i] > maxValue)
{
maxValue = similarityMeasure[i];
index = i;
}
}
return index;
}
My function is call here :
do
{
prevClusterCenter = centroidCollection;
DateTime starttime = DateTime.Now;
foreach (DocumentVector obj in documentCollection)//Parallel.ForEach(documentCollection, parallelOptions, obj =>//foreach (DocumentVector obj in documentCollection)
{
int ind = FindClosestClusterCenter(centroidCollection, obj);
resultSet[ind].GroupedDocument.Add(obj);
}
TimeSpan tempsecoule = DateTime.Now.Subtract(starttime);
Console.WriteLine(tempsecoule);
//Console.ReadKey();
InitializeClusterCentroid(out centroidCollection, centroidCollection.Count());
centroidCollection = CalculMeanPoints(resultSet);
stoppingCriteria = CheckStoppingCriteria(prevClusterCenter, centroidCollection);
if (!stoppingCriteria)
{
//initialisation du resultat pour la prochaine itération
InitializeClusterCentroid(out resultSet, centroidCollection.Count);
}
} while (stoppingCriteria == false);
_counter = counter;
return resultSet;
FindCosSimilarity :
public static float FindCosineSimilarity(float[] vecA, float[] vecB)
{
var dotProduct = DotProduct(vecA, vecB);
var magnitudeOfA = Magnitude(vecA);
var magnitudeOfB = Magnitude(vecB);
float result = dotProduct / (float)Math.Pow((magnitudeOfA * magnitudeOfB),2);
//when 0 is divided by 0 it shows result NaN so return 0 in such case.
if (float.IsNaN(result))
return 0;
else
return (float)result;
}
CalculMeansPoint :
private static List<Centroid> CalculMeanPoints(List<Centroid> _clust)
{
for (int i = 0; i < _clust.Count(); i++)
{
if (_clust[i].GroupedDocument.Count() > 0)
{
for (int j = 0; j < _clust[i].GroupedDocument[0].VectorSpace.Count(); j++)
{
float total = 0;
foreach (DocumentVector vspace in _clust[i].GroupedDocument)
{
total += vspace.VectorSpace[j];
}
_clust[i].GroupedDocument[0].VectorSpace[j] = total / _clust[i].GroupedDocument.Count();
}
}
}
return _clust;
}
You may have some side effects in FindCosineSimilarity, make sure it does not modify any field or input parameter. Example: resultSet[ind].GroupedDocument.Add(obj);. If resultSet is not a reference to locally instantiated array, then that is a side effect.
That may fix it. But FYI you could use AsParallel for this rather than Parallel.For:
similarityMeasure = clustercenter
.AsParallel().AsOrdered()
.Select(c=> SimilarityMatrics.FindCosineSimilarity(c.GroupedDocument[0].VectorSpace, obj.VectorSpace))
.ToArray();
You realize that if you synchronize the whole Content of the Parallel-For, it's just the same as having a normal synchrone for-loop, right? Meaning the code as it is doesnt do anything in parallel, so I dont think you'll have any Problems with concurrency. My guess from what I can tell is clustercenter[i].GroupedDocument is propably an empty Array.
Hi I’m fairly new to c# programming so please bear with me. I’m currently working on a “simple” little program which allows the user to enter 25 values into the same text box and once this has been done I want to be able to display this 25 values in a list box as an array of 5 row by 5 column and I want to find out the largest number in the array.
private void button1_Click(object sender, EventArgs e)
{
int arrayrows = 5;
int arraycolomns = 5;
int[,] arraytimes;
arraytimes = new int[array rows, array columns];
// list_Matrix.Items.Add(tb_First.Text);
for (int i = 0; i != 5; i++)
{
for (int j = 0; j != 5; j++)
{
array times [i,j]= Convert. To Int32(Tb_First.Text);
list_Matrix.Items.Add(array times[i, j].To String());
}
}
}
This is what I've tried for displaying the array in a list box, but it isn't working. This also prevents me from moving to the next section of finding the largest number among them.
You can split your string using .Split(' ') (or any other character or string). This will give you a onedimensional array with 25 elements (if everything was entered). The trick to converting that into a twodimensional array or grid is to use integer division and modulo, the following code would to
String[] splitText = textBox.Text.Split(' '); //gets your 25-length 1D array
//make an empty grid with the right dimensions first
int[][] grid = new int[5][];
for (int i=0;i<5;i++) {
grid[i] = new int[5];
}
//save our highest value
int maxVal = 0;
//then fill this grid
for (int i=0;i<splitText.Length;i++){
int value = int.Parse(splitText[i]);
//i%5 gives us values from 0 to 4, which is our 'x-coordinate' in the grid
//i/5 uses integer division so its the same as Math.floor(i/5.0), giving us your 'y-coordinates'
grid[i%5][i/5] = value;
//check if this value is larger than the one that is currently the largest
if (value > maxVal)
{
maxVal = value;
}
}
This will fill the twodimensional grid array with the split textbox text, and if there are not enough values in the textbox it leaves a 0 in those cells.
At the end you will also have your maximum value.
Try the following (shows by printing the numbers as string). and assuming you enter the numbers in the following way,
'1,2,3,4...'
string[] nums=txtBox.Text.Split(',');
lstBox.Items.Clear();
int colCount=5;
int colIndex=0;
string line="";
foreach(string num in nums)
{
if(colIndex==colCount)
{
lstBox.Items.Add(line);
line="";
colIndex=0;
}
line+= line==""? num : " "+num;
colIndex+=1;
}
if(line!="")
lstBox.Items.Add(line);
Make sure to correct any syntax mistakes, and to change the parameter names to yours.
private void button1_Click(object sender, EventArgs e)
{
int[] ab=new int[10];
string s = textBox1.Text;
int j = 0;
string [] a = (s.Split(' '));
foreach (string word in a)
{
ab[j] = Convert.ToInt32(word);
j++;
}
for (int i = 0; i < 10; i++)
{
label2.Text +=ab[i].ToString()+" ";
}
}