Я пытаюсь реализовать моделирование методом Монте-Карло в приложении формы C# с использованием Взвешенный быстрый союз с контуром пути. Во-первых, я беру gridSize
, а затем генерировать сетки равен gridSize * gridSize
и состоит из черного фона этикетки, которые представляют сайты, то я случайно союз некоторые сайты и сделать свой фон в белый цвет. Проблема в том, что всякий раз, когда я запускаю проект, я получаю все сайты в черном - независимо от того, сколько раз я пытаюсь -, но если бы я добавил точки останова и шаг за шагом, я получаю несколько белых сайтов по назначению !!!Странное поведение при реализации моделирования monte carlo в C#
Вот код:
public partial class Form1 : Form
{
int gridSize = 0;
byte siteSize = 50;
FlowLayoutPanel flowLayoutPanel;
UnionFind uf;
int randomFirstNumber;
int randomSecondNumber;
string labelName = string.Empty;
Random rnd = new Random();
int numberOfAttempts;
Label label;
HashSet<int> excludeHashSet = new HashSet<int>();
public Form1()
{
InitializeComponent();
}
private void setGridSizeButton_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(gridSizeTextbox.Text) && int.TryParse(gridSizeTextbox.Text, out gridSize))
{
if (gridSize > 0)
{
var flowLayoutPanel = createFlowLayoutPanelAndLabels();
setGridSizeButton.Enabled = false;
gridSizeTextbox.Enabled = false;
randomlyUnionSitesAndWhiteThem();
}
}
}
private void reset_Click(object sender, EventArgs e)
{
setGridSizeButton.Enabled = true;
gridSizeTextbox.Enabled = true;
gridSizeTextbox.Text = string.Empty;
flowLayoutPanel.Dispose();
excludeHashSet = new HashSet<int>();
gridSizeTextbox.Focus();
}
private FlowLayoutPanel createFlowLayoutPanelAndLabels()
{
flowLayoutPanel = new FlowLayoutPanel();
flowLayoutPanel.Name = "flowLayoutPanel";
flowLayoutPanel.Location = new Point(30, 60);
flowLayoutPanel.Size = new Size(gridSize, gridSize);
flowLayoutPanel.BorderStyle = BorderStyle.Fixed3D;
flowLayoutPanel.Width = siteSize * gridSize + 10 * gridSize;
flowLayoutPanel.Height = siteSize * gridSize + 10 * gridSize;
for (int i = 0; i < gridSize * gridSize; i++)
{
var label = new Label();
label.Text = "";
label.Name = i.ToString();
label.Width = siteSize;
label.Height = siteSize;
label.BackColor = Color.Black;
label.Margin = new Padding(3);
label.BorderStyle = BorderStyle.FixedSingle;
flowLayoutPanel.Controls.Add(label);
}
this.Controls.Add(flowLayoutPanel);
return flowLayoutPanel;
}
private void randomlyUnionSitesAndWhiteThem()
{
uf = new UnionFind(gridSize * gridSize);
numberOfAttempts = rnd.Next(0, gridSize * gridSize);
for (int i = 0; i < numberOfAttempts; i++)
{
randomFirstNumber = getRandomNumber(0, gridSize * gridSize, excludeHashSet);
randomSecondNumber = getRandomNumber(0, gridSize * gridSize, excludeHashSet);
labelName = uf.union(randomFirstNumber, randomSecondNumber).ToString();
if (Convert.ToInt16(labelName) > -1)
{
label = (Label)flowLayoutPanel.Controls.Find(labelName, false).First();
label.BackColor = Color.White;
excludeHashSet.Add(Convert.ToInt16(labelName));
}
}
}
private int getRandomNumber(int min, int max, HashSet<int> excludes)
{
int randomNumber;
do
{
var range = Enumerable.Range(min, max).Where(i => !excludes.Contains(i));
var rand = new Random();
int index = rand.Next(0, max - excludes.Count);
randomNumber = range.ElementAt(index);
}
while (excludes.Any(x => x == randomNumber));
return randomNumber;
}
}
И это мой Union
метод:
class UnionFind
{
.....
public int union(int firstNumber, int secondNumber)
{
firstNumber = getRoot(firstNumber);
secondNumber = getRoot(secondNumber);
if (firstNumber == secondNumber)
{
return -1;
}
if (sizes[firstNumber] < sizes[secondNumber])
{
array[firstNumber] = secondNumber;
sizes[secondNumber] += sizes[firstNumber];
return array[firstNumber];
}
else
{
array[secondNumber] = firstNumber;
sizes[firstNumber] += sizes[secondNumber];
return array[secondNumber];
}
}
.....
}
Итак, по существу Алекс был прав, даже если объяснение пропустило некоторые детали.И используя один экземпляр «Случайный» вместо нового, основанного на текущем времени, другой новый, основанный также на (неизмененном) текущем времени, кажется гораздо лучшим исправлением, чем произвольно выбранные задержки, чтобы предотвратить то же время от наблюдения дважды. – hvd