// Возвращает сокращенную дробь public Fractions Reduce() { Fractions result = this; int greatestCommonDivisor = getGreatestCommonDivisor(this.numerator, this.denominator); result.numerator /= greatestCommonDivisor; result.denominator /= greatestCommonDivisor; return(result); }
// Мой метод Equals public bool Equals(Fractions that) { Fractions a = this.Reduce(); Fractions b = that.Reduce(); return(a.numerator == b.numerator && a.denominator == b.denominator && a.sign == b.sign); }
// Метод создан для устранения повторяющегося кода в методах сложения и вычитания дробей. // Возвращает дробь, которая является результатом сложения или вычитания дробей a и b, // В зависимости от того, какая операция передана в параметр operation. // P.S. использовать только для сложения и вычитания private static Fractions performOperation(Fractions a, Fractions b, Func <int, int, int> operation) { // Наименьшее общее кратное знаменателей int leastCommonMultiple = getLeastCommonMultiple(a.denominator, b.denominator); // Дополнительный множитель к первой дроби int additionalMultiplierFirst = leastCommonMultiple / a.denominator; // Дополнительный множитель ко второй дроби int additionalMultiplierSecond = leastCommonMultiple / b.denominator; // Результат операции int operationResult = operation(a.numerator * additionalMultiplierFirst * a.sign, b.numerator * additionalMultiplierSecond * b.sign); return(new Fractions(operationResult, a.denominator * additionalMultiplierFirst)); }
/// <summary> /// Ищем ранг матрицы для дробей. Вместе с этим в функции уже удаляются "ненужные" строки. /// </summary> /// <returns>Возвращает ранг матрицы.</returns> private int RangOfMatrix(List <List <Fractions> > elements_1) { Fractions first_elem = new Fractions(0); for (int i = 0; i < elements_1.Count; i++) { int j = 0; first_elem = elements_1[i][j]; //находим ненулевой элемент в строке. если такого нет, то удаляем строку из нулей if (first_elem == 0) { j = 1; while (first_elem == 0) { first_elem = elements_1[i][j]; j++; //если не нашли не нулевого, то удаляем строку из нулей if (j == elements_1[0].Count) { elements_1.RemoveAt(i); i--; break; } } j--; } //удалось найти не нулевой if (first_elem != 0) { for (int p = 0; p < elements_1[0].Count; p++) { elements_1[i][p] /= first_elem; } for (int k = i + 1; k < elements_1.Count; k++) { if (elements_1[k][j] != 0) { Fractions first_elem_1 = elements_1[k][j]; for (int m = 0; m < elements_1[0].Count; m++) { elements_1[k][m] = elements_1[k][m] - elements_1[i][m] * first_elem_1; } } } } } return(elements_1.Count); }
// Метод сравнения двух дробей // Возвращает 0, если дроби равны // 1, если this больше that // -1, если this меньше that private int CompareTo(Fractions that) { if (this.Equals(that)) { return(0); } Fractions a = this.Reduce(); Fractions b = that.Reduce(); if (a.numerator * a.sign * b.denominator > b.numerator * b.sign * a.denominator) { return(1); } return(-1); }
/// <summary> /// Меняем колонки местами для дробей /// </summary> /// <param name="dataGridView2"></param> /// <param name="corner_dot"></param> private void ChangeColumnsForGauss(List <List <Fractions> > ogr_with_radicals, List <List <Fractions> > corner_dot, List <int> variable_visualization) { int column_index = 0; int tmp_variable = 0; for (int j = 0; j < corner_dot[0].Count; j++) { // Еесли встретили ненулевой элемент корневой точки if (corner_dot[0][j] != 0) { Fractions[] tmp_fractions = new Fractions[ogr_with_radicals.Count]; // Меняем местами столбцы for (int i = 0; i < ogr_with_radicals.Count; i++) { // Копируем первый столбец tmp_fractions[i] = ogr_with_radicals[i][column_index]; } for (int i = 0; i < ogr_with_radicals.Count; i++) { // заносим на место первого j-тый - тот, на котором на встретился ненулевой элемент корневой точки ogr_with_radicals[i][column_index] = ogr_with_radicals[i][j]; } for (int i = 0; i < ogr_with_radicals.Count; i++) { // Из копии достаём и ставим ogr_with_radicals[i][j] = tmp_fractions[i]; } // Меняем местами в массиве для визуализации tmp_variable = variable_visualization[column_index]; variable_visualization[column_index] = variable_visualization[j]; variable_visualization[j] = tmp_variable; column_index++; } } }
/// <summary> /// Преобразование матрицы в симплекс таблицу для дробей /// </summary> /// <param name="ogr"></param> public void DrawSimplexTable(List <List <Fractions> > ogr) { //для сиплекс метода if (simplextable.simplex_or_artificial == true) { Fractions a; //счёт столбца int column_index = 1; // Отображаем таблицу в её естественном виде // убираем базис и переносим его в левую колонку string now_basix_name = ""; // Алгоритм определяющий единственные единицы в столбцах for (int j = 0; j < dataGridView3.Columns.Count - 1; j++) // Проходимся по всем колонкам { a = new Fractions(0); column_index = 0; bool only_one_in_column = false; // Единственная единица в столбце for (int i = 0; i < dataGridView3.Rows.Count; i++) // Проходимся по всем элементам в колонке, кроме последнего(т.е. кроме целевой функции) { a += (Fractions)dataGridView3.Rows[i].Cells[j].Value; // Если нам встречается единица, считаем, что колонка базисная if ((Fractions)dataGridView3.Rows[i].Cells[j].Value == new Fractions(1)) { now_basix_name = dataGridView3.Columns[j].Name; column_index = i; only_one_in_column = true; } // Если встретили отличное от единицы и это не ноль, смотрим, встречалась ли нам единица раньше. Если встречалась - значит считаем колонку НЕ базисной else if (only_one_in_column == true && !((Fractions)dataGridView3.Rows[i].Cells[j].Value == new Fractions(0))) { only_one_in_column = false; break; } // Если дошли до последнего элемента в столбце и сумма всех не равна единице, то считаем НЕ базисной if ((i == dataGridView3.Rows.Count - 1) && (a != 1)) { only_one_in_column = false; break; } } if (only_one_in_column) { dataGridView3.Rows[column_index].HeaderCell.Value = now_basix_name; dataGridView3.Columns.Remove(dataGridView3.Columns[j]); j--; } } column_index = 0; // считаем коэффициенты последней строки dataGridView3.Rows.Add(); dataGridView3.Rows[simplextable.count_of_permutations].HeaderCell.Value = "f(x)"; for (int j = simplextable.count_of_permutations; j < simplextable.ogr_with_radicals[0].Count - 1; j++) { //логика a = new Fractions(0); for (int i = 0; i < simplextable.ogr_with_radicals.Count; i++) { a += simplextable.ogr_with_radicals[i][j] * cel_function_with_radicals[0][Int32.Parse(dataGridView3.Rows[i].HeaderCell.Value.ToString().Trim('x')) - 1]; } a -= simplextable.cel_function_with_radicals[0][Int32.Parse(dataGridView3.Columns[column_index].HeaderCell.Value.ToString().Replace("Своб.", column_index.ToString()).Trim('x')) - 1]; ////отображение dataGridView3.Rows[simplextable.count_of_permutations].Cells[column_index].Value = a; column_index++; } //коэффициент в нижнем правом углу симплекс таблицы a = new Fractions(0); for (int i = 0; i < simplextable.ogr_with_radicals.Count; i++) { a += simplextable.ogr_with_radicals[i][simplextable.ogr_with_radicals[0].Count - 1] * cel_function_with_radicals[0][Int32.Parse(dataGridView3.Rows[i].HeaderCell.Value.ToString().Trim('x')) - 1]; } dataGridView3.Rows[dataGridView3.Rows.Count - 1].Cells[dataGridView3.Columns.Count - 1].Value = a; //заполняем рабочий массив for (int i = 0; i < dataGridView3.Rows.Count; i++) { simplextable.simplex_elements_with_radicals.Add(new List <Fractions>()); for (int j = 0; j < dataGridView3.Columns.Count; j++) { //добавляем в массив число simplextable.simplex_elements_with_radicals[i].Add((Fractions)dataGridView3.Rows[i].Cells[j].Value); } } } }