コード例 #1
0
ファイル: MainWindow.xaml.cs プロジェクト: lkempf/Bwinf-34-r2
		private void ResetCake()
		{
			if (SizeSlider == null || angleSlider == null || DrawingCanvas == null)
				return;

			cake = new Cake((int)Math.Round(SizeSlider.Value, 0), (float)angleSlider.Value);
			cake.Render(ref DrawingCanvas);

			if(timer?.Enabled ?? false)
				timer.Stop();
			generator?.Cancle();
			generator = null;
		}
コード例 #2
0
ファイル: Cake.cs プロジェクト: lkempf/Bwinf-34-r2
		//Ermöglicht es den besten gefundenen Kuchen threadsafe zu aktualisieren
		private async Task UpdateCake(Cake cake, float newScore)
		{
			if (cake == null)
				throw new TheCakeIsALieException();

			await Task.Run(() =>
			{
				lock (this.cake)
				{
					if (newScore > bestScore)
					{
						bestScore = newScore;
						this.cake = cake;
					}
				}
			});
		}
コード例 #3
0
ファイル: Cake.cs プロジェクト: lkempf/Bwinf-34-r2
		private void OptimizeInternal(object args)
		{
			//Argumente in sinnvolle Typen zurückverwandeln
			var argsTupel = (Tuple<int, int, CancellationToken>)args;
			int threadId = argsTupel.Item1;
			int iterations = argsTupel.Item2;
			var cancellationToken = argsTupel.Item3;

			var random = new Random();
			var cake = internalCakes[threadId];
			float lastScore = cake.CalculateScore();
			for (int i = 0; i < iterations; i++)
			{
				//Es muss nicht alles n-fach gezählt werden
				if (threadId == 0)
					globalIterations++;

				int randomCandle = random.NextDouble() >= 0.25 ? cake.NearestCandle : random.Next(NumberOfCandles);
				int newX, newY;
				int oldX = cake.Candles[randomCandle].X, oldY = cake.Candles[randomCandle].Y;
				int currentTries = 0;
				while (true)
				{
					i++;
					float cooldown = (float)Math.Min(Math.Ceiling(globalIterations / 10000d), 20);

					//Evolutionen die nicht erfolgsversprechend sind zerstören
					if (i != 0 && i % 10000 == 0) //Zeit für Selektion
					{
						if (bestScore * 0.9 > lastScore)
						{
							internalCakes[threadId] = cake = Cake.Clone();
							lastScore = bestScore;
						}
					}

					currentTries++;
					//Wenn eine Kerze nicht mehr weiter optimiert werden kann, dann wird eine andere genommen
					if (currentTries == 1000)
					{
						currentTries = 0;
						//Aus stucts in einer Liste wird by value zugegriffen -> Hacky workaround
						var tmp = cake.Candles[randomCandle];
						tmp.X = oldX; tmp.Y = oldY;
						cake.Candles[randomCandle] = tmp;
						randomCandle = random.Next(NumberOfCandles);
						oldX = cake.Candles[randomCandle].X;
						oldY = cake.Candles[randomCandle].Y;
					}

					newX = oldX + (int)(Math.Max(((cake.Size * 2) / cooldown) * random.NextDouble(), 1)  //Verschiebungsrange mit cooldown
						* 
						(random.NextDouble() >= 0.5 ? 1 : -1)); //Zufälliges Vorzeichen
					newY = oldY + (int)(Math.Max(((cake.Bounds.Height / 2) / cooldown) * random.NextDouble(), 1)
						* 
						(random.NextDouble() >= 0.5 ? 1 : -1));

					//Wenn eine ungültige Mutation erzeugt wird, dann wird sie nicht mitgezählt
					if (!cake.Contains(newX, newY))
					{
						i--;
						currentTries--;
						continue;
					}

					//Mal wieder der selbe Workaround
					var tmp2 = cake.Candles[randomCandle];
					tmp2.X = newX; tmp2.Y = newY;
					cake.Candles[randomCandle] = tmp2;

					//Abbruchbedingung
					if (cancellationToken.IsCancellationRequested || i >= iterations)
						break;

					if (cake.CalculateScore() > lastScore)
						break;
				}

				lastScore = cake.CalculateScore();
				if (cancellationToken.IsCancellationRequested)
				{
					//Es sollte sichergestellt werden, dass der Kuchen wirklich aktualisiert wird, wenn die Optimierung abgeschlossen ist
					//Sonst kann es sein, dass ein veralteter Kuchen gerendert wird
					UpdateCake(cake.Clone(), lastScore).GetAwaiter().GetResult();
					break;
				}

				//Es ist egal wann der beste Kuchen aktualisiert wird
				UpdateCake(cake.Clone(), lastScore);
			}
		}
コード例 #4
0
ファイル: Cake.cs プロジェクト: lkempf/Bwinf-34-r2
		public CakeGenerator(Cake cake, int degreeOfParallelization)
		{
			this.cake = cake;
			DegreeOfParallelization = degreeOfParallelization;
			NumberOfCandles = cake.Candles.Count;

			threads = new Thread[DegreeOfParallelization];
			internalCakes = new Cake[DegreeOfParallelization];

			for (int i = 0; i < DegreeOfParallelization; i++)
				internalCakes[i] = cake.Clone();

			//Workaround um zu verhindern das der Kuchen automatisch überschrieben wird
			globalIterations = 1;
		}
コード例 #5
0
ファイル: Cake.cs プロジェクト: lkempf/Bwinf-34-r2
		public CakeGenerator(int numberOfCandles, int degreeOfParallelization, int size, float angle, int colors)
		{
			//Spannende Zuweisungen
			NumberOfCandles = numberOfCandles;
			DegreeOfParallelization = degreeOfParallelization;
			Colors = colors;
			cake = new Cake(size, angle);

			threads = new Thread[DegreeOfParallelization];
			internalCakes = new Cake[DegreeOfParallelization];

			for (int i = 0; i < DegreeOfParallelization; i++)
				internalCakes[i] = cake.Clone();
		}
コード例 #6
0
ファイル: Cake.cs プロジェクト: lkempf/Bwinf-34-r2
		public Cake Clone() //Mache mehr Kuchen
		{
			var cake = new Cake(Size, Angle);
			cake.Candles.Capacity = Candles.Count;
			foreach (var candle in Candles)
				cake.Candles.Add(candle);
			return cake;
		}
コード例 #7
0
ファイル: MainWindow.xaml.cs プロジェクト: lkempf/Bwinf-34-r2
		private void OpenButton_Click(object sender, RoutedEventArgs e)
		{
			OpenFileDialog dialog = new OpenFileDialog();
			dialog.Filter = "Innovatives Dateiformat|*.json";
			dialog.CheckFileExists = true;
			dialog.ShowDialog();
			try
			{
				if (!File.Exists(dialog.FileName))
					return;
				var cake = JsonConvert.DeserializeObject<Cake>(File.ReadAllText(dialog.FileName));
				CandleCountSlider.Value = cake.Candles.Count;
				SizeSlider.Value = cake.Size;
				angleSlider.Value = cake.Angle;
				this.cake = cake;
				cake.Render(ref DrawingCanvas);
				generator = new CakeGenerator(cake, (int)Math.Round(ParallelizationSlider.Value, 0));
			}
			catch (JsonReaderException)
			{
				throw new TheCakeIsALieException();
			}
		}
コード例 #8
0
ファイル: MainWindow.xaml.cs プロジェクト: lkempf/Bwinf-34-r2
		private void OptimizationEndedCallback()
		{
			running = false;
			StartButton.Content = "Start";
			ProgressBar.IsIndeterminate = false;
			cake = generator.Cake;
			cake.Render(ref DrawingCanvas);
		}