Проблема с симплекс-методом на python

Встала потребность написать свой сайт с решением симплекс-метода на поиск максимум.

Решил это сделать на питоне. Пошарил в интернете, нашел какие-то попытки это сделать, посидев несколько дней что-то получилось, но очень кривое. Так как проверив на сайте решение, то оно почти совпадает с ним, но является неправильным.

Сайт который я использовал для проверки задачи:

введите сюда описание изображения

И что получил у себя после вычислений:

введите сюда описание изображения

максимально близкие значения, но x2 в никаких видах этого метода(проверял на других задачах), никогда не хочет принимать истинное значение. Помогите найти проблему в методе.

from flask import Flask, request, jsonify
from flask_cors import CORS
import numpy as np
from fractions import Fraction

app = Flask(__name__)
CORS(app)

def display_tableau(tableau, basis):
    tableau_str = ""
    tableau_str += "Базис | " + " | ".join([f"x{i}" for i in range(1, tableau.shape[1])]) + " | Свободные члены\n"
    tableau_str += "-" * (12 + 9 * tableau.shape[1]) + "\n"

    for i, row in enumerate(tableau):
        basis_var = basis[i] if i < len(basis) else 'F'
        row_str = f"{basis_var}  | " + " | ".join([str(Fraction(cell).limit_denominator()) for cell in row])
        tableau_str += row_str + "\n"

    return tableau_str

def simplex_method(c, A, b):
    tableau = np.hstack([A, np.eye(len(b)), b.reshape(-1, 1)]) 
    c_extended = np.hstack([c, np.zeros(len(b)+1)]) 
    tableau = np.vstack([tableau, c_extended])

    basis = [f"x{i+1}" for i in range(len(b))] 

    iteration = 0
    all_tableaux = [] 

    while True:
        iteration += 1
        tableau_str = f"\nИтерация {iteration}:\n"
        tableau_str += display_tableau(tableau, basis)
        all_tableaux.append(tableau_str)

        pivot_col = np.argmin(tableau[-1, :-1])
        if tableau[-1, pivot_col] >= 0:
            break 

        ratios = tableau[:-1, -1] / tableau[:-1, pivot_col]
        positive_ratios = [(ratios[i], i) for i in range(len(ratios)) if ratios[i] > 0]
        pivot_row = min(positive_ratios, key=lambda x: x[0])[1]

        tableau[pivot_row, :] /= tableau[pivot_row, pivot_col]
        for i in range(tableau.shape[0]):
            if i != pivot_row:
                tableau[i, :] -= tableau[i, pivot_col] * tableau[pivot_row, :]

        # Обновляем базис
        basis[pivot_row] = f"x{pivot_col+1}"

    # Финальное решение
    final_solution = np.zeros(len(c))
    for i in range(len(basis)):
        if 'x' in basis[i]:
            var_index = int(basis[i][1:]) - 1
            final_solution[var_index] = tableau[i, -1]

    max_profit = tableau[-1, -1]

    return all_tableaux, final_solution, max_profit

@app.route('/solve', methods=['POST'])
def solve_simplex():
    try:
        data = request.get_json()

        # Целевая функция
        c = np.array(parse_objective(data['objectiveFunction']))
        # Ограничения
        A, b = parse_constraints(data['constraints'])

        tableaux, solution, profit = simplex_method(c, A, b)

        result = {
            "tableaux": tableaux,
            "solution": [str(Fraction(x).limit_denominator()) for x in solution],
            "profit": str(Fraction(profit).limit_denominator())
        }

        return jsonify(result)
    except Exception as e:
        return jsonify({'error': str(e)})

def parse_objective(obj_str):
    cleaned_str = obj_str.replace('\u200b', '').replace(' ', '')
    terms = cleaned_str.split('+')
    return [-int(term.split('x')[0]) for term in terms]  # Инвертируем для минимизации

def parse_constraints(con_str):
    cleaned_str = con_str.replace('\u200b', '').replace(' ', '')
    constraints = []
    bounds = []
    for line in cleaned_str.split('\n'):
        parts = line.split('<=')
        left_side = parts[0].split('+')
        right_side = int(parts[1])
        constraints.append([int(term.split('x')[0]) for term in left_side])
        bounds.append(right_side)
    return np.array(constraints), np.array(bounds)

if __name__ == '__main__':
    app.run(debug=True)

Ответы (0 шт):