public static void MutationOrder(Osob osob, int N, int M, List <int> stockW, List <int> orderW) //мутация по клиенту { Random rand = new Random(); int num = rand.Next(osob.osob.Count); //выбор гена над которым будет мутация int bit = rand.Next(7); //выбор мутирующего бита int ord1 = osob.osob[num].order; //номер клиента до мутации int ord2; //номер клиента после мутации int y = osob.osob[num].order * (255 / M); //представление числа в размере 0-255 int z = Convert.ToInt32(Convert.ToString(y, 2)); //перевод в двоичную систему // sw.WriteLine(z); int res = InvertBit(z, bit); //инвертируем выбранный бит ord2 = ConvertToDec(res.ToString()) / (255 / M); //новый номер клиента для этого гена StreamWriter sw; FileInfo fi = new FileInfo("pract.txt"); if (ord1 != ord2) { int i = osob.osob[num].stock; //osob.osob.Count()/N*i-M+ord2 номер склада в выбранном гене int test; test = M * i + ord2; sw = fi.AppendText(); sw.WriteLine("Столбец " + ord1 + " и " + ord2 + " строка " + i + " Элементы:" + num + " " + test); sw.Close(); if ((osob.osob[num].size == 0) && (osob.osob[test].size != 0)) //если размер гена 0, а у второго нет, то меняем их местами, чтобы не было два нуля, когда нулем заменяем число. { int tm = num; num = test; test = tm; tm = ord2; ord2 = ord1; ord1 = tm; } int prov = orderW[ord2]; if (orderW[ord2] >= osob.osob[num].size) //если запрос клиента >= передаваемому размеру { osob.osob[test].size = osob.osob[num].size; //вставляем в х ген размер мутировавшего osob.osob[num].size = 0; sw = fi.AppendText(); sw.WriteLine("Столбец " + ord1 + " и " + ord2 + " строка " + i + " Элементы:" + num + " " + test); sw.Close(); osob.additionMutO(stockW, orderW, N, M, i, ord1, ord2); } else { osob.osob[test].size = orderW[ord2]; osob.osob[num].size -= orderW[ord2]; //вычтем на величину перенесенную sw = fi.AppendText(); sw.WriteLine("**Столбец " + ord1 + " и " + ord2 + " строка " + i); sw.WriteLine("Запрос клиента меньше, чем предлагалось переместить в клетку"); //т.е. в мутировавшей клетке остаток sw.Close(); osob.additionMutO(stockW, orderW, N, M, i, ord1, ord2); } } }
public bool SequenceEquals(Osob osb) { for (int i = 0; i < osb.osob.Count; i++) { if (osb.osob[i].size != this.osob[i].size) { return(false); //break; } } return(true); }
List <int> SumStr(Osob osob) { int sum; List <int> sumStr = new List <int>(); for (int i = 0; i < N; i++) { sum = 0; for (int j = 0; j < osob.osob.Count; j++) { if (osob.osob[j].stock == i) { sum = sum + osob.osob[j].size; } } sumStr.Add(sum); } return(sumStr); }
public static void MutationStock(Osob osob, int N, int M) //мутация по складу { Random rand = new Random(); int num = rand.Next(osob.osob.Count); //выбор гена над которым будет мутация int bit = rand.Next(7); //выбор мутирующего бита int stk1 = osob.osob[num].stock; int stk2; int z = Convert.ToInt32(Convert.ToString(osob.osob[num].stock, 2)); int res = InvertBit(z, bit); //инвертируем выбранный бит stk2 = ConvertToDec(res.ToString()); //новый номер склада для этого гена if (stk1 != stk2) { int j = osob.osob[num].order; int x = osob.osob.Count / N * stk2 + j - 1; osob.osob[x].size += osob.osob[num].size; //перекидываем на другой склад товар osob.osob[num].size = 0; //обнуляем товар у этого склада //пересчитваем особь } }
void PrintOsob(Osob osob) { StreamWriter sw; FileInfo fi = new FileInfo(path); sw = fi.AppendText(); for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { richTextBox1.Text += osob.osob[M * i + j].size + " "; sw.Write(osob.osob[M * i + j].size + " "); } richTextBox1.Text += "\n"; sw.WriteLine(); } sw.Write("Стоимость перевозки по данному маршруту: " + osob.cost(MatrVesov)); richTextBox1.Text += "Стоимость перевозки по данному маршруту: " + osob.cost(MatrVesov); richTextBox1.Text += "\n"; sw.WriteLine(); sw.Close(); }
private void button1_Click(object sender, EventArgs e) { button2.Enabled = false; N = Convert.ToInt32(textBox1.Text); //количество складов - A сверху вних M = Convert.ToInt32(textBox2.Text); //количество потребителей - В слева направо cros = Convert.ToInt32(textBox6.Text); mut = Convert.ToInt32(textBox7.Text); end = Convert.ToInt32(textBox8.Text); //критерий остановки kGen = Convert.ToInt32(textBox9.Text); //количество особей в поколении // priceMin = Convert.ToInt32(textBox10.Text); // priceMax = Convert.ToInt32(textBox11.Text); orderW.Add(25); stockW.Add(150); orderW.Add(200); stockW.Add(15); orderW.Add(100); stockW.Add(70); orderW.Add(5); stockW.Add(15); orderW.Add(20); stockW.Add(100); // stockW.Add(50); int sumStock = stockW.Sum(); int sumOrder = orderW.Sum(); bool addS = false; bool addO = false; /* if (stockW.Sum() != orderW.Sum()) * { //задача является открытой * int a = 0; * if (sumStock > sumOrder) * { * a = sumStock - sumOrder; * orderW.Add(a); * M++; * addO=true; * } * else * { * a = sumOrder - sumStock; * stockW.Add(a); * N++; * addS=true; * } * } */ MatrVesov = new int[N, M]; //for (int i = 0; i < N; i++) //формируем матрицу весов //{ // for (int j = 0; j < M; j++) // { // int r = rand.Next(1, 9); // MatrVesov[i, j] = r; //} //} MatrVesov[0, 0] = 2; MatrVesov[0, 1] = 1; MatrVesov[0, 2] = 7; MatrVesov[0, 3] = 3; MatrVesov[0, 4] = 3; MatrVesov[1, 0] = 5; MatrVesov[1, 1] = 8; MatrVesov[1, 2] = 5; MatrVesov[1, 3] = 1; MatrVesov[1, 4] = 5; MatrVesov[2, 0] = 4; MatrVesov[2, 1] = 5; MatrVesov[2, 2] = 4; MatrVesov[2, 3] = 1; MatrVesov[2, 4] = 6; MatrVesov[3, 0] = 6; MatrVesov[3, 1] = 2; MatrVesov[3, 2] = 6; MatrVesov[3, 3] = 4; MatrVesov[3, 4] = 8; MatrVesov[4, 0] = 2; MatrVesov[4, 1] = 2; MatrVesov[4, 2] = 3; MatrVesov[4, 3] = 9; MatrVesov[4, 4] = 8; //if (addO) //{ // int j = M - 1; // for (int i = 0; i < N; i++) // MatrVesov[i, j] = 0; //} //if (addS) //{ // int i = N - 1; // for (int j = 0; j < M; j++) // MatrVesov[i, j] = 0; //} PrintStockOrder(stockW, orderW); PrintMatrV(MatrVesov); //выводим матрицу весов List <Osob> generation = new List <Osob>(); //поколение, состоит из нескольких расписаний StreamWriter sw; FileInfo fi = new FileInfo(path); sw = fi.AppendText(); sw.Write("Начальное поколение: "); sw.WriteLine(); sw.Close(); for (int j = 0; j < kGen; j++) { //заполняем поколение особями Osob osbb = new Osob(); osbb.CreateOsob(stockW, orderW, N, M); osbb.PrintOsob(N, M, path, MatrVesov, richTextBox1); generation.Add(osbb); } // GeneticAlgorithm.Crossover(generation, path, N, M, cros, mut, MatrVesov, stockW, orderW, richTextBox1); Osob min = new Osob(); min = GeneticAlgorithm.osobWhithMinCost(generation, MatrVesov); richTextBox1.Text += "\nМинимальная стоимость перевозки в начальном поколении = " + min.cost(MatrVesov) + "\n"; int k = 0; int kol = 0; Osob min1 = new Osob(); Osob min2 = new Osob(); do { min1 = GeneticAlgorithm.osobWhithMinCost(generation, MatrVesov); //находим мин. особь в поколении //обращаемся к кроссоверу, в нём же и мутацию реализовать GeneticAlgorithm.Crossover(generation, path, N, M, cros, mut, MatrVesov, stockW, orderW, richTextBox1); //печатаем новое поколение с двумя потомками kol++; sw = fi.AppendText(); sw.Write(kol + " поколение"); sw.WriteLine(); sw.Close(); //печать переполненного поколения for (int j = 0; j < generation.Count(); j++) { generation[j].PrintOsob(N, M, path, MatrVesov, richTextBox1); } //обращаемся к редукции do { GeneticAlgorithm.reduction(generation, MatrVesov); }while (generation.Count() != kGen); min2 = GeneticAlgorithm.osobWhithMinCost(generation, MatrVesov); if (min1.SequenceEquals(min2)) //сравниваем по значению предыдущую мин.особь и мин. особь нового поколения { k++; //если равны } else { k = 0; } } while (k != end); min1 = GeneticAlgorithm.osobWhithMinCost(generation, MatrVesov); richTextBox1.Text += "Лучшая особь: \n"; min1.PrintOsobRtb(N, M, MatrVesov, richTextBox1); min1.PrintOsob(N, M, path, MatrVesov, richTextBox1); // richTextBox1.Text += "\nСтоимость перевозки = " + min1.cost(MatrVesov) + "\n"; }
public static void Crossover(List <Osob> generation, string path, int N, int M, int cros, int mut, int[,] matrV, List <int> lstStock, List <int> lstOrder, RichTextBox rch) { Random rand = new Random(); int k = generation.Count(); int parent1, parent2; parent1 = rand.Next(k); do { parent2 = rand.Next(k); }while (parent1 == parent2); StreamWriter sw; FileInfo fi = new FileInfo(path); sw = fi.AppendText(); sw.WriteLine("Для кроссовера выбраны особи: " + parent1 + " и " + parent2); int point = rand.Next(1, N * M); //точка разбиения sw.WriteLine("Точка разбиения = " + point); sw.WriteLine("Родительские особи:"); sw.Close(); generation[parent1].PrintOsob(N, M, path, matrV, rch); generation[parent2].PrintOsob(N, M, path, matrV, rch); if (rand.Next(0, 100) <= cros) //будет кроссовер или нет { sw = fi.AppendText(); sw.WriteLine("Для данных особей кроссовер произошёл"); sw.Close(); Osob child1 = new Osob(N, M); Osob child2 = new Osob(N, M); for (int i = 0; i < generation[parent1].osob.Count; i++) { if (i < point) { child1.osob[i].size = generation[parent1].osob[i].size; child2.osob[i].size = generation[parent2].osob[i].size; } } // child1.addition(lstStock, lstOrder, N, M, point); // child2.addition(lstStock, lstOrder, N, M, point); child1.addition2(generation[parent2], lstStock, lstOrder, N, M, point); child2.addition2(generation[parent1], lstStock, lstOrder, N, M, point); sw = fi.AppendText(); sw.WriteLine("Первый потомок: "); sw.Close(); child1.PrintOsob(N, M, "pract.txt", matrV, rch); sw = fi.AppendText(); sw.WriteLine("Второй потомок: "); sw.Close(); child2.PrintOsob(N, M, "pract.txt", matrV, rch); if (rand.Next(0, 100) <= mut) //будет мутация над потомком { sw = fi.AppendText(); sw.WriteLine("Произошла мутация первого потомка "); sw.Close(); MutationOrder(child1, N, M, lstStock, lstOrder); } if (rand.Next(0, 100) <= mut) //будет мутация над потомком { sw = fi.AppendText(); sw.WriteLine("Произошла мутация второго потомка "); sw.Close(); MutationOrder(child2, N, M, lstStock, lstOrder); } //добавляем потомков generation.Add(child1); generation.Add(child2); } }
public void addition2(Osob osob2, List <int> lstStock, List <int> lstOrder, int N, int M, int point) //дозаполнение неполной особи { List <int> lstSt = new List <int>(); List <int> lstOr = new List <int>(); Random rand = new Random(); lstSt = remainderStock(lstStock); lstOr = remainderOrder(lstOrder); List <int> metka = new List <int>(); int q = -1; for (int i = point; i < osob.Count(); i++) { int val; int ii = osob[i].stock; int jj = osob[i].order; if (lstOr[jj] > 0 & lstSt[ii] > 0) { if (lstSt[ii] < lstOr[jj]) { if (osob2.osob[i].size <= lstSt[ii]) { val = osob2.osob[i].size; } else { val = lstSt[ii]; } } else { if (osob2.osob[i].size <= lstOr[jj]) { val = osob2.osob[i].size; } else { val = lstOr[jj]; } } osob[i].size += val; lstSt[ii] -= val; lstOr[jj] -= val; } } while (lstOr.Sum() > 0 || lstSt.Sum() > 0) { List <int> metka2 = new List <int>(); int q2 = -1; while (metka2.Count != (N * M)) { while (metka2.Contains(q2) || q2 == -1) { q2 = rand.Next(N * M); } metka2.Add(q2); int ii = osob[q2].stock; int jj = osob[q2].order; int val; if (lstSt[ii] != 0 && lstOr[jj] != 0) { if (lstSt[ii] < lstOr[jj]) { val = lstSt[ii]; } else { val = lstOr[jj]; } osob[q2].size += val; lstSt[ii] -= val; lstOr[jj] -= val; } } } }