public object Clone() { var newObj = new Gene(this.body.Length); newObj.points = points; newObj.keyValList = keyValList.ToList(); newObj.body = (int[]) body.Clone(); return newObj; }
private void SimpleMutation(List<Gene> result, Gene gene) { var count = (int)(_random.NextDouble() * 10) + 1; for (int n = 0; n < count; n++) { int pos = (int)(_random.NextDouble() * (gene.body.Length - 2)) + 1; gene.body[pos] = 1 - gene.body[pos]; // zmiana 0 na 1 i odwrotnie } gene.points = genePointsValue(gene); result.Add(gene); }
private void OneHalfCrossPoint(List<Gene> result, Gene first, Gene second, int firstBodyLen, int secondBodyLen) { int crossPoint = (int)(_random.NextDouble() * (secondBodyLen - 1) + 1); Gene firstCrossedGene = new Gene(firstBodyLen + (secondBodyLen - crossPoint)); Gene secondCrossedGene = new Gene(crossPoint + 1); Array.Copy(first.body, firstCrossedGene.body, 0); Array.Copy(second.body, crossPoint, firstCrossedGene.body, firstBodyLen, (secondBodyLen - crossPoint)); Array.Copy(second.body, secondCrossedGene.body, crossPoint + 1); secondCrossedGene.body[crossPoint] = 1; firstCrossedGene.points = genePointsValue(firstCrossedGene); result.Add(firstCrossedGene); secondCrossedGene.points = genePointsValue(secondCrossedGene); result.Add(secondCrossedGene); }
private void NoCutsChangeMutation(List<Gene> result, Gene gene) { int first_pos = (int)(_random.NextDouble() * (gene.body.Length - 2)) + 1; int second_pos = (int)(_random.NextDouble() * (gene.body.Length - 2)) + 1; gene.body[first_pos] = 1 - gene.body[first_pos]; // zmiana 0 na 1 i odwrotnie gene.body[second_pos] = 1 - gene.body[second_pos]; // zmiana 0 na 1 i odwrotnie gene.points = genePointsValue(gene); result.Add(gene); }
private void JoinCrossing(List<Gene> result, Gene first, Gene second, int firstBodyLen, int secondBodyLen) { var lenghtVal = firstBodyLen + secondBodyLen - 1; Gene crossedGene = new Gene(lenghtVal); first.body.CopyTo(crossedGene.body, 0); second.body.CopyTo(crossedGene.body, first.body.Length - 1); // nadpisujemy ostatnia jedynke - ciecie crossedGene.points = genePointsValue(crossedGene); result.Add(crossedGene); }
private void IncrementCutsMutation(List<Gene> result, Gene gene, int gene_cuts) { if (gene_cuts < gene.body.Length - 2) // jesli istnieje przynajmniej jedno "0" { for (var ni = 0; ni < try_n_times; ni++) // probuj kilka razy { int pos = (int)(_random.NextDouble() * (gene.body.Length - 2)) + 1; if (gene.body[pos] == 0) { gene.body[pos] = 1; gene.points = genePointsValue(gene); break; } } } result.Add(gene); }
private List<Gene> generatePopulation2() { int pos1, pos2; for (int i = 0; i < _populationSize; i++) { int ok = 0; if (segments.Count > 1) { do { pos1 = (int)(_random.NextDouble() * segments.Count); pos2 = (int)(_random.NextDouble() * segments.Count); if (pos1 != pos2) { foreach (var el in segments) { if (el == segments[pos1] + segments[pos2]) { ok = 1; Gene gene = new Gene(el + 1); gene.body[segments[pos1]] = 1; gene.points = genePointsValue(gene); startPop.Add(gene); break; } } } else // wylosowano 2 razy ten sam element, losuj dalej ok = 0; } while (ok == 0); } else // nie losuj, jest tylko 1 element { Gene gene = new Gene(segments[0] + 1); gene.points = genePointsValue(gene); startPop.Add(gene); } } return startPop; }
private int genePointsValue(Gene gene_to_evaluate) { List<int> cuts = new List<int>(); List<int> gene_segments = new List<int>(); List<int> temp_gene_segments = new List<int>(); List<int> temp_segments = segments.Where(e => true).ToList(); for (int i = 0; i < gene_to_evaluate.body.Length; i++) { if (gene_to_evaluate.body[i] == 1) { cuts.Add(i); } } int cutsCount = cuts.Count; for (int i = 0; i < cutsCount - 1; i++) { for (int j = i + 1; j < cutsCount; j++) { gene_segments.Add(cuts[j] - cuts[i]); temp_gene_segments.Add(cuts[j] - cuts[i]); } } int points = 0; int gs_count = gene_segments.Count; // jesli prawidlowa sekwencja to temp_gene_segments powinno byc puste a temp_segments jak najmneij elementów (zostana tylko FP) for (int i = 0; i < gs_count; i++) { if (temp_segments.Contains(gene_segments[i])) { temp_segments.Remove(gene_segments[i]); points++; temp_gene_segments.Remove(gene_segments[i]); } } //maxCurrentK = Gene.calculateMaxCutsFromCurrentData(gs_count); var gte_len = gene_to_evaluate.body.Length; if (gte_len - 1 > maxSegment) // kara za przekroczenie dlugosci points -= (int)((gte_len - maxSegment)* _random.NextDouble()); var tgs_count = temp_gene_segments.Count; if (tgs_count != 0) { points -= (int)((tgs_count) * maxK); } else gene_to_evaluate.isValid = true; var gte_count = gene_to_evaluate.CountCuts(); if (gte_count > maxK) points -= (gte_count - maxK);// +(int)(maxK * _random.NextDouble()); return points; }
private void DecrementCutsMutation(List<Gene> result, Gene gene) { for (var ni = 0; ni < try_n_times; ni++) // probuje kilka razy { int pos = (int)(_random.NextDouble() * (gene.body.Length - 2)) + 1; if (gene.body[pos] == 1) { gene.body[pos] = 0; gene.points = genePointsValue(gene); break; } } result.Add(gene); }
private void CrossMutation(List<Gene> result, Gene gene) { var gene_len = gene.body.Length; Gene crossedGene = new Gene(gene_len + 1); // wiekszy o jeden int pos = (int)(_random.NextDouble() * (gene_len - 2)) + 1; Array.Copy(gene.body, pos, crossedGene.body, 1, (gene_len - pos)); Array.Copy(gene.body, 1, crossedGene.body, gene_len - pos + 1, pos - 1); crossedGene.body[0] = 1; crossedGene.body[gene_len] = 1; crossedGene.points = genePointsValue(crossedGene); result.Add(crossedGene); }
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker bgw = sender as BackgroundWorker; // inicjalizacja populacji v1.0 /*for (int i = 0; i < _populationSize; i++) { int val = (int)(_random.NextDouble() * segments.Count); Gene gene = new Gene(segments[val] + 1); gene.points = genePointsValue(gene); genes.Add(gene); //Invoke(new Action(() => listView1.Items.Add(gene.PrintBody() + " " + gene.points.ToString()))); //listView2.Items.Add(genes[i].CountCuts().ToString()); }*/ // inicjalizacja populacji v2.0 genes = generatePopulation2(); for (int generation = 0; generation < maxGenerationCount; generation++) { List<Gene> GenerationGeneList = new List<Gene>(); int maxGenePoint = -10000; for (int j = 0; j < _populationSize - _takeBestCount; j++) { List<Gene> result = new List<Gene>(); double val = _random.NextDouble(); //losujem 2 dowolne geny int one = (int)(_random.NextDouble() * _populationSize); int two = (int)(_random.NextDouble() * _populationSize); Gene first = (Gene)genes[one].Clone(); Gene second = (Gene)genes[two].Clone(); int firstBodyLen = first.body.Length; int secondBodyLen = second.body.Length; if (val < _crossingRatio) // krzyzowanie { var crossingType = _random.NextDouble(); // jednopunktowe losowe if (crossingType < 0.5 && firstBodyLen > 2 && secondBodyLen > 2) OneCrossPoint(result, first, second, firstBodyLen, secondBodyLen); // jednopunktowe polowkowe else if (crossingType >= 0.6 && crossingType < 0.95 && firstBodyLen > 2 && secondBodyLen > 2) OneHalfCrossPoint(result, first, second, firstBodyLen, secondBodyLen); // polacz oba geny else JoinCrossing(result, first, second, firstBodyLen, secondBodyLen); } // nie krzyzuj else { } int points1 = first.points; int points2 = second.points; if (val < _mutationRatio) //mutacja { Gene gene; if (points1 > points2) gene = first; else gene = second; int gene_cuts = gene.CountCuts(); // za duzo ciec, zmniejszamy k przez mutacje if (gene_cuts > maxK) DecrementCutsMutation(result, gene); else if (gene_cuts == maxK) { double mut_type = _random.NextDouble(); // utrzymujemy ta sama liczbe ciec if (mut_type < 0.33) NoCutsChangeMutation(result, gene); // zmniejszamy liczbe ciec else DecrementCutsMutation(result, gene); } else // za malo ciec, zwiekszamy k przez mutacje { double mut_type = _random.NextDouble(); if (mut_type < 0.5) IncrementCutsMutation(result, gene, gene_cuts); else if (mut_type >= 0.5 && mut_type < 0.9) NoCutsChangeMutation(result, gene);//SimpleMutation(result, gene); // mutuj poprzez zamiane else CrossMutation(result, gene); } } if (result.Count == 0) // nie bylo ani mutacji ani krzyzowania { if (points1 > points2) { Array.Reverse(first.body); result.Add(first); } else { Array.Reverse(second.body); result.Add(second); } } // wybieramy najlepszy gen z rezultatow int resCount = result.Count; if (resCount > 1) { for (int n = 0; n < resCount; n++) { int points = result[n].points; if (maxGenePoint < points && result[n].isValid == true) maxGenePoint = points; } result = result.OrderByDescending(item => item.points).ToList(); if (result[1].points >0) otherResults.Add(result[1]); } else { int points = result[0].points; if (maxGenePoint < points) maxGenePoint = points; } // najlepszy wynik dodajemy do glownej listy GenerationGeneList.Add(result[0]); } genes = genes.OrderByDescending(item => item.points).ToList(); for (int j = 0; j < _takeBestCount; j++) { GenerationGeneList.Add(genes[j]); // dodanie 3 najlepszych z poprzedniego pokolenia } // utworzenie listy populacji dla nastepnego kroku genes = GenerationGeneList; genes = genes.OrderByDescending(item => item.points).ToList(); var bestGene = genes[0]; var bestVal = bestGene.points; maxValues.Add(bestVal); var restartVal = (int)(20000 / maxPointsFromData); if (restartVal < 5) restartVal = 5; int tmpTrackBarVal = 0; if (bestGene.isValid == true) { bestValidGene = bestGene; if (bestValidGenes.Count == 0) { bestValidGenes.Add(bestValidGene); } else if (bestValidGenes.Last().points < bestValidGene.points && !bestValidGenes.Any(item => item.body == bestValidGene.body)) { bestValidGenes.Add(bestValidGene); Invoke(new Action(() => resultsListView.Items.Add("P: "+ bestValidGene.points.ToString() + ", c: " + bestValidGene.CountCuts().ToString() + ", t: " + totalSecondLabelCount.Text + "[sek]"))); } } Invoke(new Action(() => { tmpTrackBarVal = trackBar1.Value; label2.Text = "Punkty: " + bestVal.ToString(); if (bestValidGene != null) { label1.Text = bestValidGenes.Last().PrintBody(); label6.Text = "Długość: " + (bestValidGenes.Last().body.Count() - 1).ToString(); label8.Text = "Zapis zbioru: " + bestValidGenes.Last().PrintBodyAsSet(); label10.Text = "Liczba ciec: " + bestValidGenes.Last().CountCuts().ToString(); } label9.Text = "maxK: " + maxK.ToString(); label13.Text = "Restart po: " + restartVal.ToString(); toolStripProgressBar1.Increment(1); refreshPlotGraph(maxValues); })); updateTime(); if ((generation % restartVal) == (restartVal - 1)) { bool needChanges = checkIfNoChanges(restartVal - 1); if (needChanges) { addToResultsNewGenes3(genes); //////////////////////////////////////////////////////////////////////// } } if (maxGenePoint >= tmpTrackBarVal || bgw.CancellationPending) { if (bgw.CancellationPending) e.Cancel = true; Invoke(new Action(() => button1.Enabled = false)); break; } } Invoke(new Action(() => { if (bestValidGenes.Count > 0) { int bestVG = bestValidGenes.Last().CountCuts(); label17.Text = _optimalK.ToString(); label15.Text = bestVG.ToString(); label14.Text = Decimal.Round((decimal)bestVG / _optimalK * 100, 2).ToString() + " %"; } else { label17.Text = _optimalK.ToString(); label15.Text = "Brak rozwiązania"; label14.Text = Decimal.Round((decimal)0 / _optimalK * 100, 2).ToString() + " %"; } toolStripStatusLabel1.Text = "Obliczenia zakończono."; toolStripProgressBar1.Value = 0; beepPing(); })); }
private void addToResultsNewGenes4(List<Gene> genes) { var g = bestValidGenes.Count - 1; int count = 0; if (g > -1) { Gene gene = (Gene)bestValidGenes[g].Clone(); int cuts = gene.CountCuts(); int size = gene.body.Length; Array.Reverse(gene.body); for (int i = 1; (i < size - 1) && (count < _populationSize); i++) { if (gene.body[i] == 1) { Gene tmpGene = new Gene(i+1); Array.Copy(gene.body, 0, tmpGene.body, 0, i + 1); tmpGene.points = genePointsValue(tmpGene); genes[count++] = tmpGene; tmpGene = new Gene(size - i); Array.Copy(gene.body, i, tmpGene.body, 0, size - i); tmpGene.points = genePointsValue(tmpGene); genes[count++] = tmpGene; } } } }