From f84c770307ad83cd954f5a2c850f03b6daac4ea2 Mon Sep 17 00:00:00 2001 From: IgorSPinto Date: Sat, 22 Nov 2025 19:39:04 -0300 Subject: [PATCH 01/15] implement Tableau class with methods for simplex algorithm --- main/simplex.py | 226 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) diff --git a/main/simplex.py b/main/simplex.py index e69de29..4dab593 100644 --- a/main/simplex.py +++ b/main/simplex.py @@ -0,0 +1,226 @@ +# tableau.py +class Tableau: + def __init__(self, tableau_rows, col_types, var_names, base_vars, objective_type="Max"): + """ + tableau_rows: lista de linhas (cada linha já inclui RHS como última coluna) + col_types: lista de strings para cada coluna (ex: 'orig','slack','surplus','artificial') + var_names: nomes das colunas (sem RHS) + base_vars: lista length = m com índices das colunas básicas (ou None) + """ + self.tableau = [row[:] for row in tableau_rows] + self.col_types = col_types[:] + self.var_names = var_names[:] + self.base_vars = base_vars[:] + self.objective_type = objective_type + + # ---- Mantive e aperfeiçoei seu build_tableau/print_tableau ---- + @classmethod + def from_phase1(cls, A, comps, b, orig_var_names=None, objective_type="Max"): + """ + Constrói o tableau inicial de fase 1 (com slacks/surplus/artificiais). + Retorna instância de Tableau pronta para rodar fase 1. + """ + m = len(A) + n = len(A[0]) if m > 0 else 0 + tableau = [row[:] for row in A] + col_types = ['orig'] * n + var_names = orig_var_names[:] if orig_var_names is not None else [f"x{j+1}" for j in range(n)] + base_vars = [None]*m + slack_count = 0 + artificial_count = 0 + + for i, comp in enumerate(comps): + if comp == "<=": + for r in range(m): + tableau[r].append(1.0 if r == i else 0.0) + col_types.append('slack') + var_names.append(f"s{slack_count+1}") + base_vars[i] = n + slack_count + slack_count += 1 + elif comp == ">=": + for r in range(m): + tableau[r].append(-1.0 if r == i else 0.0) + col_types.append('surplus') + var_names.append(f"e{slack_count+1}") + slack_count += 1 + for r in range(m): + tableau[r].append(1.0 if r == i else 0.0) + col_types.append('artificial') + var_names.append(f"a{artificial_count+1}") + base_vars[i] = n + slack_count + artificial_count += 1 + slack_count += 1 + elif comp == "=": + for r in range(m): + tableau[r].append(1.0 if r == i else 0.0) + col_types.append('artificial') + var_names.append(f"a{artificial_count+1}") + base_vars[i] = n + slack_count + artificial_count += 1 + slack_count += 1 + else: + raise ValueError("Comparator desconhecido: " + str(comp)) + + # append RHS + for i in range(m): + tableau[i].append(b[i]) + + # Build phase1 objective (maximize -sum(artificiais)) + total_cols = len(tableau[0]) + obj_row = [0.0]*total_cols + for j,t in enumerate(col_types): + if t == 'artificial': + obj_row[j] = -1.0 + obj_row[-1] = 0.0 + tableau.append(obj_row) + + # if artificials are basic, add their rows to objective (to make objective consistent) + for i in range(m): + bv = base_vars[i] + if bv is not None and bv < len(col_types) and col_types[bv] == 'artificial': + tableau[-1] = [tableau[-1][j] + tableau[i][j] for j in range(len(tableau[0]))] + + return cls(tableau, col_types, var_names, base_vars, objective_type=objective_type) + + # ---- impressão (mantive seu estilo com pequenas melhorias) ---- + def print_tableau(self, iteration=0): + m = len(self.tableau) - 1 + n = len(self.tableau[0]) + header = ["VB"] + self.var_names + ["b"] + largura = 10 + print(f"=== Iteracao: {iteration} ===") + print(f"{header[0]:>8}", end="") + for h in header[1:]: + print(f"{h:>{largura}}", end="") + print() + for i in range(m): + vb_idx = self.base_vars[i] + vb = self.var_names[vb_idx] if (vb_idx is not None and vb_idx < len(self.var_names)) else f"v{vb_idx}" + print(f"{vb:>8}", end="") + for val in self.tableau[i]: + print(f"{val:>{largura}.4f}", end="") + print() + print(f"{'OBJ':>8}", end="") + for val in self.tableau[-1]: + print(f"{val:>{largura}.4f}", end="") + print("\n") + + # ---- operações de pivô / seleção ---- + def find_pivot(self): + last = self.tableau[-1] + min_val = min(last[:-1]) + if min_val >= -EPS: + return None + pivot_col = last[:-1].index(min_val) + ratios = [] + for i in range(len(self.tableau)-1): + aij = self.tableau[i][pivot_col] + if aij > EPS: + ratios.append((self.tableau[i][-1] / aij, i)) + if not ratios: + return ("unbounded", pivot_col) + ratios.sort(key=lambda x: (x[0], x[1])) + return (ratios[0][1], pivot_col) + + def pivot(self, pivot_row, pivot_col): + m = len(self.tableau) + n = len(self.tableau[0]) + pv = self.tableau[pivot_row][pivot_col] + self.tableau[pivot_row] = [v / pv for v in self.tableau[pivot_row]] + for i in range(m): + if i == pivot_row: + continue + factor = self.tableau[i][pivot_col] + self.tableau[i] = [self.tableau[i][j] - factor*self.tableau[pivot_row][j] for j in range(n)] + # update base var for pivot_row + self.base_vars[pivot_row] = pivot_col + + def run_simplex(self, verbose=True, max_iter=500): + it = 0 + while True: + it += 1 + if verbose: + self.print_tableau(iteration=it) + pv = self.find_pivot() + if pv is None: + return "optimal" + if pv[0] == "unbounded": + return "unbounded" + r, c = pv + self.pivot(r, c) + if it >= max_iter: + return "max_iter" + + # ---- remover artificiais (após fase1) ---- + def remove_artificials(self): + # remove columns marcadas como 'artificial' + cols_to_remove = [i for i,t in enumerate(self.col_types) if t == 'artificial'] + remap = {} + jnew = 0 + for j in range(len(self.col_types)): + if j not in cols_to_remove: + remap[j] = jnew + jnew += 1 + + new_col_types = [t for i,t in enumerate(self.col_types) if i not in cols_to_remove] + new_var_names = [v for i,v in enumerate(self.var_names) if i not in cols_to_remove] + + new_tableau = [] + for i in range(len(self.tableau)-1): # exclude objective row + new_row = [val for j,val in enumerate(self.tableau[i]) if j not in cols_to_remove] + new_tableau.append(new_row) + + # update base_vars: if removed, set to None + new_base_vars = [] + for bv in self.base_vars: + if bv is None: + new_base_vars.append(None) + elif bv in remap: + new_base_vars.append(remap[bv]) + else: + new_base_vars.append(None) + + return Tableau(new_tableau, new_col_types, new_var_names, new_base_vars, objective_type=self.objective_type) + + # ---- configurar objetivo original na tabela fase2 ---- + def set_objective_from_original(self, c_orig, objective_type="Max"): + # c_orig: lista de coeficientes correspondentes às primeiras colunas 'orig' (após expansão de var livres) + # Identifica quais colunas atuais correspondem a originais: assumimos que col_types começa com 'orig' para as originais + # Construir linha objetivo + total_cols = len(self.tableau[0]) + obj = [0.0]*total_cols + # número de originais é o número de 'orig' presentes no col_types + orig_indices = [i for i,t in enumerate(self.col_types) if t == 'orig'] + for idx, orig_col in enumerate(orig_indices): + if idx < len(c_orig): + coeff = c_orig[idx] + obj[orig_col] = -coeff if objective_type == "Max" else coeff + obj[-1] = 0.0 + # tornar consistente com base atual + for i in range(len(self.tableau)-1): + bv = self.base_vars[i] + if bv is not None and abs(obj[bv]) > EPS: + factor = obj[bv] + obj = [obj[j] - factor*self.tableau[i][j] for j in range(total_cols)] + # substituir linha objetivo + self.tableau[-1] = obj + + # ---- extrair solucao para as primeiras "k" colunas (expanded) ---- + def extract_solution_expanded(self, k): + m = len(self.tableau)-1 + sol = [0.0]*k + for col in range(k): + # verificar se coluna é basica + count_one = 0 + row_index = None + for i in range(m): + if abs(self.tableau[i][col] - 1.0) < 1e-8: + count_one += 1 + row_index = i + elif abs(self.tableau[i][col]) > 1e-8: + count_one = -1000 + if count_one == 1: + sol[col] = self.tableau[row_index][-1] + else: + sol[col] = 0.0 + return sol From a9cc576986466918638617e5fd16ad51ee239ac2 Mon Sep 17 00:00:00 2001 From: IgorSPinto Date: Sat, 22 Nov 2025 20:12:38 -0300 Subject: [PATCH 02/15] refactor main function to integrate SimplexSolver and improve output formatting --- main/main.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/main/main.py b/main/main.py index b13b497..8c805f0 100644 --- a/main/main.py +++ b/main/main.py @@ -1,11 +1,24 @@ +# main.py from parser import Parser -from tableau import Tableau +from simplex import SimplexSolver def main(): filepath = "input/input.txt" - parser = Parser(filepath) - result = parser.parse() - + model = parser.parse() + + solver = SimplexSolver(model) + result = solver.solve(verbose=True) + + if result is None: + print("Problema inviável ou ilimitado.") + else: + print("\n=== Resultado ===") + print("Z ótimo:", result["z"]) + print("Solução (variáveis originais):") + for k,v in result["original_solution"].items(): + print(f" {k} = {v:.6f}") + print("\nDetalhes: phase1_obj =", result["phase1_obj"], ", status_phase1 =", result["status_phase1"], ", status_phase2 =", result["status_phase2"]) -main() \ No newline at end of file +if __name__ == "__main__": + main() From eda4caeb953b7fcd853342a7900a360b0bb4c719 Mon Sep 17 00:00:00 2001 From: IgorSPinto Date: Sat, 22 Nov 2025 20:12:43 -0300 Subject: [PATCH 03/15] refactor Parser class to enhance parsing logic and improve variable handling --- main/parser.py | 216 ++++++++++++++++++++++++------------------------- 1 file changed, 107 insertions(+), 109 deletions(-) diff --git a/main/parser.py b/main/parser.py index edd8126..aece900 100644 --- a/main/parser.py +++ b/main/parser.py @@ -1,125 +1,123 @@ +# parser.py import re class Parser: """ - Max 2x1 + 3x2 - 2x1 + x2 <= 10 - x1 + 3x2 <= 5 - x1 >= 0 - x2 >= 0 + Parser que lê arquivo input com formato: + Max 3x1 + 5x2 + x1 + 2x2 <= 6 + 3x1 + 2x2 <= 12 + x1 >= 0 + x2 free + + Retorna dicionário com: + { + "objective_type": "Max"/"Min", + "objective_coeffs": [...], + "constraints": [(row, comp, b), ...], + "num_vars": n, + "non_negative": [...] + } """ def __init__(self, filepath): self.filepath = filepath - self.objective_type = None - self.objective_coeffs = [] - self.constraints = [] - self.num_vars = 0 - self.non_negative = [] def parse(self): - lines = [line.strip() for line in open(self.filepath)] + lines = [line.strip() for line in open(self.filepath, encoding="utf-8") if line.strip() and not line.strip().startswith("#")] + if not lines: + raise ValueError("Arquivo vazio") + + # objective + obj_line = lines[0] + if obj_line.lower().startswith("max"): + obj_type = "Max" + rest = obj_line[3:].strip() + elif obj_line.lower().startswith("min"): + obj_type = "Min" + rest = obj_line[3:].strip() + else: + raise ValueError("Função objetivo deve começar com 'Max' ou 'Min'") + + obj_coeffs = {} + for raw_coeff, var in re.findall(r'([+-]?\s*\d*)x(\d+)', rest): + coeff = raw_coeff.replace(" ", "") + if coeff == "" or coeff == "+": + c = 1 + elif coeff == "-": + c = -1 + else: + c = int(coeff) + idx = int(var) + obj_coeffs[idx] = obj_coeffs.get(idx, 0) + c - self.parse_objective(lines[0]) + constraints = [] + nonneg = {} for line in lines[1:]: - if self.is_non_negative(line): - self.parse_non_negative(line) - elif "<=" in line or ">=" in line or "=" in line: - self.parse_constraint(line) - - #if some variables were not mentioned in non-negativity constraints, assume they are non-negative - while len(self.non_negative) < self.num_vars: - self.non_negative.append(True) + m_free = re.match(r'^x(\d+)\s+(free|livre)$', line, re.I) + m_nonneg = re.match(r'^x(\d+)\s*>=\s*0$', line) + if m_free: + var = int(m_free.group(1)) + nonneg[var] = False + continue + if m_nonneg: + var = int(m_nonneg.group(1)) + nonneg[var] = True + continue + + if "<=" in line or ">=" in line or "=" in line: + coeff_map = {} + for raw_coeff, var in re.findall(r'([+-]?\s*\d*)x(\d+)', line): + coeff = raw_coeff.replace(" ", "") + if coeff == "" or coeff == "+": + c = 1 + elif coeff == "-": + c = -1 + else: + c = int(coeff) + idx = int(var) + coeff_map[idx] = coeff_map.get(idx, 0) + c + + if "<=" in line: + comp = "<=" + elif ">=" in line: + comp = ">=" + else: + comp = "=" + + b_match = re.search(r'(-?\d+)\s*$', line) + if not b_match: + raise ValueError("Não foi possível ler RHS na linha: " + line) + b = int(b_match.group(1)) + + constraints.append((coeff_map, comp, b)) + + all_idx = set(obj_coeffs.keys()) + for cm,_,_ in constraints: + all_idx |= set(cm.keys()) + all_idx |= set(nonneg.keys()) + n = max(all_idx) if all_idx else 0 + + c = [0.0]*n + for i in range(1, n+1): + c[i-1] = float(obj_coeffs.get(i, 0)) + + constraints_vec = [] + for coeff_map, comp, b in constraints: + row = [0.0]*n + for i in range(1, n+1): + row[i-1] = float(coeff_map.get(i, 0)) + constraints_vec.append((row, comp, float(b))) + + nonneg_list = [] + for i in range(1, n+1): + nonneg_list.append(nonneg.get(i, True)) return { - "objective_type": self.objective_type, - "objective_coeffs": self.objective_coeffs, - "constraints": self.constraints, - "num_vars": self.num_vars, - "non_negative": self.non_negative + "objective_type": obj_type, + "objective_coeffs": c, + "constraints": constraints_vec, + "num_vars": n, + "non_negative": nonneg_list } - - def is_non_negative(self, line): - return re.match(r"x\d+\s*>=\s*0$", line) is not None - - def parse_non_negative(self, line): - var = int(re.findall(r"x(\d+)", line)[0]) - - self.num_vars = max(self.num_vars, var) - - while len(self.non_negative) < var: - self.non_negative.append(True) - - self.non_negative[var - 1] = True - - def parse_objective(self, line): - if line.startswith("Max"): - self.objective_type = "Max" - elif line.startswith("Min"): - self.objective_type = "Min" - else: - raise ValueError("Objective function must be Max or Min.") - - """ - Explaining the regex: - ([+-]?\s*\d*) - 1st step, we search for the coefficient of the variable: - [+-]? - an optional '+' or '-' sign - \s* - followed by any number of spaces - \d* - followed by any number of digits (the coefficient itself) - x(\d+) - 2nd step, we look for the variable part: - x - the character 'x' indicating a variable - (\d+) - followed by one or more digits (the variable index, e.g. x1, x2, etc.) - """ - - coeffs = re.findall(r'([+-]?\s*\d*)x(\d+)', line) - #after we have found all coefficients and variable indices, we iterate over them to process each pair: - for raw_coeff, var in coeffs: - raw_coeff = raw_coeff.replace(" ", "") #if we have some spaces, like "+ 3", we remove them - if raw_coeff == '+' or raw_coeff == '' or raw_coeff == '+ ': - raw_coeff = 1 - elif raw_coeff == '-': - raw_coeff = -1 - else: - raw_coeff = int(raw_coeff) - var = int(var) - self.num_vars = max(self.num_vars, var) - #consider an edge case where the coefficients are not in order, like "Max 3x3 + 2x1 + x2" - #we store them as tuples (variable index, coefficient) to sort them later - self.objective_coeffs.append((var, raw_coeff)) - - self.objective_coeffs = [c for _, c in sorted(self.objective_coeffs)] - - def parse_constraint(self, line): - coeffs = re.findall(r'([+-]?\s*\d*)x(\d+)', line) - parsed = [0] * (self.num_vars) - - for raw_coeff, var in coeffs: - raw_coeff = raw_coeff.replace(" ", "") - if raw_coeff == '' or raw_coeff == '+': - raw_coeff = 1 - elif raw_coeff == '-': - raw_coeff = -1 - else: - raw_coeff = int(raw_coeff) - - var = int(var) - parsed[var - 1] = raw_coeff - - if "<=" in line: - comp = "<=" - elif ">=" in line: - comp = ">=" - else: - comp = "=" - - """ - (-?\d+)$ - -? - matches an optional negative sign - \d+ - matches one or more digits - $ - guarantees that the match is at the end of the line - """ - - b = int(re.findall(r'(-?\d+)$', line)[0]) - - self.constraints.append((parsed, comp, b)) From 26b7593b8862160f7884dd1e02220ab0fab3e810 Mon Sep 17 00:00:00 2001 From: IgorSPinto Date: Sat, 22 Nov 2025 20:12:49 -0300 Subject: [PATCH 04/15] refactor SimplexSolver to enhance variable handling and improve tableau construction --- main/simplex.py | 363 +++++++++++++++++++----------------------------- 1 file changed, 140 insertions(+), 223 deletions(-) diff --git a/main/simplex.py b/main/simplex.py index 4dab593..c43bb13 100644 --- a/main/simplex.py +++ b/main/simplex.py @@ -1,226 +1,143 @@ -# tableau.py -class Tableau: - def __init__(self, tableau_rows, col_types, var_names, base_vars, objective_type="Max"): - """ - tableau_rows: lista de linhas (cada linha já inclui RHS como última coluna) - col_types: lista de strings para cada coluna (ex: 'orig','slack','surplus','artificial') - var_names: nomes das colunas (sem RHS) - base_vars: lista length = m com índices das colunas básicas (ou None) - """ - self.tableau = [row[:] for row in tableau_rows] - self.col_types = col_types[:] - self.var_names = var_names[:] - self.base_vars = base_vars[:] - self.objective_type = objective_type - - # ---- Mantive e aperfeiçoei seu build_tableau/print_tableau ---- - @classmethod - def from_phase1(cls, A, comps, b, orig_var_names=None, objective_type="Max"): - """ - Constrói o tableau inicial de fase 1 (com slacks/surplus/artificiais). - Retorna instância de Tableau pronta para rodar fase 1. - """ - m = len(A) - n = len(A[0]) if m > 0 else 0 - tableau = [row[:] for row in A] - col_types = ['orig'] * n - var_names = orig_var_names[:] if orig_var_names is not None else [f"x{j+1}" for j in range(n)] - base_vars = [None]*m - slack_count = 0 - artificial_count = 0 - - for i, comp in enumerate(comps): - if comp == "<=": - for r in range(m): - tableau[r].append(1.0 if r == i else 0.0) - col_types.append('slack') - var_names.append(f"s{slack_count+1}") - base_vars[i] = n + slack_count - slack_count += 1 - elif comp == ">=": - for r in range(m): - tableau[r].append(-1.0 if r == i else 0.0) - col_types.append('surplus') - var_names.append(f"e{slack_count+1}") - slack_count += 1 - for r in range(m): - tableau[r].append(1.0 if r == i else 0.0) - col_types.append('artificial') - var_names.append(f"a{artificial_count+1}") - base_vars[i] = n + slack_count - artificial_count += 1 - slack_count += 1 - elif comp == "=": - for r in range(m): - tableau[r].append(1.0 if r == i else 0.0) - col_types.append('artificial') - var_names.append(f"a{artificial_count+1}") - base_vars[i] = n + slack_count - artificial_count += 1 - slack_count += 1 +# simplex.py +from parser import Parser +from tableau import Tableau +import copy + +EPS = 1e-9 + +class SimplexSolver: + def __init__(self, model): + if "objective_coeffs" in model: + self.c = [float(x) for x in model["objective_coeffs"]] + else: + self.c = [float(x) for x in model["c"]] + self.objective_type = model["objective_type"] + self.constraints = model["constraints"] + self.nonneg = model.get("non_negative", model.get("nonneg")) + self.n = model["num_vars"] + + def _expand_free(self, A_rows, c, nonneg): + mapping = [] + var_names = [] + cur = 0 + for i in range(len(c)): + if not nonneg[i]: + mapping.append((cur, cur+1)) + var_names.append(f"x{i+1}_pos") + var_names.append(f"x{i+1}_neg") + cur += 2 else: - raise ValueError("Comparator desconhecido: " + str(comp)) - - # append RHS - for i in range(m): - tableau[i].append(b[i]) - - # Build phase1 objective (maximize -sum(artificiais)) - total_cols = len(tableau[0]) - obj_row = [0.0]*total_cols - for j,t in enumerate(col_types): - if t == 'artificial': - obj_row[j] = -1.0 - obj_row[-1] = 0.0 - tableau.append(obj_row) - - # if artificials are basic, add their rows to objective (to make objective consistent) - for i in range(m): - bv = base_vars[i] - if bv is not None and bv < len(col_types) and col_types[bv] == 'artificial': - tableau[-1] = [tableau[-1][j] + tableau[i][j] for j in range(len(tableau[0]))] - - return cls(tableau, col_types, var_names, base_vars, objective_type=objective_type) - - # ---- impressão (mantive seu estilo com pequenas melhorias) ---- - def print_tableau(self, iteration=0): - m = len(self.tableau) - 1 - n = len(self.tableau[0]) - header = ["VB"] + self.var_names + ["b"] - largura = 10 - print(f"=== Iteracao: {iteration} ===") - print(f"{header[0]:>8}", end="") - for h in header[1:]: - print(f"{h:>{largura}}", end="") - print() - for i in range(m): - vb_idx = self.base_vars[i] - vb = self.var_names[vb_idx] if (vb_idx is not None and vb_idx < len(self.var_names)) else f"v{vb_idx}" - print(f"{vb:>8}", end="") - for val in self.tableau[i]: - print(f"{val:>{largura}.4f}", end="") - print() - print(f"{'OBJ':>8}", end="") - for val in self.tableau[-1]: - print(f"{val:>{largura}.4f}", end="") - print("\n") - - # ---- operações de pivô / seleção ---- - def find_pivot(self): - last = self.tableau[-1] - min_val = min(last[:-1]) - if min_val >= -EPS: - return None - pivot_col = last[:-1].index(min_val) - ratios = [] - for i in range(len(self.tableau)-1): - aij = self.tableau[i][pivot_col] - if aij > EPS: - ratios.append((self.tableau[i][-1] / aij, i)) - if not ratios: - return ("unbounded", pivot_col) - ratios.sort(key=lambda x: (x[0], x[1])) - return (ratios[0][1], pivot_col) - - def pivot(self, pivot_row, pivot_col): - m = len(self.tableau) - n = len(self.tableau[0]) - pv = self.tableau[pivot_row][pivot_col] - self.tableau[pivot_row] = [v / pv for v in self.tableau[pivot_row]] - for i in range(m): - if i == pivot_row: - continue - factor = self.tableau[i][pivot_col] - self.tableau[i] = [self.tableau[i][j] - factor*self.tableau[pivot_row][j] for j in range(n)] - # update base var for pivot_row - self.base_vars[pivot_row] = pivot_col - - def run_simplex(self, verbose=True, max_iter=500): - it = 0 - while True: - it += 1 - if verbose: - self.print_tableau(iteration=it) - pv = self.find_pivot() - if pv is None: - return "optimal" - if pv[0] == "unbounded": - return "unbounded" - r, c = pv - self.pivot(r, c) - if it >= max_iter: - return "max_iter" - - # ---- remover artificiais (após fase1) ---- - def remove_artificials(self): - # remove columns marcadas como 'artificial' - cols_to_remove = [i for i,t in enumerate(self.col_types) if t == 'artificial'] - remap = {} - jnew = 0 - for j in range(len(self.col_types)): - if j not in cols_to_remove: - remap[j] = jnew - jnew += 1 - - new_col_types = [t for i,t in enumerate(self.col_types) if i not in cols_to_remove] - new_var_names = [v for i,v in enumerate(self.var_names) if i not in cols_to_remove] - - new_tableau = [] - for i in range(len(self.tableau)-1): # exclude objective row - new_row = [val for j,val in enumerate(self.tableau[i]) if j not in cols_to_remove] - new_tableau.append(new_row) - - # update base_vars: if removed, set to None - new_base_vars = [] - for bv in self.base_vars: - if bv is None: - new_base_vars.append(None) - elif bv in remap: - new_base_vars.append(remap[bv]) + mapping.append((cur,)) + var_names.append(f"x{i+1}") + cur += 1 + new_n = cur + c2 = [0.0]*new_n + for i in range(len(c)): + idxs = mapping[i] + if len(idxs) == 2: + c2[idxs[0]] += c[i] + c2[idxs[1]] += -c[i] else: - new_base_vars.append(None) - - return Tableau(new_tableau, new_col_types, new_var_names, new_base_vars, objective_type=self.objective_type) - - # ---- configurar objetivo original na tabela fase2 ---- - def set_objective_from_original(self, c_orig, objective_type="Max"): - # c_orig: lista de coeficientes correspondentes às primeiras colunas 'orig' (após expansão de var livres) - # Identifica quais colunas atuais correspondem a originais: assumimos que col_types começa com 'orig' para as originais - # Construir linha objetivo - total_cols = len(self.tableau[0]) - obj = [0.0]*total_cols - # número de originais é o número de 'orig' presentes no col_types - orig_indices = [i for i,t in enumerate(self.col_types) if t == 'orig'] - for idx, orig_col in enumerate(orig_indices): - if idx < len(c_orig): - coeff = c_orig[idx] - obj[orig_col] = -coeff if objective_type == "Max" else coeff - obj[-1] = 0.0 - # tornar consistente com base atual - for i in range(len(self.tableau)-1): - bv = self.base_vars[i] - if bv is not None and abs(obj[bv]) > EPS: - factor = obj[bv] - obj = [obj[j] - factor*self.tableau[i][j] for j in range(total_cols)] - # substituir linha objetivo - self.tableau[-1] = obj - - # ---- extrair solucao para as primeiras "k" colunas (expanded) ---- - def extract_solution_expanded(self, k): - m = len(self.tableau)-1 - sol = [0.0]*k - for col in range(k): - # verificar se coluna é basica - count_one = 0 - row_index = None - for i in range(m): - if abs(self.tableau[i][col] - 1.0) < 1e-8: - count_one += 1 - row_index = i - elif abs(self.tableau[i][col]) > 1e-8: - count_one = -1000 - if count_one == 1: - sol[col] = self.tableau[row_index][-1] + c2[idxs[0]] += c[i] + A2 = [] + for row in A_rows: + new_row = [0.0]*new_n + for i in range(len(c)): + idxs = mapping[i] + if len(idxs) == 2: + new_row[idxs[0]] += row[i] + new_row[idxs[1]] += -row[i] + else: + new_row[idxs[0]] += row[i] + A2.append(new_row) + return A2, c2, mapping, var_names + + def solve(self, verbose=True): + A = [row for row,_,_ in self.constraints] + comps = [comp for _,comp,_ in self.constraints] + b = [bb for *_,bb in [ (r,c,bb) for r,c,bb in self.constraints]] + + # expand free vars + A2, c2, mapping, var_names = self._expand_free(A, self.c, self.nonneg) + + # build phase1 tableau + T1 = Tableau.from_phase1(A2, comps, b, orig_var_names=var_names, objective_type=self.objective_type) + + if verbose: + print("\n--- Fase 1 (zerar artificiais) ---\n") + status1 = T1.run_simplex(verbose=verbose) + if status1 == "unbounded": + if verbose: print("Fase 1: ilimitado") + return None + phase1_obj = T1.tableau[-1][-1] + if abs(phase1_obj) > 1e-8: + if verbose: print("Problema inviável (fase1 != 0). Valor:", phase1_obj) + return None + + # Remove artificiais (robusto) + T2 = T1.remove_artificials() + + print("\n--- DEBUG: Tableau após remove_artificials() ---") + for row in T2.tableau: + print(row) + print("Base:", T2.base_vars) + print("Variáveis:", T2.var_names) + print("Tipos:", T2.col_types) + + # Append objective row placeholder (zeros) to T2.tableau for consistent shape + # Ensure objective row exists with correct length + if len(T2.tableau) == 0 or len(T2.tableau[-1]) != len(T2.tableau[0]): + # build a zero objective row with RHS zero + obj_row = [0.0]*len(T2.tableau[0]) + T2.tableau.append(obj_row) + else: + # ensure there's an objective row (if not present) + if len(T2.tableau) == len(T2.tableau[0]): + T2.tableau.append([0.0]*len(T2.tableau[0])) + + # Set original objective + T2.set_objective_from_original(c2, objective_type=self.objective_type) + + if verbose: + print("\n--- Fase 2 (otimização da função objetivo original) ---\n") + status2 = T2.run_simplex(verbose=verbose) + if status2 == "unbounded": + if verbose: print("Problema ilimitado (fase2).") + return None + + # extract expanded solution + orig_count = len(c2) + sol_expanded = T2.extract_solution_expanded(orig_count) + + # map back to original variables + orig_solution = {} + for orig_idx, mapped in enumerate(mapping): + if len(mapped) == 2: + p, n = mapped + vp = sol_expanded[p] if p < len(sol_expanded) else 0.0 + vn = sol_expanded[n] if n < len(sol_expanded) else 0.0 + orig_solution[f"x{orig_idx+1}"] = vp - vn else: - sol[col] = 0.0 - return sol + idx = mapped[0] + orig_solution[f"x{orig_idx+1}"] = sol_expanded[idx] if idx < len(sol_expanded) else 0.0 + + z = T2.tableau[-1][-1] + if self.objective_type == "Min": + z = -z + + return { + "z": z, + "original_solution": orig_solution, + "phase1_obj": phase1_obj, + "status_phase1": status1, + "status_phase2": status2 + } + +def run_from_input(path="input/input.txt", verbose=True): + p = Parser(path) + model = p.parse() + solver = SimplexSolver(model) + return solver.solve(verbose=verbose) + +# Expose Parser for run_from_input +from parser import Parser From 1f7e4368c73b1c7a2a9dc1de396908b44e70c029 Mon Sep 17 00:00:00 2001 From: IgorSPinto Date: Sat, 22 Nov 2025 20:12:55 -0300 Subject: [PATCH 05/15] refactor Tableau class to improve initialization and enhance tableau management --- main/tableau.py | 244 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 198 insertions(+), 46 deletions(-) diff --git a/main/tableau.py b/main/tableau.py index 2e6dd7f..a89c67a 100644 --- a/main/tableau.py +++ b/main/tableau.py @@ -1,62 +1,214 @@ +# tableau.py +EPS = 1e-9 + class Tableau: - def __init__(self, A, b, c, objective_type): - """ - A = constraints matrix - b = independent terms - c = coefficients of the objective function - objective_type = "Max" or "Min" - """ - - self.A = A - self.b = b - self.c = c + def __init__(self, tableau_rows, col_types, var_names, base_vars, objective_type="Max"): + self.tableau = [row[:] for row in tableau_rows] + self.col_types = col_types[:] + self.var_names = var_names[:] + self.base_vars = base_vars[:] self.objective_type = objective_type - self.num_constraints = len(A) - self.num_vars = len(c) + @classmethod + def from_phase1(cls, A, comps, b, orig_var_names=None, objective_type="Max"): + m = len(A) + n = len(A[0]) if m > 0 else 0 + tableau = [row[:] for row in A] + col_types = ['orig'] * n + var_names = orig_var_names[:] if orig_var_names else [f"x{j+1}" for j in range(n)] + base_vars = [None]*m + + slack_count = 0 + artificial_count = 0 - self.var_names = [f"x{i+1}" for i in range(self.num_vars)] + for i, comp in enumerate(comps): + if comp == "<=": + for r in range(m): + tableau[r].append(1.0 if r == i else 0.0) + col_types.append("slack") + var_names.append(f"s{slack_count+1}") + base_vars[i] = n + slack_count + slack_count += 1 - self.base_vars = [f"w{i+1}" for i in range(self.num_constraints)] + elif comp == ">=": + for r in range(m): + tableau[r].append(-1.0 if r == i else 0.0) + col_types.append("surplus") + var_names.append(f"e{slack_count+1}") + slack_count += 1 - self.build_tableau() + for r in range(m): + tableau[r].append(1.0 if r == i else 0.0) + col_types.append("artificial") + var_names.append(f"a{artificial_count+1}") + base_vars[i] = n + slack_count + artificial_count += 1 + slack_count += 1 - def build_tableau(self): - n = self.num_vars - m = self.num_constraints + elif comp == "=": + for r in range(m): + tableau[r].append(1.0 if r == i else 0.0) + col_types.append("artificial") + var_names.append(f"a{artificial_count+1}") + base_vars[i] = n + slack_count + artificial_count += 1 + slack_count += 1 - self.tableau = [] for i in range(m): - row = self.A[i] + [0] * m + [self.b[i]] - row[n + i] = 1 - self.tableau.append(row) + tableau[i].append(b[i]) - if self.objective_type == "Max": - obj = [-ci for ci in self.c] - else: # Min - obj = self.c[:] + total_cols = len(tableau[0]) + obj_row = [0.0]*total_cols + for j,t in enumerate(col_types): + if t == "artificial": + obj_row[j] = -1.0 + tableau.append(obj_row) - obj = obj + [0] * m + [0] - self.tableau.append(obj) + for i in range(m): + bv = base_vars[i] + if bv is not None and col_types[bv] == "artificial": + tableau[-1] = [tableau[-1][j] + tableau[i][j] for j in range(total_cols)] - def print_tableau(self, iteration=0): - Cabecalho = ["VB", "-Z"] + self.var_names + self.base_vars + ["b"] - largura = 6 + return cls(tableau, col_types, var_names, base_vars, objective_type) + def print_tableau(self, iteration=0): + m = len(self.tableau)-1 + header = ["VB"] + self.var_names + ["b"] print(f"=== Iteracao: {iteration} ===") - print(f"{Cabecalho[0]:>15}", end="") - for elemento in Cabecalho[1:]: - print(f"{elemento:>{largura}}", end="") - print() - - for i, var in enumerate(self.base_vars): - print(f"{var:>15}", end="") - for valor in self.tableau[i]: - print(f"{valor:>{largura}.2f}", end="") + print("".join(f"{h:>10}" for h in header)) + + for i in range(m): + bv = self.base_vars[i] + vb = self.var_names[bv] if bv is not None else "?" + print(f"{vb:>10}", end="") + for v in self.tableau[i]: + print(f"{v:>10.4f}", end="") print() - print(f"{'-Z':>15}", end="") - for valor in self.tableau[-1]: - print(f"{valor:>{largura}.2f}", end="") - print() - print() + print(f"{'OBJ':>10}", end="") + for v in self.tableau[-1]: + print(f"{v:>10.4f}", end="") + print("\n") + + def find_pivot(self): + last = self.tableau[-1] + min_val = min(last[:-1]) + if min_val >= -EPS: + return None + pivot_col = last[:-1].index(min_val) + + ratios = [] + for i in range(len(self.tableau)-1): + a = self.tableau[i][pivot_col] + if a > EPS: + ratios.append((self.tableau[i][-1]/a, i)) + + if not ratios: + return ("unbounded", pivot_col) + + ratios.sort(key=lambda x: (x[0], x[1])) + return ratios[0][1], pivot_col + + def pivot(self, r, c): + pv = self.tableau[r][c] + self.tableau[r] = [v / pv for v in self.tableau[r]] + + for i in range(len(self.tableau)): + if i == r: + continue + f = self.tableau[i][c] + self.tableau[i] = [ + self.tableau[i][j] - f*self.tableau[r][j] for j in range(len(self.tableau[0])) + ] + + self.base_vars[r] = c + + def run_simplex(self, verbose=True, max_iter=500): + it = 0 + while True: + it += 1 + + # Só imprime quando a linha OBJ já existe e tem o tamanho correto + if verbose and len(self.tableau[-1]) == len(self.tableau[0]): + self.print_tableau(iteration=it) + + pv = self.find_pivot() + if pv is None: + return "optimal" + if pv[0] == "unbounded": + return "unbounded" + + r, c = pv + self.pivot(r, c) + + if it >= max_iter: + return "max_iter" + + def remove_artificials(self): + cols_to_remove = [i for i,t in enumerate(self.col_types) if t == "artificial"] + + remap = {} + jnew = 0 + for j in range(len(self.col_types)): + if j not in cols_to_remove: + remap[j] = jnew + jnew += 1 + + new_col_types = [t for i,t in enumerate(self.col_types) if i not in cols_to_remove] + new_var_names = [v for i,v in enumerate(self.var_names) if i not in cols_to_remove] + + new_tableau = [] + for i in range(len(self.tableau)-1): + new_tableau.append([ + val for j,val in enumerate(self.tableau[i]) if j not in cols_to_remove + ]) + + new_base = [] + for bv in self.base_vars: + if bv in remap: + new_base.append(remap[bv]) + else: + new_base.append(None) + + return Tableau(new_tableau, new_col_types, new_var_names, new_base, self.objective_type) + + def set_objective_from_original(self, c_orig, objective_type="Max"): + total_cols = len(self.tableau[0]) + obj = [0.0]*total_cols + + orig_idx = [i for i,t in enumerate(self.col_types) if t == "orig"] + for k,j in enumerate(orig_idx): + if k < len(c_orig): + obj[j] = -c_orig[k] if objective_type=="Max" else c_orig[k] + + obj[-1] = 0.0 + + for i in range(len(self.tableau)-1): + bv = self.base_vars[i] + if bv is not None and abs(obj[bv]) > EPS: + f = obj[bv] + obj = [obj[j]-f*self.tableau[i][j] for j in range(len(obj))] + + self.tableau.append(obj) + + def extract_solution_expanded(self, k): + m = len(self.tableau)-1 + sol = [0.0]*k + + for col in range(k): + row = None + ok = True + + for i in range(m): + if abs(self.tableau[i][col]-1) < EPS: + if row is not None: + ok = False + break + row = i + elif abs(self.tableau[i][col]) > EPS: + ok = False + break + + sol[col] = self.tableau[row][-1] if ok and row is not None else 0.0 + + return sol From ec4c312125d0cab162b5cf1dc33aec9a2425299d Mon Sep 17 00:00:00 2001 From: IgorSPinto Date: Mon, 24 Nov 2025 17:23:00 -0300 Subject: [PATCH 06/15] refactor SimplexSolver and Tableau classes to enhance variable handling, improve tableau construction, and streamline objective row management --- main/simplex.py | 109 +++++++++++++++++------------- main/tableau.py | 171 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 177 insertions(+), 103 deletions(-) diff --git a/main/simplex.py b/main/simplex.py index c43bb13..923cff3 100644 --- a/main/simplex.py +++ b/main/simplex.py @@ -1,7 +1,6 @@ # simplex.py from parser import Parser from tableau import Tableau -import copy EPS = 1e-9 @@ -11,17 +10,23 @@ def __init__(self, model): self.c = [float(x) for x in model["objective_coeffs"]] else: self.c = [float(x) for x in model["c"]] + self.objective_type = model["objective_type"] self.constraints = model["constraints"] self.nonneg = model.get("non_negative", model.get("nonneg")) self.n = model["num_vars"] + # ========================================================== + # Expansão de variáveis livres (x = x⁺ - x⁻) + # ========================================================== def _expand_free(self, A_rows, c, nonneg): mapping = [] var_names = [] cur = 0 + for i in range(len(c)): if not nonneg[i]: + # variável livre → vira duas não-negativas mapping.append((cur, cur+1)) var_names.append(f"x{i+1}_pos") var_names.append(f"x{i+1}_neg") @@ -30,8 +35,11 @@ def _expand_free(self, A_rows, c, nonneg): mapping.append((cur,)) var_names.append(f"x{i+1}") cur += 1 + new_n = cur - c2 = [0.0]*new_n + c2 = [0.0] * new_n + + # Expande objetivo for i in range(len(c)): idxs = mapping[i] if len(idxs) == 2: @@ -39,9 +47,11 @@ def _expand_free(self, A_rows, c, nonneg): c2[idxs[1]] += -c[i] else: c2[idxs[0]] += c[i] + + # Expande restrições A2 = [] for row in A_rows: - new_row = [0.0]*new_n + new_row = [0.0] * new_n for i in range(len(c)): idxs = mapping[i] if len(idxs) == 2: @@ -50,77 +60,81 @@ def _expand_free(self, A_rows, c, nonneg): else: new_row[idxs[0]] += row[i] A2.append(new_row) + return A2, c2, mapping, var_names + # ========================================================== + # Resolver + # ========================================================== def solve(self, verbose=True): - A = [row for row,_,_ in self.constraints] - comps = [comp for _,comp,_ in self.constraints] - b = [bb for *_,bb in [ (r,c,bb) for r,c,bb in self.constraints]] + # A, comp, b + A = [row for row, _, _ in self.constraints] + comps = [comp for _, comp, _ in self.constraints] + b = [bb for *_, bb in self.constraints] - # expand free vars + # Expande variáveis livres A2, c2, mapping, var_names = self._expand_free(A, self.c, self.nonneg) - # build phase1 tableau - T1 = Tableau.from_phase1(A2, comps, b, orig_var_names=var_names, objective_type=self.objective_type) + # ------------------------------------------------------ + # FASE 1: construir tableau + # ------------------------------------------------------ + T1 = Tableau.from_phase1(A2, comps, b, orig_var_names=var_names, + objective_type=self.objective_type) if verbose: print("\n--- Fase 1 (zerar artificiais) ---\n") - status1 = T1.run_simplex(verbose=verbose) - if status1 == "unbounded": - if verbose: print("Fase 1: ilimitado") + + status_phase1 = T1.run_simplex(verbose=verbose) + + if status_phase1 == "unbounded": + if verbose: + print("Fase 1: ilimitado.") return None + phase1_obj = T1.tableau[-1][-1] - if abs(phase1_obj) > 1e-8: - if verbose: print("Problema inviável (fase1 != 0). Valor:", phase1_obj) + + if abs(phase1_obj) > 1e-7: + if verbose: + print("Problema inviável (valor da Fase 1 != 0).") return None - # Remove artificiais (robusto) + # ------------------------------------------------------ + # Remover artificiais para iniciar Fase 2 + # ------------------------------------------------------ T2 = T1.remove_artificials() - print("\n--- DEBUG: Tableau após remove_artificials() ---") - for row in T2.tableau: - print(row) - print("Base:", T2.base_vars) - print("Variáveis:", T2.var_names) - print("Tipos:", T2.col_types) - - # Append objective row placeholder (zeros) to T2.tableau for consistent shape - # Ensure objective row exists with correct length - if len(T2.tableau) == 0 or len(T2.tableau[-1]) != len(T2.tableau[0]): - # build a zero objective row with RHS zero - obj_row = [0.0]*len(T2.tableau[0]) - T2.tableau.append(obj_row) - else: - # ensure there's an objective row (if not present) - if len(T2.tableau) == len(T2.tableau[0]): - T2.tableau.append([0.0]*len(T2.tableau[0])) - - # Set original objective + # Criar linha OBJ (fase 2) + # Substituir por objetivo original (não adicionar linha extra antes; método já cria a linha OBJ) T2.set_objective_from_original(c2, objective_type=self.objective_type) if verbose: print("\n--- Fase 2 (otimização da função objetivo original) ---\n") - status2 = T2.run_simplex(verbose=verbose) - if status2 == "unbounded": - if verbose: print("Problema ilimitado (fase2).") + + status_phase2 = T2.run_simplex(verbose=verbose) + + if status_phase2 == "unbounded": + if verbose: + print("Problema ilimitado (fase 2).") return None - # extract expanded solution - orig_count = len(c2) - sol_expanded = T2.extract_solution_expanded(orig_count) + # ------------------------------------------------------ + # Recuperar solução das variáveis expandidas + # ------------------------------------------------------ + sol_expanded = T2.extract_solution_expanded(len(c2)) - # map back to original variables + # Remapear para x originais orig_solution = {} for orig_idx, mapped in enumerate(mapping): if len(mapped) == 2: p, n = mapped - vp = sol_expanded[p] if p < len(sol_expanded) else 0.0 - vn = sol_expanded[n] if n < len(sol_expanded) else 0.0 + vp = sol_expanded[p] if p < len(sol_expanded) else 0 + vn = sol_expanded[n] if n < len(sol_expanded) else 0 orig_solution[f"x{orig_idx+1}"] = vp - vn else: idx = mapped[0] - orig_solution[f"x{orig_idx+1}"] = sol_expanded[idx] if idx < len(sol_expanded) else 0.0 + orig_solution[f"x{orig_idx+1}"] = sol_expanded[idx] if idx < len(sol_expanded) else 0 + # Valor ótimo z = T2.tableau[-1][-1] if self.objective_type == "Min": z = -z @@ -129,15 +143,16 @@ def solve(self, verbose=True): "z": z, "original_solution": orig_solution, "phase1_obj": phase1_obj, - "status_phase1": status1, - "status_phase2": status2 + "status_phase1": status_phase1, + "status_phase2": status_phase2 } + +# Interface simples def run_from_input(path="input/input.txt", verbose=True): p = Parser(path) model = p.parse() solver = SimplexSolver(model) return solver.solve(verbose=verbose) -# Expose Parser for run_from_input from parser import Parser diff --git a/main/tableau.py b/main/tableau.py index a89c67a..032efad 100644 --- a/main/tableau.py +++ b/main/tableau.py @@ -4,83 +4,115 @@ class Tableau: def __init__(self, tableau_rows, col_types, var_names, base_vars, objective_type="Max"): self.tableau = [row[:] for row in tableau_rows] - self.col_types = col_types[:] - self.var_names = var_names[:] - self.base_vars = base_vars[:] + self.col_types = col_types[:] # orig, slack, surplus, artificial + self.var_names = var_names[:] # nomes das colunas + self.base_vars = base_vars[:] # índice da coluna básica por linha self.objective_type = objective_type + # ========================================================== + # FASE 1 - Construção do tableau + # ========================================================== @classmethod def from_phase1(cls, A, comps, b, orig_var_names=None, objective_type="Max"): m = len(A) n = len(A[0]) if m > 0 else 0 + tableau = [row[:] for row in A] + col_types = ['orig'] * n var_names = orig_var_names[:] if orig_var_names else [f"x{j+1}" for j in range(n)] - base_vars = [None]*m + base_vars = [None] * m slack_count = 0 artificial_count = 0 for i, comp in enumerate(comps): + + # <= ---> + slack if comp == "<=": + col = len(col_types) for r in range(m): tableau[r].append(1.0 if r == i else 0.0) + col_types.append("slack") var_names.append(f"s{slack_count+1}") - base_vars[i] = n + slack_count + base_vars[i] = col slack_count += 1 + # >= ---> surplus (-1) + artificial (+1) elif comp == ">=": + # Surplus + col_surp = len(col_types) for r in range(m): tableau[r].append(-1.0 if r == i else 0.0) + col_types.append("surplus") var_names.append(f"e{slack_count+1}") slack_count += 1 + # Artificial + col_art = len(col_types) for r in range(m): tableau[r].append(1.0 if r == i else 0.0) + col_types.append("artificial") var_names.append(f"a{artificial_count+1}") - base_vars[i] = n + slack_count + base_vars[i] = col_art artificial_count += 1 - slack_count += 1 + # = ---> + artificial elif comp == "=": + col_art = len(col_types) for r in range(m): tableau[r].append(1.0 if r == i else 0.0) + col_types.append("artificial") var_names.append(f"a{artificial_count+1}") - base_vars[i] = n + slack_count + base_vars[i] = col_art artificial_count += 1 - slack_count += 1 + # coluna b for i in range(m): tableau[i].append(b[i]) + # ========================================================== + # Linha OBJ da fase 1: minimizar soma das artificiais → coef −1 + # ========================================================== total_cols = len(tableau[0]) - obj_row = [0.0]*total_cols - for j,t in enumerate(col_types): + obj_row = [0.0] * total_cols + + for j, t in enumerate(col_types): if t == "artificial": obj_row[j] = -1.0 + + # adiciona linha obj tableau.append(obj_row) + # corrige linha OBJ adicionando linhas com artificiais básicas for i in range(m): bv = base_vars[i] if bv is not None and col_types[bv] == "artificial": - tableau[-1] = [tableau[-1][j] + tableau[i][j] for j in range(total_cols)] + tableau[-1] = [ + tableau[-1][j] + tableau[i][j] + for j in range(total_cols) + ] return cls(tableau, col_types, var_names, base_vars, objective_type) + # ========================================================== + # Impressão do tableau + # ========================================================== def print_tableau(self, iteration=0): - m = len(self.tableau)-1 + m = len(self.tableau) - 1 header = ["VB"] + self.var_names + ["b"] + print(f"=== Iteracao: {iteration} ===") print("".join(f"{h:>10}" for h in header)) for i in range(m): bv = self.base_vars[i] - vb = self.var_names[bv] if bv is not None else "?" - print(f"{vb:>10}", end="") + vb_name = self.var_names[bv] if bv is not None else "?" + print(f"{vb_name:>10}", end="") for v in self.tableau[i]: print(f"{v:>10.4f}", end="") print() @@ -90,23 +122,42 @@ def print_tableau(self, iteration=0): print(f"{v:>10.4f}", end="") print("\n") + # ========================================================== + # Simplex pivot (FASE 1 e FASE 2) + # ========================================================== def find_pivot(self): last = self.tableau[-1] - min_val = min(last[:-1]) - if min_val >= -EPS: - return None - pivot_col = last[:-1].index(min_val) - + # Detect Phase 1 (artificials still present). In Phase 1 we are + # maximizing -w (row built as negative of the sum of artificials). + # So entering column should have POSITIVE coefficient. + phase1 = any(t == "artificial" for t in self.col_types) + + if phase1: + # Choose column with largest positive coefficient + candidates = [(val, j) for j, val in enumerate(last[:-1]) if val > EPS] + if not candidates: + return None # Optimal for Phase 1 (all artificials driven to zero) + # pick with max positive value + _, pivot_col = max(candidates, key=lambda x: x[0]) + else: + # Phase 2 (standard maximization with negative costs in row) + candidates = [(val, j) for j, val in enumerate(last[:-1]) if val < -EPS] + if not candidates: + return None # Optimal for Phase 2 + # pick most negative + _, pivot_col = min(candidates, key=lambda x: x[0]) + + # Ratio test (same for both phases): need a_ij > 0 ratios = [] - for i in range(len(self.tableau)-1): + for i in range(len(self.tableau) - 1): a = self.tableau[i][pivot_col] if a > EPS: - ratios.append((self.tableau[i][-1]/a, i)) + ratios.append((self.tableau[i][-1] / a, i)) if not ratios: return ("unbounded", pivot_col) - ratios.sort(key=lambda x: (x[0], x[1])) + ratios.sort() return ratios[0][1], pivot_col def pivot(self, r, c): @@ -114,23 +165,24 @@ def pivot(self, r, c): self.tableau[r] = [v / pv for v in self.tableau[r]] for i in range(len(self.tableau)): - if i == r: - continue - f = self.tableau[i][c] - self.tableau[i] = [ - self.tableau[i][j] - f*self.tableau[r][j] for j in range(len(self.tableau[0])) - ] + if i != r: + f = self.tableau[i][c] + self.tableau[i] = [ + self.tableau[i][j] - f * self.tableau[r][j] + for j in range(len(self.tableau[0])) + ] self.base_vars[r] = c - def run_simplex(self, verbose=True, max_iter=500): + # ========================================================== + # Loop do simplex + # ========================================================== + def run_simplex(self, verbose=True, max_iter=200): it = 0 while True: it += 1 - - # Só imprime quando a linha OBJ já existe e tem o tamanho correto - if verbose and len(self.tableau[-1]) == len(self.tableau[0]): - self.print_tableau(iteration=it) + if verbose: + self.print_tableau(it) pv = self.find_pivot() if pv is None: @@ -144,8 +196,11 @@ def run_simplex(self, verbose=True, max_iter=500): if it >= max_iter: return "max_iter" + # ========================================================== + # Remover artificiais para Fase 2 + # ========================================================== def remove_artificials(self): - cols_to_remove = [i for i,t in enumerate(self.col_types) if t == "artificial"] + cols_to_remove = [i for i, t in enumerate(self.col_types) if t == "artificial"] remap = {} jnew = 0 @@ -154,53 +209,58 @@ def remove_artificials(self): remap[j] = jnew jnew += 1 - new_col_types = [t for i,t in enumerate(self.col_types) if i not in cols_to_remove] - new_var_names = [v for i,v in enumerate(self.var_names) if i not in cols_to_remove] + new_col_types = [t for i, t in enumerate(self.col_types) if i not in cols_to_remove] + new_var_names = [v for i, v in enumerate(self.var_names) if i not in cols_to_remove] new_tableau = [] - for i in range(len(self.tableau)-1): + for i in range(len(self.tableau) - 1): new_tableau.append([ - val for j,val in enumerate(self.tableau[i]) if j not in cols_to_remove + val for j, val in enumerate(self.tableau[i]) if j not in cols_to_remove ]) new_base = [] for bv in self.base_vars: - if bv in remap: - new_base.append(remap[bv]) - else: - new_base.append(None) + new_base.append(remap.get(bv, None)) return Tableau(new_tableau, new_col_types, new_var_names, new_base, self.objective_type) + # ========================================================== + # Linha objetivo da Fase 2 + # ========================================================== def set_objective_from_original(self, c_orig, objective_type="Max"): total_cols = len(self.tableau[0]) - obj = [0.0]*total_cols + obj = [0.0] * total_cols - orig_idx = [i for i,t in enumerate(self.col_types) if t == "orig"] - for k,j in enumerate(orig_idx): - if k < len(c_orig): - obj[j] = -c_orig[k] if objective_type=="Max" else c_orig[k] + orig_idx = [i for i, t in enumerate(self.col_types) if t == "orig"] - obj[-1] = 0.0 + for k, j in enumerate(orig_idx): + if k < len(c_orig): + obj[j] = -c_orig[k] if objective_type == "Max" else c_orig[k] - for i in range(len(self.tableau)-1): + # Ajustar com base + for i in range(len(self.tableau) - 1): bv = self.base_vars[i] if bv is not None and abs(obj[bv]) > EPS: f = obj[bv] - obj = [obj[j]-f*self.tableau[i][j] for j in range(len(obj))] + obj = [ + obj[j] - f * self.tableau[i][j] + for j in range(total_cols) + ] self.tableau.append(obj) + # ========================================================== + # Extração da solução expandida + # ========================================================== def extract_solution_expanded(self, k): - m = len(self.tableau)-1 - sol = [0.0]*k + m = len(self.tableau) - 1 + sol = [0.0] * k for col in range(k): row = None ok = True - for i in range(m): - if abs(self.tableau[i][col]-1) < EPS: + if abs(self.tableau[i][col] - 1) < EPS: if row is not None: ok = False break @@ -208,7 +268,6 @@ def extract_solution_expanded(self, k): elif abs(self.tableau[i][col]) > EPS: ok = False break - sol[col] = self.tableau[row][-1] if ok and row is not None else 0.0 return sol From 8d0ce9a1f2339a355eef721f911f8b92c008b721 Mon Sep 17 00:00:00 2001 From: EricoMeger Date: Sun, 23 Nov 2025 17:21:43 -0300 Subject: [PATCH 07/15] create bigM-based simplex, refactor tableau class --- main/input/input.txt | 6 +- main/main.py | 55 +++++-- main/simplex.py | 375 +++++++++++++++++++++++++------------------ main/tableau.py | 362 ++++++++++++----------------------------- main/temp.py | 121 -------------- 5 files changed, 368 insertions(+), 551 deletions(-) delete mode 100644 main/temp.py diff --git a/main/input/input.txt b/main/input/input.txt index 4ef8c26..f63fbca 100644 --- a/main/input/input.txt +++ b/main/input/input.txt @@ -1,5 +1,5 @@ -Max 2x1 + 3x2 -2x1 + x2 <= 10 -x1 + 3x2 <= 5 +Max 3x1 + 2x2 +2x1 + x2 <= 6 +3x1 + 2x2 <= 12 x1 >= 0 x2 >= 0 \ No newline at end of file diff --git a/main/main.py b/main/main.py index 8c805f0..1c1afd7 100644 --- a/main/main.py +++ b/main/main.py @@ -1,24 +1,49 @@ # main.py from parser import Parser -from simplex import SimplexSolver +from simplex import Simplex def main(): filepath = "input/input.txt" parser = Parser(filepath) - model = parser.parse() - - solver = SimplexSolver(model) - result = solver.solve(verbose=True) - - if result is None: - print("Problema inviável ou ilimitado.") + result = parser.parse() + + print("="*80) + print(f"Tipo: {result['objective_type']}") + print(f"Função Objetivo: {result['objective_coeffs']}") + print(f"Número de variáveis: {result['num_vars']}") + print(f"Restrições: {result['constraints']}") + print("="*80 + "\n") + + simplex = Simplex( + objective_coeffs=result['objective_coeffs'], + constraints=result['constraints'], + objective_type=result['objective_type'], + non_negative=result['non_negative'] + ) + + solution = simplex.solve() + + print() + print("="*80) + print("RESULTADO") + print("="*80) + print() + print(f"Status: {solution['status']}") + + if solution['status'] == 'optimal': + print(f"Valor ótimo: {solution['optimal_value']:.4f}") + print("Solução ótima:") + for i, val in enumerate(solution['solution'], start=1): + print(f" x{i} = {val:.4f}") + elif solution['status'] == 'unbounded': + print("O problema é ILIMITADO (unbounded)") + elif solution['status'] == 'infeasible': + print("O problema é INVIÁVEL (infeasible)") else: - print("\n=== Resultado ===") - print("Z ótimo:", result["z"]) - print("Solução (variáveis originais):") - for k,v in result["original_solution"].items(): - print(f" {k} = {v:.6f}") - print("\nDetalhes: phase1_obj =", result["phase1_obj"], ", status_phase1 =", result["status_phase1"], ", status_phase2 =", result["status_phase2"]) + print(f"Status desconhecido: {solution['status']}") + + print("="*80) + if __name__ == "__main__": - main() + main() \ No newline at end of file diff --git a/main/simplex.py b/main/simplex.py index 923cff3..c29531d 100644 --- a/main/simplex.py +++ b/main/simplex.py @@ -1,158 +1,225 @@ -# simplex.py -from parser import Parser +from typing import List, Tuple, Optional from tableau import Tableau -EPS = 1e-9 - -class SimplexSolver: - def __init__(self, model): - if "objective_coeffs" in model: - self.c = [float(x) for x in model["objective_coeffs"]] - else: - self.c = [float(x) for x in model["c"]] - - self.objective_type = model["objective_type"] - self.constraints = model["constraints"] - self.nonneg = model.get("non_negative", model.get("nonneg")) - self.n = model["num_vars"] - - # ========================================================== - # Expansão de variáveis livres (x = x⁺ - x⁻) - # ========================================================== - def _expand_free(self, A_rows, c, nonneg): - mapping = [] - var_names = [] - cur = 0 - - for i in range(len(c)): - if not nonneg[i]: - # variável livre → vira duas não-negativas - mapping.append((cur, cur+1)) - var_names.append(f"x{i+1}_pos") - var_names.append(f"x{i+1}_neg") - cur += 2 - else: - mapping.append((cur,)) - var_names.append(f"x{i+1}") - cur += 1 - - new_n = cur - c2 = [0.0] * new_n - - # Expande objetivo - for i in range(len(c)): - idxs = mapping[i] - if len(idxs) == 2: - c2[idxs[0]] += c[i] - c2[idxs[1]] += -c[i] - else: - c2[idxs[0]] += c[i] - - # Expande restrições - A2 = [] - for row in A_rows: - new_row = [0.0] * new_n - for i in range(len(c)): - idxs = mapping[i] - if len(idxs) == 2: - new_row[idxs[0]] += row[i] - new_row[idxs[1]] += -row[i] - else: - new_row[idxs[0]] += row[i] - A2.append(new_row) - - return A2, c2, mapping, var_names - - # ========================================================== - # Resolver - # ========================================================== - def solve(self, verbose=True): - # A, comp, b - A = [row for row, _, _ in self.constraints] - comps = [comp for _, comp, _ in self.constraints] - b = [bb for *_, bb in self.constraints] - - # Expande variáveis livres - A2, c2, mapping, var_names = self._expand_free(A, self.c, self.nonneg) - - # ------------------------------------------------------ - # FASE 1: construir tableau - # ------------------------------------------------------ - T1 = Tableau.from_phase1(A2, comps, b, orig_var_names=var_names, - objective_type=self.objective_type) - - if verbose: - print("\n--- Fase 1 (zerar artificiais) ---\n") - - status_phase1 = T1.run_simplex(verbose=verbose) - - if status_phase1 == "unbounded": - if verbose: - print("Fase 1: ilimitado.") - return None - - phase1_obj = T1.tableau[-1][-1] - - if abs(phase1_obj) > 1e-7: - if verbose: - print("Problema inviável (valor da Fase 1 != 0).") - return None - - # ------------------------------------------------------ - # Remover artificiais para iniciar Fase 2 - # ------------------------------------------------------ - T2 = T1.remove_artificials() - - # Criar linha OBJ (fase 2) - # Substituir por objetivo original (não adicionar linha extra antes; método já cria a linha OBJ) - T2.set_objective_from_original(c2, objective_type=self.objective_type) - - if verbose: - print("\n--- Fase 2 (otimização da função objetivo original) ---\n") - - status_phase2 = T2.run_simplex(verbose=verbose) - - if status_phase2 == "unbounded": - if verbose: - print("Problema ilimitado (fase 2).") - return None - - # ------------------------------------------------------ - # Recuperar solução das variáveis expandidas - # ------------------------------------------------------ - sol_expanded = T2.extract_solution_expanded(len(c2)) - - # Remapear para x originais - orig_solution = {} - for orig_idx, mapped in enumerate(mapping): - if len(mapped) == 2: - p, n = mapped - vp = sol_expanded[p] if p < len(sol_expanded) else 0 - vn = sol_expanded[n] if n < len(sol_expanded) else 0 - orig_solution[f"x{orig_idx+1}"] = vp - vn - else: - idx = mapped[0] - orig_solution[f"x{orig_idx+1}"] = sol_expanded[idx] if idx < len(sol_expanded) else 0 - - # Valor ótimo - z = T2.tableau[-1][-1] - if self.objective_type == "Min": - z = -z - +class Simplex: + def __init__(self, objective_coeffs: List[float], constraints: List[Tuple], + objective_type: str = "Max", non_negative: List[bool] = None): + """ + Args: + objective_coeffs: objective function coefficients + constraints: List of tuples (coefficients, operator, rhs) + objective_type: "Max" (only maximization is supported) + non_negative: List indicating if each variable is non-negative + """ + if objective_type != "Max": + raise ValueError("Only maximization is supported.") + + self.c = [float(x) for x in objective_coeffs] + self.constraints = constraints + self.objective_type = objective_type + self.num_vars = len(objective_coeffs) + self.non_negative = non_negative if non_negative else [True] * self.num_vars + + self.M = 1000000 + + self.tableau_obj = None + + self.artificial_indices = [] + + self.solution = None + self.optimal_value = None + + def solve(self) -> dict: + """ + Solves the LP problem using the Simplex method with Big M. + + Returns: + dict with 'status', 'solution', 'optimal_value' + """ + self.prepare_tableau() + + status = self.simplex_iterations() + + if status == "optimal": + self.extract_solution() + return { - "z": z, - "original_solution": orig_solution, - "phase1_obj": phase1_obj, - "status_phase1": status_phase1, - "status_phase2": status_phase2 + "status": status, + "solution": self.solution, + "optimal_value": self.optimal_value } - - -# Interface simples -def run_from_input(path="input/input.txt", verbose=True): - p = Parser(path) - model = p.parse() - solver = SimplexSolver(model) - return solver.solve(verbose=verbose) - -from parser import Parser + + def prepare_tableau(self): + """ + Prepares the initial tableau: + - Processes constraints + - Identifies which need slack/artificial variables + - Creates the tableau using the Tableau class + """ + A = [] + b = [] + slack_indices = [] + artificial_indices = [] + slack_types = {} + + for i, (coeffs, op, rhs) in enumerate(self.constraints): + coeffs = [float(x) for x in coeffs] + rhs = float(rhs) + + # if RHS is negative we multiply by -1 and invert the operator + if rhs < 0: + coeffs = [-x for x in coeffs] + rhs = -rhs + if op == "<=": + op = ">=" + elif op == ">=": + op = "<=" + + A.append(coeffs) + b.append(rhs) + + if op == "<=": + # add a slack variable with coefficient +1 + slack_indices.append(i) + slack_types[i] = 1.0 + + elif op == ">=": + # add a slack variable with coefficient -1 and a artificial variable + slack_indices.append(i) + slack_types[i] = -1.0 + artificial_indices.append(i) + + else: # op == "=" + # add only an artificial variable + artificial_indices.append(i) + + self.tableau_obj = Tableau(A, b, self.c) + self.tableau_obj.build_tableau( + slack_indices=slack_indices, + artificial_indices=artificial_indices, + M=self.M, + slack_types=slack_types + ) + + num_slack = len(slack_indices) + for i, idx in enumerate(artificial_indices): + col_idx = self.num_vars + num_slack + i + self.artificial_indices.append(col_idx) + + def simplex_iterations(self) -> str: + """ + Returns: + "optimal", "unbounded" or "infeasible" + """ + max_iterations = 1000 + iteration = 0 + + self.tableau_obj.print_tableau(iteration=0) + + while iteration < max_iterations: + iteration += 1 + + pivot_col = self.find_pivot_column() + + if pivot_col is None: + if self.check_artificial_in_basis(): + return "infeasible" + return "optimal" + + # find pivot row (variable leaving the basis) + pivot_row = self.find_pivot_row(pivot_col) + + if pivot_row is None: + return "unbounded" + + self.pivot(pivot_row, pivot_col) + + all_var_names = self.tableau_obj.get_all_var_names() + self.tableau_obj.basis[pivot_row] = all_var_names[pivot_col] + + self.tableau_obj.print_tableau(iteration=iteration) + + return "max_iterations_reached" + + def find_pivot_column(self) -> Optional[int]: + """ + Find the pivot column (non-basic variable with most negative coefficient). + Uses Bland's rule to avoid cycling. + + Returns: + Index of the pivot column or None if optimal + """ + obj_row = self.tableau_obj.tableau[-1][:-1] + + min_val = min(obj_row) + + if min_val >= -1e-10: + return None + + for i, val in enumerate(obj_row): + if abs(val - min_val) < 1e-10: + return i + + return None + + def find_pivot_row(self, pivot_col: int) -> Optional[int]: + m = len(self.tableau_obj.basis) + ratios = [] + + for i in range(m): + if self.tableau_obj.tableau[i][pivot_col] > 1e-10: + ratio = self.tableau_obj.tableau[i][-1] / self.tableau_obj.tableau[i][pivot_col] + ratios.append((ratio, i)) + else: + ratios.append((float('inf'), i)) + + valid_ratios = [(r, i) for r, i in ratios if r >= 0] + + if not valid_ratios: + return None # means that the problem is unbounded + + min_ratio = min(r for r, _ in valid_ratios) + + for r, i in valid_ratios: + if abs(r - min_ratio) < 1e-10: + return i + + return None + + def pivot(self, pivot_row: int, pivot_col: int): + pivot = self.tableau_obj.tableau[pivot_row][pivot_col] + num_cols = len(self.tableau_obj.tableau[0]) + + for j in range(num_cols): + self.tableau_obj.tableau[pivot_row][j] /= pivot + + for i in range(len(self.tableau_obj.tableau)): + if i != pivot_row: + multiplier = self.tableau_obj.tableau[i][pivot_col] + for j in range(num_cols): + self.tableau_obj.tableau[i][j] -= multiplier * self.tableau_obj.tableau[pivot_row][j] + + def check_artificial_in_basis(self) -> bool: + """ + Check for artificial variables in the basis with positive value. + If true, the problem is infeasible. + """ + all_var_names = self.tableau_obj.get_all_var_names() + + for i, var_name in enumerate(self.tableau_obj.basis): + if var_name.startswith('a'): + if self.tableau_obj.tableau[i][-1] > 1e-10: + return True + return False + + def extract_solution(self): + self.solution = [0.0] * self.num_vars + + all_var_names = self.tableau_obj.get_all_var_names() + + for i, var_name in enumerate(self.tableau_obj.basis): + if var_name and var_name.startswith('x'): + var_index = int(var_name[1:]) - 1 + self.solution[var_index] = self.tableau_obj.tableau[i][-1] + + self.optimal_value = self.tableau_obj.tableau[-1][-1] \ No newline at end of file diff --git a/main/tableau.py b/main/tableau.py index 032efad..204f79b 100644 --- a/main/tableau.py +++ b/main/tableau.py @@ -2,272 +2,118 @@ EPS = 1e-9 class Tableau: - def __init__(self, tableau_rows, col_types, var_names, base_vars, objective_type="Max"): - self.tableau = [row[:] for row in tableau_rows] - self.col_types = col_types[:] # orig, slack, surplus, artificial - self.var_names = var_names[:] # nomes das colunas - self.base_vars = base_vars[:] # índice da coluna básica por linha - self.objective_type = objective_type + def __init__(self, A, b, c): + """ + A = constraints matrix (lista de listas com coeficientes) + b = independent terms (lista com RHS das restrições) + c = coefficients of the objective function (lista) + """ + self.A = A + self.b = b + self.c = c + + self.num_constraints = len(A) + self.num_vars = len(c) + + self.var_names = [f"x{i+1}" for i in range(self.num_vars)] + + self.slack_vars = [] + self.artificial_vars = [] + + self.basis = [] + + self.tableau = [] + + def add_slack_variable(self, name=None): + if name is None: + name = f"w{len(self.slack_vars) + 1}" + self.slack_vars.append(name) + return name + + def add_artificial_variable(self, name=None): + if name is None: + name = f"a{len(self.artificial_vars) + 1}" + self.artificial_vars.append(name) + return name + + def build_tableau(self, slack_indices, artificial_indices=None, M=1000000, slack_types=None): + """ + Constrói o tableau do simplex. + + Args: + slack_indices: index list of constraints that receive slack variables + artificial_indices: index list of constraints that receive artificial variables + M: Big M penalty value for artificial variables + slack_types: dictionary {constraint_index: coef} where coef is 1 (<=) or -1 (>=) + """ + m = self.num_constraints + n = self.num_vars + num_slack = len(slack_indices) if slack_indices else 0 + num_artificial = len(artificial_indices) if artificial_indices else 0 + num_cols = n + num_slack + num_artificial + 1 + self.tableau = [[0.0] * num_cols for _ in range(m + 1)] - # ========================================================== - # FASE 1 - Construção do tableau - # ========================================================== - @classmethod - def from_phase1(cls, A, comps, b, orig_var_names=None, objective_type="Max"): - m = len(A) - n = len(A[0]) if m > 0 else 0 - - tableau = [row[:] for row in A] - - col_types = ['orig'] * n - var_names = orig_var_names[:] if orig_var_names else [f"x{j+1}" for j in range(n)] - base_vars = [None] * m - - slack_count = 0 - artificial_count = 0 - - for i, comp in enumerate(comps): - - # <= ---> + slack - if comp == "<=": - col = len(col_types) - for r in range(m): - tableau[r].append(1.0 if r == i else 0.0) - - col_types.append("slack") - var_names.append(f"s{slack_count+1}") - base_vars[i] = col - slack_count += 1 - - # >= ---> surplus (-1) + artificial (+1) - elif comp == ">=": - # Surplus - col_surp = len(col_types) - for r in range(m): - tableau[r].append(-1.0 if r == i else 0.0) - - col_types.append("surplus") - var_names.append(f"e{slack_count+1}") - slack_count += 1 - - # Artificial - col_art = len(col_types) - for r in range(m): - tableau[r].append(1.0 if r == i else 0.0) - - col_types.append("artificial") - var_names.append(f"a{artificial_count+1}") - base_vars[i] = col_art - artificial_count += 1 - - # = ---> + artificial - elif comp == "=": - col_art = len(col_types) - for r in range(m): - tableau[r].append(1.0 if r == i else 0.0) - - col_types.append("artificial") - var_names.append(f"a{artificial_count+1}") - base_vars[i] = col_art - artificial_count += 1 - - # coluna b for i in range(m): - tableau[i].append(b[i]) - - # ========================================================== - # Linha OBJ da fase 1: minimizar soma das artificiais → coef −1 - # ========================================================== - total_cols = len(tableau[0]) - obj_row = [0.0] * total_cols - - for j, t in enumerate(col_types): - if t == "artificial": - obj_row[j] = -1.0 - - # adiciona linha obj - tableau.append(obj_row) - - # corrige linha OBJ adicionando linhas com artificiais básicas - for i in range(m): - bv = base_vars[i] - if bv is not None and col_types[bv] == "artificial": - tableau[-1] = [ - tableau[-1][j] + tableau[i][j] - for j in range(total_cols) - ] - - return cls(tableau, col_types, var_names, base_vars, objective_type) + for j in range(n): + self.tableau[i][j] = float(self.A[i][j]) + self.tableau[i][-1] = float(self.b[i]) + + base = [None] * m + + slack_col = n + for idx in (slack_indices or []): + var_name = self.add_slack_variable() + coef = 1.0 if slack_types is None else slack_types.get(idx, 1.0) + self.tableau[idx][slack_col] = coef + if coef == 1.0: + base[idx] = var_name + slack_col += 1 + + artificial_col = n + num_slack + artificial_col_indices = [] + for idx in (artificial_indices or []): + var_name = self.add_artificial_variable() + self.tableau[idx][artificial_col] = 1.0 + base[idx] = var_name + artificial_col_indices.append(artificial_col) + artificial_col += 1 + + for j in range(n): + self.tableau[-1][j] = -float(self.c[j]) + + for col_idx in artificial_col_indices: + self.tableau[-1][col_idx] = M + if artificial_indices: + for idx in artificial_indices: + for j in range(num_cols): + self.tableau[-1][j] -= M * self.tableau[idx][j] + + self.basis = base + + def get_all_var_names(self): + return self.var_names + self.slack_vars + self.artificial_vars # ========================================================== # Impressão do tableau # ========================================================== def print_tableau(self, iteration=0): - m = len(self.tableau) - 1 - header = ["VB"] + self.var_names + ["b"] + all_vars = self.get_all_var_names() + cabecalho = ["VB"] + all_vars + ["b"] + largura = 8 print(f"=== Iteracao: {iteration} ===") - print("".join(f"{h:>10}" for h in header)) - - for i in range(m): - bv = self.base_vars[i] - vb_name = self.var_names[bv] if bv is not None else "?" - print(f"{vb_name:>10}", end="") - for v in self.tableau[i]: - print(f"{v:>10.4f}", end="") + print(f"{cabecalho[0]:>15}", end="") + for elemento in cabecalho[1:]: + print(f"{elemento:>{largura}}", end="") + print() + + for i, var in enumerate(self.basis): + print(f"{var:>15}", end="") + for valor in self.tableau[i]: + print(f"{valor:>{largura}.2f}", end="") print() - print(f"{'OBJ':>10}", end="") - for v in self.tableau[-1]: - print(f"{v:>10.4f}", end="") - print("\n") - - # ========================================================== - # Simplex pivot (FASE 1 e FASE 2) - # ========================================================== - def find_pivot(self): - last = self.tableau[-1] - # Detect Phase 1 (artificials still present). In Phase 1 we are - # maximizing -w (row built as negative of the sum of artificials). - # So entering column should have POSITIVE coefficient. - phase1 = any(t == "artificial" for t in self.col_types) - - if phase1: - # Choose column with largest positive coefficient - candidates = [(val, j) for j, val in enumerate(last[:-1]) if val > EPS] - if not candidates: - return None # Optimal for Phase 1 (all artificials driven to zero) - # pick with max positive value - _, pivot_col = max(candidates, key=lambda x: x[0]) - else: - # Phase 2 (standard maximization with negative costs in row) - candidates = [(val, j) for j, val in enumerate(last[:-1]) if val < -EPS] - if not candidates: - return None # Optimal for Phase 2 - # pick most negative - _, pivot_col = min(candidates, key=lambda x: x[0]) - - # Ratio test (same for both phases): need a_ij > 0 - ratios = [] - for i in range(len(self.tableau) - 1): - a = self.tableau[i][pivot_col] - if a > EPS: - ratios.append((self.tableau[i][-1] / a, i)) - - if not ratios: - return ("unbounded", pivot_col) - - ratios.sort() - return ratios[0][1], pivot_col - - def pivot(self, r, c): - pv = self.tableau[r][c] - self.tableau[r] = [v / pv for v in self.tableau[r]] - - for i in range(len(self.tableau)): - if i != r: - f = self.tableau[i][c] - self.tableau[i] = [ - self.tableau[i][j] - f * self.tableau[r][j] - for j in range(len(self.tableau[0])) - ] - - self.base_vars[r] = c - - # ========================================================== - # Loop do simplex - # ========================================================== - def run_simplex(self, verbose=True, max_iter=200): - it = 0 - while True: - it += 1 - if verbose: - self.print_tableau(it) - - pv = self.find_pivot() - if pv is None: - return "optimal" - if pv[0] == "unbounded": - return "unbounded" - - r, c = pv - self.pivot(r, c) - - if it >= max_iter: - return "max_iter" - - # ========================================================== - # Remover artificiais para Fase 2 - # ========================================================== - def remove_artificials(self): - cols_to_remove = [i for i, t in enumerate(self.col_types) if t == "artificial"] - - remap = {} - jnew = 0 - for j in range(len(self.col_types)): - if j not in cols_to_remove: - remap[j] = jnew - jnew += 1 - - new_col_types = [t for i, t in enumerate(self.col_types) if i not in cols_to_remove] - new_var_names = [v for i, v in enumerate(self.var_names) if i not in cols_to_remove] - - new_tableau = [] - for i in range(len(self.tableau) - 1): - new_tableau.append([ - val for j, val in enumerate(self.tableau[i]) if j not in cols_to_remove - ]) - - new_base = [] - for bv in self.base_vars: - new_base.append(remap.get(bv, None)) - - return Tableau(new_tableau, new_col_types, new_var_names, new_base, self.objective_type) - - # ========================================================== - # Linha objetivo da Fase 2 - # ========================================================== - def set_objective_from_original(self, c_orig, objective_type="Max"): - total_cols = len(self.tableau[0]) - obj = [0.0] * total_cols - - orig_idx = [i for i, t in enumerate(self.col_types) if t == "orig"] - - for k, j in enumerate(orig_idx): - if k < len(c_orig): - obj[j] = -c_orig[k] if objective_type == "Max" else c_orig[k] - - # Ajustar com base - for i in range(len(self.tableau) - 1): - bv = self.base_vars[i] - if bv is not None and abs(obj[bv]) > EPS: - f = obj[bv] - obj = [ - obj[j] - f * self.tableau[i][j] - for j in range(total_cols) - ] - - self.tableau.append(obj) - - # ========================================================== - # Extração da solução expandida - # ========================================================== - def extract_solution_expanded(self, k): - m = len(self.tableau) - 1 - sol = [0.0] * k - - for col in range(k): - row = None - ok = True - for i in range(m): - if abs(self.tableau[i][col] - 1) < EPS: - if row is not None: - ok = False - break - row = i - elif abs(self.tableau[i][col]) > EPS: - ok = False - break - sol[col] = self.tableau[row][-1] if ok and row is not None else 0.0 - - return sol + print(f"{'Z':>15}", end="") + for valor in self.tableau[-1]: + print(f"{valor:>{largura}.2f}", end="") + print() \ No newline at end of file diff --git a/main/temp.py b/main/temp.py deleted file mode 100644 index 20a8ccb..0000000 --- a/main/temp.py +++ /dev/null @@ -1,121 +0,0 @@ -# Método Simplex para Problemas Básicos - -def Ler_Modelo(): - - """ - Max Z = 3*x1 + 2*x2 - s.a - [R1] 2*x1 + 1*x2 = 6 - [R2] 3*x1 + 2*x2 <= 12 - x1, x2 < 0 - """ - c = [3, 2] - A = [[2, 1], - [3, 2]] - b = [6, 12] - VD = ['x1', 'x2'] - - return c, A, b, VD - -def Imprimir_Tableau(Base, Iter, Variaveis, Tableau): - - Cabecalho = ['VB', '-Z'] + Variaveis + ['b'] - Largura = 6 #para as colunas numéricas - - # Impressão - print(f'=== Iteracao: {Iter} ===') - print(f'{Cabecalho[0]:>15}', end="") - for elemento in Cabecalho[1:]: - print(f'{elemento:>{Largura}}', end="") - print() - - # Impressão das Variáveis Básicas - for i, var in enumerate(Base): - print(f'{var:>15}', end="") - for valor in Tableau[i]: - print(f'{valor:>{Largura}.2f}', end="") - print() - - # Impressão da FO - print(f'{"-Z":>15}', end="") - for valor in Tableau[-1]: - print(f'{valor:>{Largura}.2f}', end="") - print() - -def Metodo_Simplex(c, A, b, VD): - - # Contando VDs e Restrições - m = len(A) # Número de Restrições - n = len(c) # Número de VDs - - # Coeficiente das Restrições - Tableau = [] - for i in range(m): - linha = [0] + A[i][:] + [0]*m + [b[i]] - linha[n + i + 1] = 1 - Tableau.append(linha) - - # Coeficientes da FO - linha_FO = [1] + [-j for j in c] + [0]*m + [0] - Tableau.append(linha_FO) - - # Nomeando as variáveis de folga - Folgas = [f'w{i+1}' for i in range(m)] - VD_Folgas = VD + Folgas - Base = Folgas[:] - - Iter = 0 - Imprimir_Tableau(Base, Iter, VD_Folgas, Tableau) - print() - - # Loop Principal - while True: - Z_Linha = Tableau[-1][1:-1] # última linha do tableau, da primeira até a última coluna - Menor_Coef = min(Z_Linha) # Captura o coeficiente mais negativo - - if Menor_Coef >= 0: # Critério de Parada - print('\nSolução Ótima Encontrada') - break - - # Identificando a Variável que Entrará na Base - Coluna_Pivo = Z_Linha.index(Menor_Coef) + 1 - - # Identificando a Variável que Sairá da Base - Vetor_Bloqueio = [] - for i in range(m): - if Tableau[i][Coluna_Pivo] > 0: - Valor_Bloq = Tableau[i][-1] / Tableau[i][Coluna_Pivo] - else: - Valor_Bloq = float("inf") - Vetor_Bloqueio.append(Valor_Bloq) - Linha_Pivo = Vetor_Bloqueio.index(min(Vetor_Bloqueio)) - - # Identificando Solução Ilimitada - if min(Vetor_Bloqueio) == float("inf"): - print('\nSolução Ilimitada') - return - - # Normalização da Linha Pivô - Pivo = Tableau[Linha_Pivo][Coluna_Pivo] - for j in range(len(Tableau[Linha_Pivo])): - Tableau[Linha_Pivo][j] = (Tableau[Linha_Pivo][j] / Pivo) - - # Zerando as colunas acima e abaixo da linha pivô (escalonamento de Gauss) - for i in range(len(Tableau)): - if i != Linha_Pivo: - Fator = Tableau[i][Coluna_Pivo] - for j in range(len(Tableau[1])): - Tableau[i][j] = Tableau[i][j] - Fator*Tableau[Linha_Pivo][j] - - # Atualizando a Base - Base[Linha_Pivo] = VD_Folgas[Coluna_Pivo - 1] - - Iter = Iter + 1 - Imprimir_Tableau(Base, Iter, VD_Folgas, Tableau) - print() - - - -if __name__ == "__main__": - c, A, b, VD = Ler_Modelo() - Metodo_Simplex(c, A, b, VD) \ No newline at end of file From 40b57fffb37d30d6d1cd55d1a66dd729e5c0fbed Mon Sep 17 00:00:00 2001 From: EricoMeger Date: Sun, 23 Nov 2025 17:26:39 -0300 Subject: [PATCH 08/15] remove datatypes --- main/simplex.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/main/simplex.py b/main/simplex.py index c29531d..156920e 100644 --- a/main/simplex.py +++ b/main/simplex.py @@ -1,9 +1,8 @@ -from typing import List, Tuple, Optional from tableau import Tableau class Simplex: - def __init__(self, objective_coeffs: List[float], constraints: List[Tuple], - objective_type: str = "Max", non_negative: List[bool] = None): + def __init__(self, objective_coeffs, constraints, + objective_type="Max", non_negative=None): """ Args: objective_coeffs: objective function coefficients @@ -29,7 +28,7 @@ def __init__(self, objective_coeffs: List[float], constraints: List[Tuple], self.solution = None self.optimal_value = None - def solve(self) -> dict: + def solve(self): """ Solves the LP problem using the Simplex method with Big M. @@ -106,7 +105,7 @@ def prepare_tableau(self): col_idx = self.num_vars + num_slack + i self.artificial_indices.append(col_idx) - def simplex_iterations(self) -> str: + def simplex_iterations(self): """ Returns: "optimal", "unbounded" or "infeasible" @@ -141,7 +140,7 @@ def simplex_iterations(self) -> str: return "max_iterations_reached" - def find_pivot_column(self) -> Optional[int]: + def find_pivot_column(self): """ Find the pivot column (non-basic variable with most negative coefficient). Uses Bland's rule to avoid cycling. @@ -162,7 +161,7 @@ def find_pivot_column(self) -> Optional[int]: return None - def find_pivot_row(self, pivot_col: int) -> Optional[int]: + def find_pivot_row(self, pivot_col): m = len(self.tableau_obj.basis) ratios = [] @@ -186,7 +185,7 @@ def find_pivot_row(self, pivot_col: int) -> Optional[int]: return None - def pivot(self, pivot_row: int, pivot_col: int): + def pivot(self, pivot_row, pivot_col): pivot = self.tableau_obj.tableau[pivot_row][pivot_col] num_cols = len(self.tableau_obj.tableau[0]) @@ -199,7 +198,7 @@ def pivot(self, pivot_row: int, pivot_col: int): for j in range(num_cols): self.tableau_obj.tableau[i][j] -= multiplier * self.tableau_obj.tableau[pivot_row][j] - def check_artificial_in_basis(self) -> bool: + def check_artificial_in_basis(self): """ Check for artificial variables in the basis with positive value. If true, the problem is infeasible. From cad5c8b31d4dfcf638fe450a2fbd23eb39081550 Mon Sep 17 00:00:00 2001 From: EricoMeger Date: Mon, 24 Nov 2025 18:02:21 -0300 Subject: [PATCH 09/15] fix parser for professor's expected input --- main/input/input.txt | 21 ++++- main/parser.py | 179 +++++++++++++++++++++++-------------------- 2 files changed, 111 insertions(+), 89 deletions(-) diff --git a/main/input/input.txt b/main/input/input.txt index f63fbca..2c452ba 100644 --- a/main/input/input.txt +++ b/main/input/input.txt @@ -1,5 +1,18 @@ -Max 3x1 + 2x2 -2x1 + x2 <= 6 -3x1 + 2x2 <= 12 +MAX 3 x1 + 2 x2 + 10 x3 + 0 x4 + 2 x5 + +3 x1 + 1 x2 + 7 x3 + 10 x4 + 0 x5 <= 6 +1 x1 + 0 x2 + 7 x3 + 0 x4 + 9 x5 >= 46 +8 x1 + 0 x2 + 1 x3 + 1 x4 + 1 x5 >= 25 +3 x1 + 3 x2 + 1 x3 + 3 x4 + 9 x5 <= 29 +4 x1 + 4 x2 + 8 x3 + 7 x4 + 0 x5 = 19 +1 x1 + 10 x2 + 5 x3 + 10 x4 + 4 x5 <= 30 +0 x1 + 6 x2 + 1 x3 + 5 x4 + 2 x5 >= 50 +7 x1 + 5 x2 + 4 x3 + 3 x4 + 8 x5 >= 6 +8 x1 + 7 x2 + 5 x3 + 10 x4 + 6 x5 >= 33 +4 x1 + 7 x2 + 4 x3 + 3 x4 + 8 x5 <= 6 + x1 >= 0 -x2 >= 0 \ No newline at end of file +x2 >= 0 +x3 >= 0 +x4 <= 0 +x5 livre diff --git a/main/parser.py b/main/parser.py index aece900..3c15c35 100644 --- a/main/parser.py +++ b/main/parser.py @@ -24,60 +24,101 @@ def __init__(self, filepath): self.filepath = filepath def parse(self): - lines = [line.strip() for line in open(self.filepath, encoding="utf-8") if line.strip() and not line.strip().startswith("#")] - if not lines: - raise ValueError("Arquivo vazio") - - # objective - obj_line = lines[0] - if obj_line.lower().startswith("max"): - obj_type = "Max" - rest = obj_line[3:].strip() - elif obj_line.lower().startswith("min"): - obj_type = "Min" - rest = obj_line[3:].strip() - else: - raise ValueError("Função objetivo deve começar com 'Max' ou 'Min'") - - obj_coeffs = {} - for raw_coeff, var in re.findall(r'([+-]?\s*\d*)x(\d+)', rest): - coeff = raw_coeff.replace(" ", "") - if coeff == "" or coeff == "+": - c = 1 - elif coeff == "-": - c = -1 - else: - c = int(coeff) - idx = int(var) - obj_coeffs[idx] = obj_coeffs.get(idx, 0) + c + lines = [line.strip() for line in open(self.filepath)] - constraints = [] - nonneg = {} + self.parse_objective(lines[0]) for line in lines[1:]: - m_free = re.match(r'^x(\d+)\s+(free|livre)$', line, re.I) - m_nonneg = re.match(r'^x(\d+)\s*>=\s*0$', line) - if m_free: - var = int(m_free.group(1)) - nonneg[var] = False - continue - if m_nonneg: - var = int(m_nonneg.group(1)) - nonneg[var] = True - continue - - if "<=" in line or ">=" in line or "=" in line: - coeff_map = {} - for raw_coeff, var in re.findall(r'([+-]?\s*\d*)x(\d+)', line): - coeff = raw_coeff.replace(" ", "") - if coeff == "" or coeff == "+": - c = 1 - elif coeff == "-": - c = -1 - else: - c = int(coeff) - idx = int(var) - coeff_map[idx] = coeff_map.get(idx, 0) + c + if self.is_non_negative(line): + self.parse_non_negative(line) + elif "<=" in line or ">=" in line or "=" in line: + self.parse_constraint(line) + + #if some variables were not mentioned in non-negativity constraints, assume they are non-negative + while len(self.non_negative) < self.num_vars: + self.non_negative.append(True) + + return { + "objective_type": self.objective_type, + "objective_coeffs": self.objective_coeffs, + "constraints": self.constraints, + "num_vars": self.num_vars, + "non_negative": self.non_negative + } + + def is_non_negative(self, line): + return re.match(r"x\d+\s*(>=|<=)\s*0$", line) is not None or "livre" in line.lower() + + def parse_non_negative(self, line): + var_match = re.findall(r"x(\d+)", line) + if not var_match: + return + + var = int(var_match[0]) + + self.num_vars = max(self.num_vars, var) + + while len(self.non_negative) < var: + self.non_negative.append(True) + + if "livre" in line.lower(): + self.non_negative[var - 1] = False + elif "<=" in line: + self.non_negative[var - 1] = False + else: + self.non_negative[var - 1] = True + + def parse_objective(self, line): + line_lower = line.lower() + if line_lower.startswith("max"): + self.objective_type = "Max" + elif line_lower.startswith("min"): + self.objective_type = "Min" + else: + raise ValueError("Objective function must be Max or Min.") + + """ + Regex atualizado para aceitar espaços entre coeficiente e variável: + ([+-]?\s*\d*)\s* - coeficiente com possíveis espaços após + x\s*(\d+) - 'x' seguido de possíveis espaços e depois o índice + + Exemplos que funciona: + - "3x1" (sem espaço) + - "3 x1" (com espaço) + - "+ 3x1" (sinal com espaço) + - "+3 x1" (combinação) + """ + coeffs = re.findall(r'([+-]?\s*\d*)\s*x\s*(\d+)', line) + + for raw_coeff, var in coeffs: + raw_coeff = raw_coeff.replace(" ", "") + if raw_coeff == '+' or raw_coeff == '' or raw_coeff == '+ ': + raw_coeff = 1 + elif raw_coeff == '-': + raw_coeff = -1 + else: + raw_coeff = int(raw_coeff) + var = int(var) + self.num_vars = max(self.num_vars, var) + self.objective_coeffs.append((var, raw_coeff)) + + self.objective_coeffs = [c for _, c in sorted(self.objective_coeffs)] + + def parse_constraint(self, line): + coeffs = re.findall(r'([+-]?\s*\d*)\s*x\s*(\d+)', line) + parsed = [0] * (self.num_vars) + + for raw_coeff, var in coeffs: + raw_coeff = raw_coeff.replace(" ", "") + if raw_coeff == '' or raw_coeff == '+': + raw_coeff = 1 + elif raw_coeff == '-': + raw_coeff = -1 + else: + raw_coeff = int(raw_coeff) + + var = int(var) + parsed[var - 1] = raw_coeff if "<=" in line: comp = "<=" @@ -86,38 +127,6 @@ def parse(self): else: comp = "=" - b_match = re.search(r'(-?\d+)\s*$', line) - if not b_match: - raise ValueError("Não foi possível ler RHS na linha: " + line) - b = int(b_match.group(1)) - - constraints.append((coeff_map, comp, b)) - - all_idx = set(obj_coeffs.keys()) - for cm,_,_ in constraints: - all_idx |= set(cm.keys()) - all_idx |= set(nonneg.keys()) - n = max(all_idx) if all_idx else 0 - - c = [0.0]*n - for i in range(1, n+1): - c[i-1] = float(obj_coeffs.get(i, 0)) + b = int(re.findall(r'(-?\d+)$', line)[0]) - constraints_vec = [] - for coeff_map, comp, b in constraints: - row = [0.0]*n - for i in range(1, n+1): - row[i-1] = float(coeff_map.get(i, 0)) - constraints_vec.append((row, comp, float(b))) - - nonneg_list = [] - for i in range(1, n+1): - nonneg_list.append(nonneg.get(i, True)) - - return { - "objective_type": obj_type, - "objective_coeffs": c, - "constraints": constraints_vec, - "num_vars": n, - "non_negative": nonneg_list - } + self.constraints.append((parsed, comp, b)) From aa43d3c9b8f819f1a8e15bf4090d83199513db7a Mon Sep 17 00:00:00 2001 From: EricoMeger Date: Mon, 24 Nov 2025 18:32:15 -0300 Subject: [PATCH 10/15] consider variables constraints --- main/input/input.txt | 55 +++++++++++++++++++-------- main/main.py | 2 +- main/parser.py | 31 +++++++++++++-- main/simplex.py | 89 ++++++++++++++++++++++++++++++++++++++------ 4 files changed, 147 insertions(+), 30 deletions(-) diff --git a/main/input/input.txt b/main/input/input.txt index 2c452ba..883fe8d 100644 --- a/main/input/input.txt +++ b/main/input/input.txt @@ -1,18 +1,43 @@ -MAX 3 x1 + 2 x2 + 10 x3 + 0 x4 + 2 x5 +MAX 1 x1 + 7 x2 + 7 x3 + 8 x4 + 4 x5 + 6 x6 + 1 x7 + 10 x8 + 9 x9 + 8 x10 -3 x1 + 1 x2 + 7 x3 + 10 x4 + 0 x5 <= 6 -1 x1 + 0 x2 + 7 x3 + 0 x4 + 9 x5 >= 46 -8 x1 + 0 x2 + 1 x3 + 1 x4 + 1 x5 >= 25 -3 x1 + 3 x2 + 1 x3 + 3 x4 + 9 x5 <= 29 -4 x1 + 4 x2 + 8 x3 + 7 x4 + 0 x5 = 19 -1 x1 + 10 x2 + 5 x3 + 10 x4 + 4 x5 <= 30 -0 x1 + 6 x2 + 1 x3 + 5 x4 + 2 x5 >= 50 -7 x1 + 5 x2 + 4 x3 + 3 x4 + 8 x5 >= 6 -8 x1 + 7 x2 + 5 x3 + 10 x4 + 6 x5 >= 33 -4 x1 + 7 x2 + 4 x3 + 3 x4 + 8 x5 <= 6 +6 x1 + 2 x2 + 6 x3 + 7 x4 + 0 x5 + 2 x6 + 2 x7 + 5 x8 + 5 x9 + 10 x10 = 5 +0 x1 + 9 x2 + 10 x3 + 9 x4 + 3 x5 + 3 x6 + 4 x7 + 6 x8 + 6 x9 + 8 x10 <= 60 +1 x1 + 4 x2 + 1 x3 + 8 x4 + 6 x5 + 0 x6 + 6 x7 + 8 x8 + 4 x9 + 4 x10 <= 33 +3 x1 + 5 x2 + 3 x3 + 2 x4 + 10 x5 + 4 x6 + 0 x7 + 1 x8 + 7 x9 + 7 x10 <= 57 +7 x1 + 2 x2 + 3 x3 + 2 x4 + 9 x5 + 10 x6 + 6 x7 + 6 x8 + 9 x9 + 1 x10 <= 64 +6 x1 + 10 x2 + 8 x3 + 5 x4 + 9 x5 + 4 x6 + 8 x7 + 2 x8 + 9 x9 + 5 x10 <= 67 +7 x1 + 2 x2 + 10 x3 + 9 x4 + 3 x5 + 5 x6 + 8 x7 + 6 x8 + 4 x9 + 6 x10 <= 35 +8 x1 + 7 x2 + 4 x3 + 0 x4 + 5 x5 + 7 x6 + 0 x7 + 5 x8 + 4 x9 + 4 x10 <= 42 +4 x1 + 0 x2 + 3 x3 + 3 x4 + 1 x5 + 6 x6 + 6 x7 + 2 x8 + 6 x9 + 7 x10 <= 22 +2 x1 + 10 x2 + 6 x3 + 6 x4 + 4 x5 + 4 x6 + 4 x7 + 9 x8 + 3 x9 + 10 x10 <= 74 +1 x1 + 8 x2 + 10 x3 + 1 x4 + 5 x5 + 10 x6 + 7 x7 + 10 x8 + 8 x9 + 10 x10 <= 49 +4 x1 + 2 x2 + 0 x3 + 8 x4 + 1 x5 + 9 x6 + 4 x7 + 10 x8 + 0 x9 + 10 x10 <= 89 +0 x1 + 5 x2 + 7 x3 + 2 x4 + 10 x5 + 3 x6 + 5 x7 + 2 x8 + 6 x9 + 5 x10 <= 73 +10 x1 + 8 x2 + 2 x3 + 3 x4 + 0 x5 + 6 x6 + 7 x7 + 7 x8 + 8 x9 + 3 x10 <= 64 +4 x1 + 10 x2 + 10 x3 + 4 x4 + 9 x5 + 6 x6 + 4 x7 + 3 x8 + 1 x9 + 5 x10 <= 36 +3 x1 + 9 x2 + 2 x3 + 0 x4 + 7 x5 + 5 x6 + 1 x7 + 8 x8 + 4 x9 + 8 x10 <= 44 +2 x1 + 7 x2 + 8 x3 + 3 x4 + 2 x5 + 5 x6 + 9 x7 + 3 x8 + 3 x9 + 6 x10 <= 29 +1 x1 + 7 x2 + 9 x3 + 6 x4 + 9 x5 + 0 x6 + 3 x7 + 7 x8 + 5 x9 + 9 x10 <= 28 +8 x1 + 8 x2 + 7 x3 + 9 x4 + 3 x5 + 3 x6 + 7 x7 + 1 x8 + 2 x9 + 9 x10 <= 87 +3 x1 + 8 x2 + 5 x3 + 6 x4 + 9 x5 + 2 x6 + 0 x7 + 3 x8 + 10 x9 + 0 x10 <= 100 +9 x1 + 8 x2 + 6 x3 + 10 x4 + 5 x5 + 10 x6 + 7 x7 + 2 x8 + 6 x9 + 2 x10 <= 43 +1 x1 + 9 x2 + 0 x3 + 10 x4 + 3 x5 + 6 x6 + 5 x7 + 6 x8 + 9 x9 + 4 x10 <= 78 +7 x1 + 3 x2 + 6 x3 + 7 x4 + 4 x5 + 10 x6 + 5 x7 + 1 x8 + 3 x9 + 8 x10 <= 87 +3 x1 + 0 x2 + 9 x3 + 5 x4 + 0 x5 + 10 x6 + 6 x7 + 10 x8 + 6 x9 + 10 x10 <= 7 +9 x1 + 4 x2 + 5 x3 + 10 x4 + 7 x5 + 7 x6 + 9 x7 + 5 x8 + 0 x9 + 5 x10 <= 97 +4 x1 + 7 x2 + 7 x3 + 2 x4 + 0 x5 + 1 x6 + 6 x7 + 0 x8 + 10 x9 + 6 x10 <= 68 +3 x1 + 0 x2 + 2 x3 + 5 x4 + 5 x5 + 7 x6 + 10 x7 + 5 x8 + 5 x9 + 10 x10 <= 54 +4 x1 + 10 x2 + 7 x3 + 9 x4 + 10 x5 + 4 x6 + 5 x7 + 6 x8 + 7 x9 + 9 x10 <= 48 +4 x1 + 0 x2 + 8 x3 + 3 x4 + 0 x5 + 7 x6 + 4 x7 + 5 x8 + 10 x9 + 5 x10 <= 44 +3 x1 + 4 x2 + 2 x3 + 7 x4 + 5 x5 + 3 x6 + 5 x7 + 3 x8 + 3 x9 + 2 x10 >= 38 x1 >= 0 -x2 >= 0 -x3 >= 0 -x4 <= 0 -x5 livre +x2 <= 0 +x3 <= 0 +x4 >= 0 +x5 >= 0 +x6 >= 0 +x7 >= 0 +x8 livre +x9 >= 0 +x10 >= 0 diff --git a/main/main.py b/main/main.py index 1c1afd7..2e98a8a 100644 --- a/main/main.py +++ b/main/main.py @@ -18,7 +18,7 @@ def main(): objective_coeffs=result['objective_coeffs'], constraints=result['constraints'], objective_type=result['objective_type'], - non_negative=result['non_negative'] + var_signs=result['var_signs'] ) solution = simplex.solve() diff --git a/main/parser.py b/main/parser.py index 3c15c35..364f1c8 100644 --- a/main/parser.py +++ b/main/parser.py @@ -22,13 +22,30 @@ class Parser: def __init__(self, filepath): self.filepath = filepath + self.objective_type = None + self.objective_coeffs = [] + self.constraints = [] + self.num_vars = 0 + self.non_negative = [] + self.var_signs = [] def parse(self): lines = [line.strip() for line in open(self.filepath)] - self.parse_objective(lines[0]) + idx = None + for i, l in enumerate(lines): + ll = l.lower() + if ll.startswith("max") or ll.startswith("min"): + idx = i + break + if idx is None: + raise ValueError("Objective function must be Max or Min.") + + self.parse_objective(lines[idx]) - for line in lines[1:]: + for line in lines[idx+1:]: + if not line: + continue if self.is_non_negative(line): self.parse_non_negative(line) elif "<=" in line or ">=" in line or "=" in line: @@ -37,13 +54,16 @@ def parse(self): #if some variables were not mentioned in non-negativity constraints, assume they are non-negative while len(self.non_negative) < self.num_vars: self.non_negative.append(True) + while len(self.var_signs) < self.num_vars: + self.var_signs.append(">=0") return { "objective_type": self.objective_type, "objective_coeffs": self.objective_coeffs, "constraints": self.constraints, "num_vars": self.num_vars, - "non_negative": self.non_negative + "non_negative": self.non_negative, + "var_signs": self.var_signs } def is_non_negative(self, line): @@ -60,13 +80,18 @@ def parse_non_negative(self, line): while len(self.non_negative) < var: self.non_negative.append(True) + while len(self.var_signs) < var: + self.var_signs.append(">=0") if "livre" in line.lower(): self.non_negative[var - 1] = False + self.var_signs[var - 1] = "free" elif "<=" in line: self.non_negative[var - 1] = False + self.var_signs[var - 1] = "<=0" else: self.non_negative[var - 1] = True + self.var_signs[var - 1] = ">=0" def parse_objective(self, line): line_lower = line.lower() diff --git a/main/simplex.py b/main/simplex.py index 156920e..871b34b 100644 --- a/main/simplex.py +++ b/main/simplex.py @@ -2,7 +2,7 @@ class Simplex: def __init__(self, objective_coeffs, constraints, - objective_type="Max", non_negative=None): + objective_type="Max", var_signs=None): """ Args: objective_coeffs: objective function coefficients @@ -10,14 +10,23 @@ def __init__(self, objective_coeffs, constraints, objective_type: "Max" (only maximization is supported) non_negative: List indicating if each variable is non-negative """ - if objective_type != "Max": - raise ValueError("Only maximization is supported.") + self.original_objective_type = objective_type + self.orig_num_vars = len(objective_coeffs) + self.var_signs = var_signs if var_signs else [">=0"] * self.orig_num_vars + + self.c, self.constraints, self._map_orig_to_internal = self._expand_variables( + objective_coeffs, constraints, self.var_signs + ) + + if objective_type == "Min": + self.c = [-float(x) for x in self.c] + self.is_minimization = True + else: + self.c = [float(x) for x in self.c] + self.is_minimization = False - self.c = [float(x) for x in objective_coeffs] - self.constraints = constraints - self.objective_type = objective_type - self.num_vars = len(objective_coeffs) - self.non_negative = non_negative if non_negative else [True] * self.num_vars + self.objective_type = "Max" + self.num_vars = len(self.c) self.M = 1000000 @@ -27,6 +36,49 @@ def __init__(self, objective_coeffs, constraints, self.solution = None self.optimal_value = None + + def _expand_variables(self, c, constraints, var_signs): + n = len(c) + A = [list(coeffs) for (coeffs, _, _) in constraints] + ops = [op for (_, op, _) in constraints] + b = [rhs for (_, _, rhs) in constraints] + + new_c = [] + mapping = [] + col_blocks = [] + for i in range(n): + sign = var_signs[i] if i < len(var_signs) else ">=0" + if sign == ">=0": + mapping.append([len(new_c)]) + new_c.append(float(c[i])) + col_blocks.append(("single", i, [len(new_c)-1])) + elif sign == "<=0": + mapping.append([len(new_c)]) + new_c.append(float(-c[i])) + col_blocks.append(("neg", i, [len(new_c)-1])) + else: + mapping.append([len(new_c), len(new_c)+1]) + new_c.append(float(c[i])) + new_c.append(float(-c[i])) + col_blocks.append(("free", i, [len(new_c)-2, len(new_c)-1])) + + A_exp = [] + for r in range(len(constraints)): + row = [0.0] * len(new_c) + for i in range(n): + a = float(A[r][i]) + typ, _, idxs = col_blocks[i] + if typ == "single": + row[idxs[0]] = a + elif typ == "neg": + row[idxs[0]] = -a + else: + row[idxs[0]] = a + row[idxs[1]] = -a + A_exp.append(row) + + constraints_exp = [(A_exp[i], ops[i], b[i]) for i in range(len(constraints))] + return new_c, constraints_exp, mapping def solve(self): """ @@ -212,13 +264,28 @@ def check_artificial_in_basis(self): return False def extract_solution(self): - self.solution = [0.0] * self.num_vars + internal_solution = [0.0] * self.num_vars all_var_names = self.tableau_obj.get_all_var_names() for i, var_name in enumerate(self.tableau_obj.basis): if var_name and var_name.startswith('x'): var_index = int(var_name[1:]) - 1 - self.solution[var_index] = self.tableau_obj.tableau[i][-1] + internal_solution[var_index] = self.tableau_obj.tableau[i][-1] + + sol = [0.0] * self.orig_num_vars + for i, idxs in enumerate(self._map_orig_to_internal): + if len(idxs) == 1: + if self.var_signs[i] == "<=0": + sol[i] = -internal_solution[idxs[0]] + else: + sol[i] = internal_solution[idxs[0]] + else: + plus, minus = idxs + sol[i] = internal_solution[plus] - internal_solution[minus] + + self.solution = sol - self.optimal_value = self.tableau_obj.tableau[-1][-1] \ No newline at end of file + self.optimal_value = self.tableau_obj.tableau[-1][-1] + if self.is_minimization: + self.optimal_value = -self.optimal_value \ No newline at end of file From 6697eaef3102d2326f0db6d5b856b36e77c5284b Mon Sep 17 00:00:00 2001 From: EricoMeger Date: Mon, 24 Nov 2025 21:18:19 -0300 Subject: [PATCH 11/15] output results --- main/main.py | 3 +- main/output/resultado.txt | 421 ++++++++++++++++++++++++++++++++++++++ main/simplex.py | 57 ++++-- main/tableau.py | 34 ++- 4 files changed, 477 insertions(+), 38 deletions(-) create mode 100644 main/output/resultado.txt diff --git a/main/main.py b/main/main.py index 2e98a8a..8a35b11 100644 --- a/main/main.py +++ b/main/main.py @@ -22,6 +22,8 @@ def main(): ) solution = simplex.solve() + + simplex.write_report("output/resultado.txt") print() print("="*80) @@ -29,7 +31,6 @@ def main(): print("="*80) print() print(f"Status: {solution['status']}") - if solution['status'] == 'optimal': print(f"Valor ótimo: {solution['optimal_value']:.4f}") print("Solução ótima:") diff --git a/main/output/resultado.txt b/main/output/resultado.txt new file mode 100644 index 0000000..1d60951 --- /dev/null +++ b/main/output/resultado.txt @@ -0,0 +1,421 @@ +Iterações do Simplex +================================================================================ +=== Iteracao: 0 === + VB x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 a1 a2 b + a1 6.00 -2.00 -6.00 7.00 0.00 2.00 2.00 5.00 -5.00 5.00 10.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 5.00 + w1 0.00 -9.00 -10.00 9.00 3.00 3.00 4.00 6.00 -6.00 6.00 8.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 60.00 + w2 1.00 -4.00 -1.00 8.00 6.00 0.00 6.00 8.00 -8.00 4.00 4.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 33.00 + w3 3.00 -5.00 -3.00 2.00 10.00 4.00 0.00 1.00 -1.00 7.00 7.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 57.00 + w4 7.00 -2.00 -3.00 2.00 9.00 10.00 6.00 6.00 -6.00 9.00 1.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 64.00 + w5 6.00 -10.00 -8.00 5.00 9.00 4.00 8.00 2.00 -2.00 9.00 5.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 67.00 + w6 7.00 -2.00 -10.00 9.00 3.00 5.00 8.00 6.00 -6.00 4.00 6.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 35.00 + w7 8.00 -7.00 -4.00 0.00 5.00 7.00 0.00 5.00 -5.00 4.00 4.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 42.00 + w8 4.00 -0.00 -3.00 3.00 1.00 6.00 6.00 2.00 -2.00 6.00 7.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 22.00 + w9 2.00 -10.00 -6.00 6.00 4.00 4.00 4.00 9.00 -9.00 3.00 10.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 74.00 + w10 1.00 -8.00 -10.00 1.00 5.00 10.00 7.00 10.00 -10.00 8.00 10.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 49.00 + w11 4.00 -2.00 -0.00 8.00 1.00 9.00 4.00 10.00 -10.00 0.00 10.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 89.00 + w12 0.00 -5.00 -7.00 2.00 10.00 3.00 5.00 2.00 -2.00 6.00 5.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 73.00 + w13 10.00 -8.00 -2.00 3.00 0.00 6.00 7.00 7.00 -7.00 8.00 3.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 64.00 + w14 4.00 -10.00 -10.00 4.00 9.00 6.00 4.00 3.00 -3.00 1.00 5.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 36.00 + w15 3.00 -9.00 -2.00 0.00 7.00 5.00 1.00 8.00 -8.00 4.00 8.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 44.00 + w16 2.00 -7.00 -8.00 3.00 2.00 5.00 9.00 3.00 -3.00 3.00 6.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 29.00 + w17 1.00 -7.00 -9.00 6.00 9.00 0.00 3.00 7.00 -7.00 5.00 9.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 28.00 + w18 8.00 -8.00 -7.00 9.00 3.00 3.00 7.00 1.00 -1.00 2.00 9.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 87.00 + w19 3.00 -8.00 -5.00 6.00 9.00 2.00 0.00 3.00 -3.00 10.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 + w20 9.00 -8.00 -6.00 10.00 5.00 10.00 7.00 2.00 -2.00 6.00 2.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 43.00 + w21 1.00 -9.00 -0.00 10.00 3.00 6.00 5.00 6.00 -6.00 9.00 4.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 78.00 + w22 7.00 -3.00 -6.00 7.00 4.00 10.00 5.00 1.00 -1.00 3.00 8.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 87.00 + w23 3.00 -0.00 -9.00 5.00 0.00 10.00 6.00 10.00 -10.00 6.00 10.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 7.00 + w24 9.00 -4.00 -5.00 10.00 7.00 7.00 9.00 5.00 -5.00 0.00 5.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 97.00 + w25 4.00 -7.00 -7.00 2.00 0.00 1.00 6.00 0.00 -0.00 10.00 6.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 68.00 + w26 3.00 -0.00 -2.00 5.00 5.00 7.00 10.00 5.00 -5.00 5.00 10.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 54.00 + w27 4.00 -10.00 -7.00 9.00 10.00 4.00 5.00 6.00 -6.00 7.00 9.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 48.00 + w28 4.00 -0.00 -8.00 3.00 0.00 7.00 4.00 5.00 -5.00 10.00 5.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 44.00 + a2 3.00 -4.00 -2.00 7.00 5.00 3.00 5.00 3.00 -3.00 3.00 2.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.00 0.00 1.00 38.00 + Z-9000001.006000007.008000007.00-14000008.00-5000004.00-5000006.00-7000001.00-8000010.008000010.00-8000009.00-12000008.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.001000000.00 0.00 0.00-43000000.00 + +=== Iteracao: 1 === + VB x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 a1 a2 b + x4 0.86 -0.29 -0.86 1.00 0.00 0.29 0.29 0.71 -0.71 0.71 1.43 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.14 0.00 0.71 + w1 -7.71 -6.43 -2.29 0.00 3.00 0.43 1.43 -0.43 0.43 -0.43 -4.86 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.29 0.00 53.57 + w2 -5.86 -1.71 5.86 0.00 6.00 -2.29 3.71 2.29 -2.29 -1.71 -7.43 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.14 0.00 27.29 + w3 1.29 -4.43 -1.29 0.00 10.00 3.43 -0.57 -0.43 0.43 5.57 4.14 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.29 0.00 55.57 + w4 5.29 -1.43 -1.29 0.00 9.00 9.43 5.43 4.57 -4.57 7.57 -1.86 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.29 0.00 62.57 + w5 1.71 -8.57 -3.71 0.00 9.00 2.57 6.57 -1.57 1.57 5.43 -2.14 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.71 0.00 63.43 + w6 -0.71 0.57 -2.29 0.00 3.00 2.43 5.43 -0.43 0.43 -2.43 -6.86 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.29 0.00 28.57 + w7 8.00 -7.00 -4.00 0.00 5.00 7.00 0.00 5.00 -5.00 4.00 4.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 42.00 + w8 1.43 0.86 -0.43 0.00 1.00 5.14 5.14 -0.14 0.14 3.86 2.71 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.43 0.00 19.86 + w9 -3.14 -8.29 -0.86 0.00 4.00 2.29 2.29 4.71 -4.71 -1.29 1.43 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.86 0.00 69.71 + w10 0.14 -7.71 -9.14 0.00 5.00 9.71 6.71 9.29 -9.29 7.29 8.57 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.14 0.00 48.29 + w11 -2.86 0.29 6.86 0.00 1.00 6.71 1.71 4.29 -4.29 -5.71 -1.43 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.14 0.00 83.29 + w12 -1.71 -4.43 -5.29 0.00 10.00 2.43 4.43 0.57 -0.57 4.57 2.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.29 0.00 71.57 + w13 7.43 -7.14 0.57 0.00 0.00 5.14 6.14 4.86 -4.86 5.86 -1.29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.43 0.00 61.86 + w14 0.57 -8.86 -6.57 0.00 9.00 4.86 2.86 0.14 -0.14 -1.86 -0.71 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.57 0.00 33.14 + w15 3.00 -9.00 -2.00 0.00 7.00 5.00 1.00 8.00 -8.00 4.00 8.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 44.00 + w16 -0.57 -6.14 -5.43 0.00 2.00 4.14 8.14 0.86 -0.86 0.86 1.71 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.43 0.00 26.86 + w17 -4.14 -5.29 -3.86 0.00 9.00 -1.71 1.29 2.71 -2.71 0.71 0.43 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.86 0.00 23.71 + w18 0.29 -5.43 0.71 0.00 3.00 0.43 4.43 -5.43 5.43 -4.43 -3.86 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.29 0.00 80.57 + w19 -2.14 -6.29 0.14 0.00 9.00 0.29 -1.71 -1.29 1.29 5.71 -8.57 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.86 0.00 95.71 + w20 0.43 -5.14 2.57 0.00 5.00 7.14 4.14 -5.14 5.14 -1.14 -12.29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.43 0.00 35.86 + w21 -7.57 -6.14 8.57 0.00 3.00 3.14 2.14 -1.14 1.14 1.86 -10.29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.43 0.00 70.86 + w22 1.00 -1.00 0.00 0.00 4.00 8.00 3.00 -4.00 4.00 -2.00 -2.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.00 0.00 82.00 + w23 -1.29 1.43 -4.71 0.00 0.00 8.57 4.57 6.43 -6.43 2.43 2.86 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.71 0.00 3.43 + w24 0.43 -1.14 3.57 0.00 7.00 4.14 6.14 -2.14 2.14 -7.14 -9.29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 -1.43 0.00 89.86 + w25 2.29 -6.43 -5.29 0.00 0.00 0.43 5.43 -1.43 1.43 8.57 3.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 -0.29 0.00 66.57 + w26 -1.29 1.43 2.29 0.00 5.00 5.57 8.57 1.43 -1.43 1.43 2.86 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 -0.71 0.00 50.43 + w27 -3.71 -7.43 0.71 0.00 10.00 1.43 2.43 -0.43 0.43 0.57 -3.86 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 -1.29 0.00 41.57 + w28 1.43 0.86 -5.43 0.00 0.00 6.14 3.14 2.86 -2.86 7.86 0.71 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 -0.43 0.00 41.86 + a2 -3.00 -2.00 4.00 0.00 5.00 1.00 3.00 -2.00 2.00 -2.00 -8.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.00 -1.00 1.00 33.00 + Z3000005.862000004.71-3999999.86 0.00-5000004.00-1000003.71-2999998.711999995.71-1999995.711999996.718000003.43 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.001000000.002000001.14 0.00-32999994.29 + +=== Iteracao: 2 === + VB x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 a1 a2 b + x4 0.86 -0.29 -0.86 1.00 0.00 0.29 0.29 0.71 -0.71 0.71 1.43 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.14 0.00 0.71 + w1 -6.33 -4.67 -1.00 0.00 0.00 1.00 1.00 -1.33 1.33 -0.67 -5.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.00 0.00 45.67 + w2 -3.10 1.81 8.43 0.00 0.00 -1.14 2.86 0.48 -0.48 -2.19 -7.71 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.67 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.57 0.00 11.48 + w3 5.89 1.44 3.00 0.00 0.00 5.33 -2.00 -3.44 3.44 4.78 3.67 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.67 0.00 29.22 + w4 9.43 3.86 2.57 0.00 0.00 11.14 4.14 1.86 -1.86 6.86 -2.29 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.57 0.00 38.86 + w5 5.86 -3.29 0.14 0.00 0.00 4.29 5.29 -4.29 4.29 4.71 -2.57 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.14 0.00 39.71 + w6 0.67 2.33 -1.00 0.00 0.00 3.00 5.00 -1.33 1.33 -2.67 -7.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.00 0.00 20.67 + w7 10.30 -4.06 -1.86 0.00 0.00 7.95 -0.71 3.49 -3.49 3.60 3.76 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.56 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.48 0.00 28.83 + w8 1.89 1.44 -0.00 0.00 0.00 5.33 5.00 -0.44 0.44 3.78 2.67 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.33 0.00 17.22 + w9 -1.30 -5.94 0.86 0.00 0.00 3.05 1.71 3.51 -3.51 -1.60 1.24 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.44 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.48 0.00 59.17 + w10 2.44 -4.78 -7.00 0.00 0.00 10.67 6.00 7.78 -7.78 6.89 8.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.56 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.33 0.00 35.11 + w11 -2.40 0.87 7.29 0.00 0.00 6.90 1.57 3.98 -3.98 -5.79 -1.48 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 -0.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.05 0.00 80.65 + w12 2.89 1.44 -1.00 0.00 0.00 4.33 3.00 -2.44 2.44 3.78 1.67 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 -1.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.67 0.00 45.22 + w13 7.43 -7.14 0.57 0.00 0.00 5.14 6.14 4.86 -4.86 5.86 -1.29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.43 0.00 61.86 + w14 4.71 -3.57 -2.71 0.00 0.00 6.57 1.57 -2.57 2.57 -2.57 -1.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 -1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.29 0.00 9.43 + w15 6.22 -4.89 1.00 0.00 0.00 6.33 -0.00 5.89 -5.89 3.44 7.67 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 -0.78 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.67 0.00 25.56 + w16 0.35 -4.97 -4.57 0.00 0.00 4.52 7.86 0.25 -0.25 0.70 1.62 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 -0.22 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.24 0.00 21.59 + x5 -0.46 -0.59 -0.43 0.00 1.00 -0.19 0.14 0.30 -0.30 0.08 0.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.10 0.00 2.63 + w18 1.67 -3.67 2.00 0.00 0.00 1.00 4.00 -6.33 6.33 -4.67 -4.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.33 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.00 0.00 72.67 + w19 2.00 -1.00 4.00 0.00 0.00 2.00 -3.00 -4.00 4.00 5.00 -9.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 72.00 + w20 2.73 -2.21 4.71 0.00 0.00 8.10 3.43 -6.65 6.65 -1.54 -12.52 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.56 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.95 0.00 22.68 + w21 -6.19 -4.38 9.86 0.00 0.00 3.71 1.71 -2.05 2.05 1.62 -10.43 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.33 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.14 0.00 62.95 + w22 2.84 1.35 1.71 0.00 0.00 8.76 2.43 -5.21 5.21 -2.32 -2.19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.44 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.62 0.00 71.46 + w23 -1.29 1.43 -4.71 0.00 0.00 8.57 4.57 6.43 -6.43 2.43 2.86 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.71 0.00 3.43 + w24 3.65 2.97 6.57 0.00 0.00 5.48 5.14 -4.25 4.25 -7.70 -9.62 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.78 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 -0.76 0.00 71.41 + w25 2.29 -6.43 -5.29 0.00 0.00 0.43 5.43 -1.43 1.43 8.57 3.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 -0.29 0.00 66.57 + w26 1.02 4.37 4.43 0.00 0.00 6.52 7.86 -0.08 0.08 1.03 2.62 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.56 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 -0.24 0.00 37.25 + w27 0.89 -1.56 5.00 0.00 0.00 3.33 1.00 -3.44 3.44 -0.22 -4.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 -0.33 0.00 15.22 + w28 1.43 0.86 -5.43 0.00 0.00 6.14 3.14 2.86 -2.86 7.86 0.71 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 -0.43 0.00 41.86 + a2 -0.70 0.94 6.14 0.00 0.00 1.95 2.29 -3.51 3.51 -2.40 -8.24 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.56 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.00 -0.52 1.00 19.83 + Z 698416.71-936505.57-6142858.71 0.00 0.00-1952385.43-2285712.433507933.43-3507933.432396822.438238098.86 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 555556.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.001000000.001523810.29 0.00-19825380.57 + +=== Iteracao: 3 === + VB x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 a1 a2 b + x4 0.54 -0.10 0.00 1.00 0.00 0.17 0.58 0.76 -0.76 0.49 0.64 0.00 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.08 0.00 1.88 + w1 -6.70 -4.45 0.00 0.00 0.00 0.86 1.34 -1.28 1.28 -0.93 -5.92 1.00 0.12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.41 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.07 0.00 47.03 + x3 -0.37 0.21 1.00 0.00 0.00 -0.14 0.34 0.06 -0.06 -0.26 -0.92 0.00 0.12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.07 0.00 1.36 + w3 6.99 0.80 0.00 0.00 0.00 5.74 -3.02 -3.61 3.61 5.56 6.41 0.00 -0.36 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.87 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.87 0.00 25.14 + w4 10.37 3.31 0.00 0.00 0.00 11.49 3.27 1.71 -1.71 7.53 0.07 0.00 -0.31 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.80 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.75 0.00 35.36 + w5 5.91 -3.32 0.00 0.00 0.00 4.31 5.24 -4.29 4.29 4.75 -2.44 0.00 -0.02 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.99 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.15 0.00 39.52 + w6 0.30 2.55 0.00 0.00 0.00 2.86 5.34 -1.28 1.28 -2.93 -7.92 0.00 0.12 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.41 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.07 0.00 22.03 + w7 9.62 -3.66 0.00 0.00 0.00 7.70 -0.08 3.60 -3.60 3.12 2.06 0.00 0.22 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.70 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.35 0.00 31.35 + w8 1.89 1.44 0.00 0.00 0.00 5.33 5.00 -0.44 0.44 3.78 2.67 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.33 0.00 17.22 + w9 -0.99 -6.12 0.00 0.00 0.00 3.16 1.42 3.46 -3.46 -1.38 2.02 0.00 -0.10 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.38 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.42 0.00 58.01 + w10 -0.13 -3.27 0.00 0.00 0.00 9.72 8.37 8.17 -8.17 5.07 1.93 0.00 0.83 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.14 0.00 44.64 + w11 0.28 -0.69 0.00 0.00 0.00 7.89 -0.90 3.57 -3.57 -3.90 5.19 0.00 -0.86 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.47 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.55 0.00 70.73 + w12 2.52 1.66 0.00 0.00 0.00 4.20 3.34 -2.39 2.39 3.52 0.75 0.00 0.12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 -1.19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.60 0.00 46.58 + w13 7.64 -7.27 0.00 0.00 0.00 5.22 5.95 4.82 -4.82 6.01 -0.76 0.00 -0.07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.39 0.00 61.08 + w14 3.72 -2.99 0.00 0.00 0.00 6.20 2.49 -2.42 2.42 -3.28 -3.63 0.00 0.32 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 -1.21 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.10 0.00 13.12 + w15 6.59 -5.10 0.00 0.00 0.00 6.47 -0.34 5.83 -5.83 3.70 8.58 0.00 -0.12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 -0.70 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.73 0.00 24.19 + w16 -1.33 -3.99 0.00 0.00 0.00 3.90 9.41 0.51 -0.51 -0.49 -2.56 0.00 0.54 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 -0.58 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.55 0.00 27.81 + x5 -0.62 -0.50 0.00 0.00 1.00 -0.25 0.29 0.33 -0.33 -0.03 -0.34 0.00 0.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.12 0.00 3.22 + w18 2.40 -4.10 0.00 0.00 0.00 1.27 3.32 -6.45 6.45 -4.15 -2.17 0.00 -0.24 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.18 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.86 0.00 69.94 + w19 3.47 -1.86 0.00 0.00 0.00 2.54 -4.36 -4.23 4.23 6.04 -5.34 0.00 -0.47 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.68 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.27 0.00 66.55 + w20 4.46 -3.22 0.00 0.00 0.00 8.73 1.83 -6.92 6.92 -0.31 -8.21 0.00 -0.56 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.18 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.63 0.00 16.26 + w21 -2.57 -6.50 0.00 0.00 0.00 5.05 -1.63 -2.60 2.60 4.18 -1.41 0.00 -1.17 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.45 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.47 0.00 49.53 + w22 3.47 0.98 0.00 0.00 0.00 8.99 1.85 -5.30 5.30 -1.87 -0.62 0.00 -0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.31 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.50 0.00 69.13 + w23 -3.02 2.44 0.00 0.00 0.00 7.93 6.17 6.69 -6.69 1.20 -1.46 0.00 0.56 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.37 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.03 0.00 9.85 + w24 6.06 1.56 0.00 0.00 0.00 6.37 2.92 -4.63 4.63 -5.99 -3.60 0.00 -0.78 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.26 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 -0.32 0.00 62.47 + w25 0.34 -5.29 0.00 0.00 0.00 -0.29 7.22 -1.13 1.13 7.20 -1.69 0.00 0.63 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.42 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 -0.64 0.00 73.77 + w26 2.64 3.41 0.00 0.00 0.00 7.12 6.36 -0.33 0.33 2.18 6.67 0.00 -0.53 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.21 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.06 0.00 31.22 + w27 2.73 -2.63 0.00 0.00 0.00 4.01 -0.69 -3.73 3.73 1.08 0.24 0.00 -0.59 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.72 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.01 0.00 8.41 + w28 -0.56 2.02 0.00 0.00 0.00 5.41 4.98 3.16 -3.16 6.45 -4.25 0.00 0.64 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.43 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 -0.80 0.00 49.25 + a2 1.56 -0.38 0.00 0.00 0.00 2.79 0.20 -3.85 3.85 -0.80 -2.62 0.00 -0.73 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.00 -0.11 1.00 11.46 + Z-1557435.36 382300.25 0.00 0.00 0.00-2785315.42-203387.443854987.59-3854987.59 800373.272615821.39 0.00 728813.75 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 69680.17 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.001000000.001107345.29 0.00-11461375.20 + +=== Iteracao: 4 === + VB x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 a1 a2 b + x4 1.10 -0.64 0.00 1.00 0.00 0.99 0.43 0.00 0.00 0.71 0.69 0.00 -0.02 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.21 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.20 0.00 0.00 0.09 0.00 3.60 + w1 -7.63 -3.55 0.00 0.00 0.00 -0.51 1.58 0.00 0.00 -1.30 -6.00 1.00 0.32 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.17 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.34 0.00 0.00 -1.07 0.00 44.15 + x3 -0.33 0.17 1.00 0.00 0.00 -0.07 0.33 0.00 0.00 -0.24 -0.91 0.00 0.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.09 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.02 0.00 0.00 -0.07 0.00 1.49 + w3 4.35 3.35 0.00 0.00 0.00 1.85 -2.34 0.00 0.00 4.51 6.18 0.00 0.22 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.18 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.97 0.00 0.00 0.86 0.00 16.98 + w4 11.62 2.10 0.00 0.00 0.00 13.33 2.95 0.00 0.00 8.02 0.18 0.00 -0.58 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.13 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.46 0.00 0.00 0.75 0.00 39.22 + w5 2.77 -0.29 0.00 0.00 0.00 -0.32 6.04 0.00 0.00 3.51 -2.72 0.00 0.67 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.15 0.00 0.00 0.15 0.00 29.83 + w6 -0.63 3.45 0.00 0.00 0.00 1.49 5.58 0.00 0.00 -3.30 -8.00 0.00 0.32 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.17 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.34 0.00 0.00 -1.07 0.00 19.15 + w7 12.25 -6.20 0.00 0.00 0.00 11.57 -0.76 0.00 0.00 4.16 2.30 0.00 -0.35 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.39 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.97 0.00 0.00 0.36 0.00 39.47 + w8 1.56 1.76 0.00 0.00 0.00 4.85 5.08 0.00 0.00 3.65 2.64 0.00 0.07 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.03 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.12 0.00 0.00 -0.33 0.00 16.22 + w9 1.54 -8.56 0.00 0.00 0.00 6.89 0.78 0.00 0.00 -0.38 2.25 0.00 -0.65 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.04 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.93 0.00 0.00 -0.41 0.00 65.82 + w10 5.85 -9.04 0.00 0.00 0.00 18.51 6.85 0.00 0.00 7.43 2.46 0.00 -0.47 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 -2.68 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2.19 0.00 0.00 -0.13 0.00 63.09 + w11 2.89 -3.21 0.00 0.00 0.00 11.74 -1.56 0.00 0.00 -2.87 5.42 0.00 -1.43 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 -0.22 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.96 0.00 0.00 -0.55 0.00 78.80 + w12 0.78 3.34 0.00 0.00 0.00 1.63 3.78 0.00 0.00 2.83 0.60 0.00 0.50 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 -0.73 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.64 0.00 0.00 0.60 0.00 41.19 + w13 11.17 -10.67 0.00 0.00 0.00 10.41 5.05 0.00 0.00 7.40 -0.45 0.00 -0.84 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 -0.88 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.29 0.00 0.00 -0.38 0.00 71.97 + w14 1.95 -1.28 0.00 0.00 0.00 3.60 2.94 0.00 0.00 -3.98 -3.78 0.00 0.71 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 -0.75 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.65 0.00 0.00 0.10 0.00 7.66 + w15 10.85 -9.22 0.00 0.00 0.00 12.75 -1.43 0.00 0.00 5.39 8.96 0.00 -1.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 -1.82 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.56 0.00 0.00 0.74 0.00 37.36 + w16 -0.96 -4.35 0.00 0.00 0.00 4.46 9.31 0.00 0.00 -0.34 -2.53 0.00 0.46 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 -0.68 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.14 0.00 0.00 -0.55 0.00 28.97 + x5 -0.38 -0.73 0.00 0.00 1.00 0.10 0.23 0.00 0.00 0.06 -0.32 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.09 0.00 0.00 -0.12 0.00 3.95 + w18 -2.31 0.45 0.00 0.00 0.00 -5.67 4.52 0.00 0.00 -6.01 -2.59 0.00 0.79 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.06 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.73 0.00 0.00 -0.87 0.00 55.39 + w19 0.38 1.12 0.00 0.00 0.00 -2.01 -3.57 0.00 0.00 4.82 -5.61 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.13 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.13 0.00 0.00 0.26 0.00 57.01 + w20 -0.60 1.66 0.00 0.00 0.00 1.29 3.12 0.00 0.00 -2.31 -8.66 0.00 0.54 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.15 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.86 0.00 0.00 -0.64 0.00 0.65 + w21 -4.47 -4.66 0.00 0.00 0.00 2.25 -1.14 0.00 0.00 3.43 -1.58 0.00 -0.75 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.95 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 -0.70 0.00 0.00 -0.48 0.00 43.65 + w22 -0.41 4.72 0.00 0.00 0.00 3.29 2.84 0.00 0.00 -3.40 -0.97 0.00 0.64 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.71 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 -1.42 0.00 0.00 -0.51 0.00 57.15 + w23 1.88 -2.28 0.00 0.00 0.00 15.14 4.92 0.00 0.00 3.14 -1.02 0.00 -0.51 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.66 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 1.80 0.00 0.00 -1.02 0.00 24.96 + w24 2.68 4.82 0.00 0.00 0.00 1.39 3.78 0.00 0.00 -7.33 -3.91 0.00 -0.04 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.63 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 -1.24 0.00 0.00 -0.32 0.00 52.02 + w25 -0.48 -4.50 0.00 0.00 0.00 -1.50 7.43 0.00 0.00 6.87 -1.77 0.00 0.81 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 -0.30 0.00 0.00 -0.65 0.00 71.22 + w26 2.40 3.65 0.00 0.00 0.00 6.77 6.42 0.00 0.00 2.09 6.65 0.00 -0.47 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 -0.09 0.00 0.00 0.06 0.00 30.48 + x9 0.73 -0.71 0.00 0.00 0.00 1.08 -0.19 -1.00 1.00 0.29 0.07 0.00 -0.16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.27 0.00 0.00 0.00 0.00 2.26 + w28 1.75 -0.21 0.00 0.00 0.00 8.81 4.39 0.00 0.00 7.36 -4.05 0.00 0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.04 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.85 1.00 0.00 -0.79 0.00 56.39 + a2 -1.26 2.34 0.00 0.00 0.00 -1.36 0.92 0.00 0.00 -1.91 -2.87 0.00 -0.12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.67 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.03 0.00 -1.00 -0.11 1.00 2.76 + Z1261244.30-2337034.10 0.00 0.00 0.001363812.20-922179.97 0.00 0.001914599.092867106.58 0.00 115210.36 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00-670539.78 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.001034359.99 0.001000000.001113189.13 0.00-2757946.92 + +=== Iteracao: 5 === + VB x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 a1 a2 b + x4 0.87 0.00 0.00 1.00 0.00 1.49 1.64 0.00 0.00 -0.18 -2.64 0.00 0.19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.23 0.00 0.00 0.39 0.00 0.00 0.00 0.00 0.00 0.00 -0.51 0.00 0.00 -0.16 0.00 3.85 + w1 -8.91 0.00 0.00 0.00 0.00 2.25 8.25 0.00 0.00 -6.24 -24.51 1.00 1.48 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2.28 0.00 0.00 2.14 0.00 0.00 0.00 0.00 0.00 0.00 -4.31 0.00 0.00 -2.45 0.00 45.53 + x3 -0.26 0.00 1.00 0.00 0.00 -0.21 -0.00 0.00 0.00 0.00 0.00 0.00 0.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.21 0.00 0.00 -0.11 0.00 0.00 0.00 0.00 0.00 0.00 0.21 0.00 0.00 0.00 0.00 1.42 + w3 5.55 0.00 0.00 0.00 0.00 -0.75 -8.64 0.00 0.00 9.18 23.64 0.00 -0.87 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -2.49 0.00 0.00 -2.02 0.00 0.00 0.00 0.00 0.00 0.00 2.77 0.00 0.00 2.16 0.00 15.67 + w4 12.38 0.00 0.00 0.00 0.00 11.71 -0.99 0.00 0.00 10.94 11.12 0.00 -1.26 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -2.57 0.00 0.00 -1.26 0.00 0.00 0.00 0.00 0.00 0.00 2.80 0.00 0.00 1.56 0.00 38.40 + w5 2.67 0.00 0.00 0.00 0.00 -0.09 6.58 0.00 0.00 3.11 -4.22 0.00 0.76 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.03 0.00 0.00 0.17 0.00 0.00 0.00 0.00 0.00 0.00 -1.47 0.00 0.00 0.03 0.00 29.94 + w6 0.60 0.00 0.00 0.00 0.00 -1.19 -0.90 0.00 0.00 1.51 9.98 0.00 -0.80 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -2.55 0.00 0.00 -2.08 0.00 0.00 0.00 0.00 0.00 0.00 3.51 0.00 0.00 0.27 0.00 17.80 + w7 10.02 0.00 0.00 0.00 0.00 16.39 10.90 0.00 0.00 -4.48 -30.04 0.00 1.67 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2.88 0.00 0.00 3.73 0.00 0.00 0.00 0.00 0.00 0.00 -5.97 0.00 0.00 -2.05 0.00 41.89 + w8 2.20 0.00 0.00 0.00 0.00 3.49 1.78 0.00 0.00 6.10 11.80 0.00 -0.50 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.24 0.00 0.00 -1.06 0.00 0.00 0.00 0.00 0.00 0.00 1.85 0.00 0.00 0.35 0.00 15.53 + w9 -1.53 0.00 0.00 0.00 0.00 13.53 16.86 0.00 0.00 -12.31 -42.39 0.00 2.14 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 4.86 0.00 0.00 5.15 0.00 0.00 0.00 0.00 0.00 0.00 -8.64 0.00 0.00 -3.73 0.00 69.15 + w10 2.60 0.00 0.00 0.00 0.00 25.53 23.83 0.00 0.00 -5.16 -44.68 0.00 2.48 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 3.56 0.00 0.00 5.44 0.00 0.00 0.00 0.00 0.00 0.00 -7.91 0.00 0.00 -3.63 0.00 66.62 + w11 1.74 0.00 0.00 0.00 0.00 14.23 4.47 0.00 0.00 -7.34 -11.32 0.00 -0.39 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 1.99 0.00 0.00 1.93 0.00 0.00 0.00 0.00 0.00 0.00 -2.63 0.00 0.00 -1.79 0.00 80.05 + w12 1.98 0.00 0.00 0.00 0.00 -0.97 -2.50 0.00 0.00 7.49 18.03 0.00 -0.59 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 -3.04 0.00 0.00 -2.01 0.00 0.00 0.00 0.00 0.00 0.00 3.10 0.00 0.00 1.89 0.00 39.89 + w13 7.34 0.00 0.00 0.00 0.00 18.70 25.09 0.00 0.00 -7.46 -56.08 0.00 2.64 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 6.48 0.00 0.00 6.42 0.00 0.00 0.00 0.00 0.00 0.00 -10.63 0.00 0.00 -4.51 0.00 76.13 + w14 1.49 0.00 0.00 0.00 0.00 4.60 5.35 0.00 0.00 -5.76 -10.47 0.00 1.13 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.13 0.00 0.00 0.77 0.00 0.00 0.00 0.00 0.00 0.00 -2.08 0.00 0.00 -0.40 0.00 8.16 + w15 7.54 0.00 0.00 0.00 0.00 19.90 15.89 0.00 0.00 -7.45 -39.10 0.00 1.96 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 4.54 0.00 0.00 5.55 0.00 0.00 0.00 0.00 0.00 0.00 -8.74 0.00 0.00 -2.83 0.00 40.95 + w16 -2.52 0.00 0.00 0.00 0.00 7.83 17.48 0.00 0.00 -6.40 -25.20 0.00 1.88 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 2.32 0.00 0.00 2.62 0.00 0.00 0.00 0.00 0.00 0.00 -4.72 0.00 0.00 -2.23 0.00 30.66 + x5 -0.64 0.00 0.00 0.00 1.00 0.67 1.59 0.00 0.00 -0.95 -4.10 0.00 0.24 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.51 0.00 0.00 0.44 0.00 0.00 0.00 0.00 0.00 0.00 -0.72 0.00 0.00 -0.40 0.00 4.24 + w18 -2.15 0.00 0.00 0.00 0.00 -6.02 3.68 0.00 0.00 -5.38 -0.24 0.00 0.64 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.75 1.00 0.00 -0.27 0.00 0.00 0.00 0.00 0.00 0.00 -1.23 0.00 0.00 -0.70 0.00 55.21 + w19 0.78 0.00 0.00 0.00 0.00 -2.88 -5.68 0.00 0.00 6.38 0.24 0.00 -0.17 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.65 0.00 1.00 -0.68 0.00 0.00 0.00 0.00 0.00 0.00 0.12 0.00 0.00 0.70 0.00 56.58 + x2 -0.36 1.00 0.00 0.00 0.00 0.78 1.88 0.00 0.00 -1.39 -5.21 0.00 0.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.69 0.00 0.00 0.60 0.00 0.00 0.00 0.00 0.00 0.00 -1.12 0.00 0.00 -0.39 0.00 0.39 + w21 -6.15 0.00 0.00 0.00 0.00 5.87 7.61 0.00 0.00 -3.06 -25.87 0.00 0.76 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 4.16 0.00 0.00 2.81 1.00 0.00 0.00 0.00 0.00 0.00 -5.91 0.00 0.00 -2.28 0.00 45.47 + w22 1.29 0.00 0.00 0.00 0.00 -0.38 -6.03 0.00 0.00 3.17 23.65 0.00 -0.90 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -2.55 0.00 0.00 -2.84 0.00 1.00 0.00 0.00 0.00 0.00 3.85 0.00 0.00 1.32 0.00 55.31 + w23 1.06 0.00 0.00 0.00 0.00 16.91 9.21 0.00 0.00 -0.04 -12.92 0.00 0.24 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.08 0.00 0.00 1.37 0.00 0.00 1.00 0.00 0.00 0.00 -0.75 0.00 0.00 -1.91 0.00 25.85 + w24 4.41 0.00 0.00 0.00 0.00 -2.35 -5.28 0.00 0.00 -0.61 21.23 0.00 -1.62 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -2.69 0.00 0.00 -2.90 0.00 0.00 0.00 1.00 0.00 0.00 4.15 0.00 0.00 1.54 0.00 50.15 + w25 -2.10 0.00 0.00 0.00 0.00 1.99 15.88 0.00 0.00 0.61 -25.21 0.00 2.27 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2.90 0.00 0.00 2.71 0.00 0.00 0.00 0.00 1.00 0.00 -5.33 0.00 0.00 -2.39 0.00 72.97 + w26 3.71 0.00 0.00 0.00 0.00 3.94 -0.43 0.00 0.00 7.17 25.66 0.00 -1.66 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -2.66 0.00 0.00 -2.20 0.00 0.00 0.00 0.00 0.00 1.00 3.99 0.00 0.00 1.47 0.00 29.06 + x9 0.48 0.00 0.00 0.00 0.00 1.62 1.14 -1.00 1.00 -0.69 -3.61 0.00 0.07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.29 0.00 0.00 0.42 0.00 0.00 0.00 0.00 0.00 0.00 -0.52 0.00 0.00 -0.27 0.00 2.53 + w28 1.67 0.00 0.00 0.00 0.00 8.97 4.79 0.00 0.00 7.07 -5.14 0.00 0.21 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.89 0.00 0.00 0.13 0.00 0.00 0.00 0.00 0.00 0.00 0.62 1.00 0.00 -0.87 0.00 56.47 + a2 -0.42 0.00 0.00 0.00 0.00 -3.18 -3.47 0.00 0.00 1.34 9.32 0.00 -0.88 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.94 0.00 0.00 -1.41 0.00 0.00 0.00 0.00 0.00 0.00 1.58 0.00 -1.00 0.79 1.00 1.85 + Z 422272.53 0.00 0.00 0.00 0.003178266.423468202.00 0.00 0.00-1341038.00-9317892.00 0.00 877394.89 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 941281.42 0.00 0.001407055.21 0.00 0.00 0.00 0.00 0.00 0.00-1577117.42 0.001000000.00 208095.00 0.00-1847875.84 + +=== Iteracao: 6 === + VB x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 a1 a2 b + x4 0.75 0.00 0.00 1.00 0.00 0.59 0.65 0.00 0.00 0.20 0.00 0.00 -0.06 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.04 0.00 0.00 -0.01 0.00 0.00 0.00 0.00 0.00 0.00 -0.06 0.00 -0.28 0.06 0.28 4.38 + w1 -10.02 0.00 0.00 0.00 0.00 -6.11 -0.88 0.00 0.00 -2.71 0.00 1.00 -0.83 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.19 0.00 0.00 -1.56 0.00 0.00 0.00 0.00 0.00 0.00 -0.16 0.00 -2.63 -0.36 2.63 50.39 + x3 -0.26 0.00 1.00 0.00 0.00 -0.21 0.00 0.00 0.00 0.00 0.00 0.00 0.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.21 0.00 0.00 -0.11 0.00 0.00 0.00 0.00 0.00 0.00 0.21 0.00 0.00 -0.00 -0.00 1.42 + w3 6.62 0.00 0.00 0.00 0.00 7.31 0.16 0.00 0.00 5.78 0.00 0.00 1.35 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.10 0.00 0.00 1.55 0.00 0.00 0.00 0.00 0.00 0.00 -1.23 0.00 2.54 0.15 -2.54 10.99 + w4 12.88 0.00 0.00 0.00 0.00 15.50 3.15 0.00 0.00 9.34 0.00 0.00 -0.21 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.45 0.00 0.00 0.42 0.00 0.00 0.00 0.00 0.00 0.00 0.92 0.00 1.19 0.62 -1.19 36.20 + w5 2.48 0.00 0.00 0.00 0.00 -1.53 5.01 0.00 0.00 3.72 0.00 0.00 0.36 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.39 0.00 0.00 -0.46 0.00 0.00 0.00 0.00 0.00 0.00 -0.76 0.00 -0.45 0.39 0.45 30.77 + w6 1.06 0.00 0.00 0.00 0.00 2.22 2.81 0.00 0.00 0.07 0.00 0.00 0.14 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.54 0.00 0.00 -0.57 0.00 0.00 0.00 0.00 0.00 0.00 1.82 0.00 1.07 -0.58 -1.07 15.82 + w7 8.66 0.00 0.00 0.00 0.00 6.14 -0.29 0.00 0.00 -0.16 0.00 0.00 -1.16 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.15 0.00 0.00 -0.80 0.00 0.00 0.00 0.00 0.00 0.00 -0.88 0.00 -3.22 0.51 3.22 47.85 + w8 2.73 0.00 0.00 0.00 0.00 7.52 6.17 0.00 0.00 4.40 0.00 0.00 0.61 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.05 0.00 0.00 0.72 0.00 0.00 0.00 0.00 0.00 0.00 -0.15 0.00 1.27 -0.66 -1.27 13.19 + w9 -3.45 0.00 0.00 0.00 0.00 -0.92 1.08 0.00 0.00 -6.21 0.00 0.00 -1.85 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.58 0.00 0.00 -1.25 0.00 0.00 0.00 0.00 0.00 0.00 -1.46 0.00 -4.55 -0.13 4.55 77.56 + w10 0.58 0.00 0.00 0.00 0.00 10.29 7.20 0.00 0.00 1.27 0.00 0.00 -1.73 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.96 0.00 0.00 -1.30 0.00 0.00 0.00 0.00 0.00 0.00 -0.35 0.00 -4.79 0.17 4.79 75.48 + w11 1.23 0.00 0.00 0.00 0.00 10.37 0.26 0.00 0.00 -5.71 0.00 0.00 -1.45 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.85 0.00 0.00 0.22 0.00 0.00 0.00 0.00 0.00 0.00 -0.71 0.00 -1.21 -0.83 1.21 82.29 + w12 2.79 0.00 0.00 0.00 0.00 5.18 4.21 0.00 0.00 4.89 0.00 0.00 1.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 -1.22 0.00 0.00 0.71 0.00 0.00 0.00 0.00 0.00 0.00 0.04 0.00 1.93 0.36 -1.93 36.32 + w13 4.79 0.00 0.00 0.00 0.00 -0.43 4.22 0.00 0.00 0.61 0.00 0.00 -2.64 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.81 0.00 0.00 -2.04 0.00 0.00 0.00 0.00 0.00 0.00 -1.14 0.00 -6.02 0.25 6.02 87.25 + w14 1.01 0.00 0.00 0.00 0.00 1.02 1.45 0.00 0.00 -4.26 0.00 0.00 0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 -0.92 0.00 0.00 -0.81 0.00 0.00 0.00 0.00 0.00 0.00 -0.31 0.00 -1.12 0.49 1.12 10.24 + w15 5.77 0.00 0.00 0.00 0.00 6.57 1.34 0.00 0.00 -1.82 0.00 0.00 -1.72 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.59 0.00 0.00 -0.35 0.00 0.00 0.00 0.00 0.00 0.00 -2.12 0.00 -4.20 0.50 4.20 48.71 + w16 -3.66 0.00 0.00 0.00 0.00 -0.77 8.10 0.00 0.00 -2.77 0.00 0.00 -0.49 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 -0.23 0.00 0.00 -1.19 0.00 0.00 0.00 0.00 0.00 0.00 -0.46 0.00 -2.70 -0.09 2.70 35.66 + x5 -0.83 0.00 0.00 0.00 1.00 -0.73 0.06 0.00 0.00 -0.36 0.00 0.00 -0.15 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.10 0.00 0.00 -0.18 0.00 0.00 0.00 0.00 0.00 0.00 -0.03 0.00 -0.44 -0.06 0.44 5.05 + w18 -2.16 0.00 0.00 0.00 0.00 -6.10 3.59 0.00 0.00 -5.35 0.00 0.00 0.62 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.73 1.00 0.00 -0.31 0.00 0.00 0.00 0.00 0.00 0.00 -1.19 0.00 -0.03 -0.68 0.03 55.26 + w19 0.79 0.00 0.00 0.00 0.00 -2.80 -5.59 0.00 0.00 6.35 0.00 0.00 -0.15 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.62 0.00 1.00 -0.64 0.00 0.00 0.00 0.00 0.00 0.00 0.08 0.00 0.03 0.68 -0.03 56.53 + x2 -0.60 1.00 0.00 0.00 0.00 -1.00 -0.06 0.00 0.00 -0.64 0.00 0.00 -0.16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.16 0.00 0.00 -0.19 0.00 0.00 0.00 0.00 0.00 0.00 -0.23 0.00 -0.56 0.06 0.56 1.42 + w21 -7.32 0.00 0.00 0.00 0.00 -2.96 -2.02 0.00 0.00 0.66 0.00 0.00 -1.67 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.55 0.00 0.00 -1.10 1.00 0.00 0.00 0.00 0.00 0.00 -1.53 0.00 -2.78 -0.08 2.78 50.60 + w22 2.36 0.00 0.00 0.00 0.00 7.69 2.77 0.00 0.00 -0.23 0.00 0.00 1.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.16 0.00 0.00 0.73 0.00 1.00 0.00 0.00 0.00 0.00 -0.15 0.00 2.54 -0.69 -2.54 50.62 + w23 0.47 0.00 0.00 0.00 0.00 12.50 4.40 0.00 0.00 1.82 0.00 0.00 -0.98 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.39 0.00 0.00 -0.58 0.00 0.00 1.00 0.00 0.00 0.00 1.43 0.00 -1.39 -0.81 1.39 28.41 + w24 5.37 0.00 0.00 0.00 0.00 4.89 2.62 0.00 0.00 -3.67 0.00 0.00 0.38 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.55 0.00 0.00 0.30 0.00 0.00 0.00 1.00 0.00 0.00 0.55 0.00 2.28 -0.26 -2.28 45.94 + w25 -3.24 0.00 0.00 0.00 0.00 -6.61 6.49 0.00 0.00 4.24 0.00 0.00 -0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.35 0.00 0.00 -1.10 0.00 0.00 0.00 0.00 1.00 0.00 -1.06 0.00 -2.71 -0.24 2.71 77.97 + w26 4.87 0.00 0.00 0.00 0.00 12.69 9.12 0.00 0.00 3.47 0.00 0.00 0.75 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.06 0.00 0.00 1.68 0.00 0.00 0.00 0.00 0.00 1.00 -0.36 0.00 2.75 -0.71 -2.75 23.97 + x9 0.31 0.00 0.00 0.00 0.00 0.39 -0.21 -1.00 1.00 -0.17 0.00 0.00 -0.27 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.07 0.00 0.00 -0.12 0.00 0.00 0.00 0.00 0.00 0.00 0.09 0.00 -0.39 0.04 0.39 3.25 + w28 1.44 0.00 0.00 0.00 0.00 7.22 2.87 0.00 0.00 7.81 0.00 0.00 -0.28 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.41 0.00 0.00 -0.65 0.00 0.00 0.00 0.00 0.00 0.00 1.48 1.00 -0.55 -0.44 0.55 57.49 + x11 -0.05 0.00 0.00 0.00 0.00 -0.34 -0.37 0.00 0.00 0.14 1.00 0.00 -0.09 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.10 0.00 0.00 -0.15 0.00 0.00 0.00 0.00 0.00 0.00 0.17 0.00 -0.11 0.08 0.11 0.20 + Z 4.21 0.00 0.00 0.00 0.00 -2.41 3.99 0.00 0.00 -1.43 0.00 0.00 1.64 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.31 0.00 0.00 1.19 0.00 0.00 0.00 0.00 0.00 0.00 -0.01 0.00 2.911000000.21 999997.09 4.40 + +=== Iteracao: 7 === + VB x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 a1 a2 b + x4 0.22 0.00 0.00 1.00 0.00 0.00 0.64 0.00 0.00 -0.26 0.00 0.00 -0.17 -0.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.03 0.00 0.00 -0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.04 0.00 -0.49 0.05 0.49 3.50 + w1 -4.48 0.00 0.00 0.00 0.00 0.00 -0.74 0.00 0.00 2.11 0.00 1.00 0.30 0.84 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.28 0.00 0.00 -0.27 0.00 0.00 0.00 0.00 0.00 0.00 -1.19 0.00 -0.51 -0.23 0.51 59.57 + x3 -0.07 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.17 0.00 0.00 0.09 0.03 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.21 0.00 0.00 -0.06 0.00 0.00 0.00 0.00 0.00 0.00 0.18 0.00 0.07 0.00 -0.07 1.74 + x6 0.91 0.00 0.00 0.00 0.00 1.00 0.02 0.00 0.00 0.79 0.00 0.00 0.18 0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.01 0.00 0.00 0.21 0.00 0.00 0.00 0.00 0.00 0.00 -0.17 0.00 0.35 0.02 -0.35 1.50 + w4 -1.15 0.00 0.00 0.00 0.00 0.00 2.80 0.00 0.00 -2.90 0.00 0.00 -3.08 -2.12 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.23 0.00 0.00 -2.88 0.00 0.00 0.00 0.00 0.00 0.00 3.52 0.00 -4.18 0.29 4.18 12.92 + w5 3.86 0.00 0.00 0.00 0.00 0.00 5.04 0.00 0.00 4.93 0.00 0.00 0.65 0.21 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.41 0.00 0.00 -0.14 0.00 0.00 0.00 0.00 0.00 0.00 -1.02 0.00 0.08 0.43 -0.08 33.08 + w6 -0.95 0.00 0.00 0.00 0.00 0.00 2.76 0.00 0.00 -1.68 0.00 0.00 -0.27 -0.30 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.51 0.00 0.00 -1.04 0.00 0.00 0.00 0.00 0.00 0.00 2.19 0.00 0.30 -0.63 -0.30 12.49 + w7 3.10 0.00 0.00 0.00 0.00 0.00 -0.42 0.00 0.00 -5.01 0.00 0.00 -2.29 -0.84 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.06 0.00 0.00 -2.11 0.00 0.00 0.00 0.00 0.00 0.00 0.15 0.00 -5.35 0.38 5.35 38.62 + w8 -4.08 0.00 0.00 0.00 0.00 0.00 6.01 0.00 0.00 -1.54 0.00 0.00 -0.78 -1.03 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.06 0.00 0.00 -0.87 0.00 0.00 0.00 0.00 0.00 0.00 1.11 0.00 -1.34 -0.81 1.34 1.90 + w9 -2.61 0.00 0.00 0.00 0.00 0.00 1.11 0.00 0.00 -5.48 0.00 0.00 -1.68 0.13 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.57 0.00 0.00 -1.05 0.00 0.00 0.00 0.00 0.00 0.00 -1.62 0.00 -4.23 -0.11 4.23 78.95 + w10 -8.74 0.00 0.00 0.00 0.00 0.00 6.97 0.00 0.00 -6.86 0.00 0.00 -3.63 -1.41 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.81 0.00 0.00 -3.49 0.00 0.00 0.00 0.00 0.00 0.00 1.38 0.00 -8.37 -0.05 8.37 60.01 + w11 -8.16 0.00 0.00 0.00 0.00 0.00 0.02 0.00 0.00 -13.90 0.00 0.00 -3.37 -1.42 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 -1.98 0.00 0.00 0.00 0.00 0.00 0.00 1.03 0.00 -4.81 -1.05 4.81 66.71 + w12 -1.90 0.00 0.00 0.00 0.00 0.00 4.10 0.00 0.00 0.80 0.00 0.00 0.15 -0.71 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 -1.14 0.00 0.00 -0.39 0.00 0.00 0.00 0.00 0.00 0.00 0.91 0.00 0.14 0.25 -0.14 28.53 + w13 5.18 0.00 0.00 0.00 0.00 0.00 4.23 0.00 0.00 0.95 0.00 0.00 -2.56 0.06 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.81 0.00 0.00 -1.95 0.00 0.00 0.00 0.00 0.00 0.00 -1.21 0.00 -5.87 0.26 5.87 87.89 + w14 0.09 0.00 0.00 0.00 0.00 0.00 1.43 0.00 0.00 -5.06 0.00 0.00 -0.05 -0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 -0.91 0.00 0.00 -1.03 0.00 0.00 0.00 0.00 0.00 0.00 -0.14 0.00 -1.48 0.47 1.48 8.70 + w15 -0.17 0.00 0.00 0.00 0.00 0.00 1.19 0.00 0.00 -7.01 0.00 0.00 -2.94 -0.90 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.68 0.00 0.00 -1.75 0.00 0.00 0.00 0.00 0.00 0.00 -1.01 0.00 -6.47 0.36 6.47 38.84 + w16 -2.97 0.00 0.00 0.00 0.00 0.00 8.12 0.00 0.00 -2.17 0.00 0.00 -0.35 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 -0.24 0.00 0.00 -1.03 0.00 0.00 0.00 0.00 0.00 0.00 -0.58 0.00 -2.44 -0.07 2.44 36.81 + x5 -0.16 0.00 0.00 0.00 1.00 0.00 0.08 0.00 0.00 0.22 0.00 0.00 -0.02 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.09 0.00 0.00 -0.03 0.00 0.00 0.00 0.00 0.00 0.00 -0.15 0.00 -0.19 -0.04 0.19 6.15 + w18 3.36 0.00 0.00 0.00 0.00 0.00 3.72 0.00 0.00 -0.53 0.00 0.00 1.75 0.83 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.64 1.00 0.00 0.99 0.00 0.00 0.00 0.00 0.00 0.00 -2.21 0.00 2.09 -0.55 -2.09 64.42 + w19 3.32 0.00 0.00 0.00 0.00 0.00 -5.53 0.00 0.00 8.56 0.00 0.00 0.37 0.38 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.66 0.00 1.00 -0.05 0.00 0.00 0.00 0.00 0.00 0.00 -0.39 0.00 1.00 0.74 -1.00 60.73 + x2 0.31 1.00 0.00 0.00 0.00 0.00 -0.04 0.00 0.00 0.15 0.00 0.00 0.02 0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.15 0.00 0.00 0.03 0.00 0.00 0.00 0.00 0.00 0.00 -0.40 0.00 -0.21 0.08 0.21 2.93 + w21 -4.64 0.00 0.00 0.00 0.00 0.00 -1.95 0.00 0.00 3.00 0.00 0.00 -1.12 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.51 0.00 0.00 -0.47 1.00 0.00 0.00 0.00 0.00 0.00 -2.02 0.00 -1.75 -0.02 1.75 55.04 + w22 -4.60 0.00 0.00 0.00 0.00 0.00 2.60 0.00 0.00 -6.30 0.00 0.00 -0.09 -1.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.05 0.00 0.00 -0.90 0.00 1.00 0.00 0.00 0.00 0.00 1.14 0.00 -0.13 -0.85 0.13 39.08 + w23 -10.85 0.00 0.00 0.00 0.00 0.00 4.12 0.00 0.00 -8.06 0.00 0.00 -3.29 -1.71 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.22 0.00 0.00 -3.23 0.00 0.00 1.00 0.00 0.00 0.00 3.53 0.00 -5.72 -1.07 5.72 9.63 + w24 0.95 0.00 0.00 0.00 0.00 0.00 2.51 0.00 0.00 -7.53 0.00 0.00 -0.52 -0.67 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.48 0.00 0.00 -0.73 0.00 0.00 0.00 1.00 0.00 0.00 1.37 0.00 0.58 -0.36 -0.58 38.60 + w25 2.75 0.00 0.00 0.00 0.00 0.00 6.64 0.00 0.00 9.46 0.00 0.00 1.12 0.90 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.26 0.00 0.00 0.30 0.00 0.00 0.00 0.00 1.00 0.00 -2.17 0.00 -0.41 -0.11 0.41 87.90 + w26 -6.62 0.00 0.00 0.00 0.00 0.00 8.83 0.00 0.00 -6.55 0.00 0.00 -1.59 -1.74 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.11 0.00 0.00 -1.02 0.00 0.00 0.00 0.00 0.00 1.00 1.77 0.00 -1.65 -0.97 1.65 4.91 + x9 -0.04 0.00 0.00 0.00 0.00 0.00 -0.21 -1.00 1.00 -0.48 0.00 0.00 -0.34 -0.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.07 0.00 0.00 -0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.16 0.00 -0.52 0.03 0.52 2.66 + w28 -5.10 0.00 0.00 0.00 0.00 0.00 2.71 0.00 0.00 2.11 0.00 0.00 -1.61 -0.99 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.31 0.00 0.00 -2.18 0.00 0.00 0.00 0.00 0.00 0.00 2.70 1.00 -3.06 -0.59 3.06 46.65 + x11 0.26 0.00 0.00 0.00 0.00 0.00 -0.36 0.00 0.00 0.41 1.00 0.00 -0.03 0.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.11 0.00 0.00 -0.08 0.00 0.00 0.00 0.00 0.00 0.00 0.11 0.00 0.01 0.09 -0.01 0.71 + Z 6.39 0.00 0.00 0.00 0.00 0.00 4.04 0.00 0.00 0.47 0.00 0.00 2.09 0.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.28 0.00 0.00 1.70 0.00 0.00 0.00 0.00 0.00 0.00 -0.41 0.00 3.741000000.26 999996.26 8.02 + +=== Iteracao: 8 === + VB x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 a1 a2 b + x4 0.35 0.00 0.00 1.00 0.00 0.00 0.45 0.00 0.00 -0.21 0.00 0.00 -0.14 -0.05 0.00 0.00 0.00 0.00 -0.03 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.03 0.00 0.00 -0.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.44 0.08 0.44 3.44 + w1 -8.85 0.00 0.00 0.00 0.00 0.00 5.69 0.00 0.00 0.47 0.00 1.00 -0.53 -0.26 0.00 0.00 0.00 0.00 1.07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.22 0.00 0.00 -1.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.95 -1.11 1.95 61.61 + x3 0.57 0.00 1.00 0.00 0.00 0.00 -0.94 0.00 0.00 0.41 0.00 0.00 0.21 0.19 0.00 0.00 0.00 0.00 -0.16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.22 0.00 0.00 0.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.28 0.13 -0.28 1.44 + x6 0.29 0.00 0.00 0.00 0.00 1.00 0.93 0.00 0.00 0.56 0.00 0.00 0.07 -0.02 0.00 0.00 0.00 0.00 0.15 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.01 0.00 0.00 0.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.14 -0.10 -0.14 1.79 + w4 11.79 0.00 0.00 0.00 0.00 0.00 -16.27 0.00 0.00 1.98 0.00 0.00 -0.60 1.15 1.00 0.00 0.00 0.00 -3.18 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.42 0.00 0.00 -0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.08 2.88 -0.08 6.88 + w5 0.13 0.00 0.00 0.00 0.00 0.00 10.54 0.00 0.00 3.52 0.00 0.00 -0.07 -0.73 0.00 1.00 0.00 0.00 0.92 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.36 0.00 0.00 -0.94 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.15 -0.32 1.15 34.82 + w6 7.11 0.00 0.00 0.00 0.00 0.00 -9.11 0.00 0.00 1.36 0.00 0.00 1.27 1.73 0.00 0.00 1.00 0.00 -1.98 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.62 0.00 0.00 0.68 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2.95 0.98 -2.95 8.73 + w7 3.65 0.00 0.00 0.00 0.00 0.00 -1.24 0.00 0.00 -4.80 0.00 0.00 -2.19 -0.70 0.00 0.00 0.00 1.00 -0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.07 0.00 0.00 -1.99 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -5.17 0.49 5.17 38.37 + w27 -3.67 0.00 0.00 0.00 0.00 0.00 5.41 0.00 0.00 -1.39 0.00 0.00 -0.70 -0.93 0.00 0.00 0.00 0.00 0.90 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.05 0.00 0.00 -0.79 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 -1.21 -0.73 1.21 1.72 + w9 -8.56 0.00 0.00 0.00 0.00 0.00 9.87 0.00 0.00 -7.72 0.00 0.00 -2.82 -1.37 0.00 0.00 0.00 0.00 1.46 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.65 0.00 0.00 -2.32 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -6.18 -1.29 6.18 81.72 + w10 -3.67 0.00 0.00 0.00 0.00 0.00 -0.50 0.00 0.00 -4.95 0.00 0.00 -2.66 -0.13 0.00 0.00 0.00 0.00 -1.25 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.89 0.00 0.00 -2.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -6.70 0.96 6.70 57.64 + w11 -4.39 0.00 0.00 0.00 0.00 0.00 -5.54 0.00 0.00 -12.48 0.00 0.00 -2.65 -0.47 0.00 0.00 0.00 0.00 -0.93 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.94 0.00 0.00 -1.17 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -3.57 -0.29 3.57 64.95 + w12 1.46 0.00 0.00 0.00 0.00 0.00 -0.85 0.00 0.00 2.06 0.00 0.00 0.79 0.14 0.00 0.00 0.00 0.00 -0.82 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 -1.19 0.00 0.00 0.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.24 0.92 -1.24 26.96 + w13 0.75 0.00 0.00 0.00 0.00 0.00 10.77 0.00 0.00 -0.73 0.00 0.00 -3.41 -1.06 0.00 0.00 0.00 0.00 1.09 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.87 0.00 0.00 -2.90 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -7.33 -0.63 7.33 89.97 + w14 -0.42 0.00 0.00 0.00 0.00 0.00 2.18 0.00 0.00 -5.26 0.00 0.00 -0.15 -0.27 0.00 0.00 0.00 0.00 0.12 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 -0.90 0.00 0.00 -1.13 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.65 0.37 1.65 8.94 + w15 -3.90 0.00 0.00 0.00 0.00 0.00 6.68 0.00 0.00 -8.42 0.00 0.00 -3.65 -1.84 0.00 0.00 0.00 0.00 0.91 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.73 0.00 0.00 -2.55 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -7.70 -0.38 7.70 40.58 + w16 -5.11 0.00 0.00 0.00 0.00 0.00 11.28 0.00 0.00 -2.98 0.00 0.00 -0.76 -0.44 0.00 0.00 0.00 0.00 0.53 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 -0.21 0.00 0.00 -1.48 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -3.15 -0.50 3.15 37.81 + x5 -0.72 0.00 0.00 0.00 1.00 0.00 0.90 0.00 0.00 0.01 0.00 0.00 -0.12 -0.04 0.00 0.00 0.00 0.00 0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.10 0.00 0.00 -0.15 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.37 -0.15 0.37 6.41 + w18 -4.76 0.00 0.00 0.00 0.00 0.00 15.68 0.00 0.00 -3.59 0.00 0.00 0.19 -1.21 0.00 0.00 0.00 0.00 1.99 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.76 1.00 0.00 -0.75 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.58 -2.17 0.58 68.21 + w19 1.89 0.00 0.00 0.00 0.00 0.00 -3.42 0.00 0.00 8.02 0.00 0.00 0.10 0.02 0.00 0.00 0.00 0.00 0.35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.64 0.00 1.00 -0.35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.52 0.45 -0.52 61.40 + x2 -1.17 1.00 0.00 0.00 0.00 0.00 2.14 0.00 0.00 -0.41 0.00 0.00 -0.26 -0.24 0.00 0.00 0.00 0.00 0.36 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.17 0.00 0.00 -0.29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.70 -0.22 0.70 3.62 + w21 -12.07 0.00 0.00 0.00 0.00 0.00 9.00 0.00 0.00 0.19 0.00 0.00 -2.55 -1.47 0.00 0.00 0.00 0.00 1.82 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.61 0.00 0.00 -2.06 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -4.20 -1.51 4.20 58.51 + w22 -0.41 0.00 0.00 0.00 0.00 0.00 -3.58 0.00 0.00 -4.72 0.00 0.00 0.71 0.01 0.00 0.00 0.00 0.00 -1.03 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.11 0.00 0.00 -0.01 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 1.25 -0.02 -1.25 37.12 + w23 2.13 0.00 0.00 0.00 0.00 0.00 -15.00 0.00 0.00 -3.16 0.00 0.00 -0.80 1.56 0.00 0.00 0.00 0.00 -3.18 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.40 0.00 0.00 -0.45 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 -1.46 1.52 1.46 3.57 + w24 5.99 0.00 0.00 0.00 0.00 0.00 -4.92 0.00 0.00 -5.62 0.00 0.00 0.45 0.60 0.00 0.00 0.00 0.00 -1.24 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.55 0.00 0.00 0.34 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 2.24 0.64 -2.24 36.24 + w25 -5.22 0.00 0.00 0.00 0.00 0.00 18.39 0.00 0.00 6.45 0.00 0.00 -0.41 -1.11 0.00 0.00 0.00 0.00 1.96 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.38 0.00 0.00 -1.40 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 -3.04 -1.70 3.04 91.63 + w26 -0.10 0.00 0.00 0.00 0.00 0.00 -0.77 0.00 0.00 -4.09 0.00 0.00 -0.34 -0.09 0.00 0.00 0.00 0.00 -1.60 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.02 0.00 0.00 0.38 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.49 0.33 -0.49 1.86 + x9 0.54 0.00 0.00 0.00 0.00 0.00 -1.07 -1.00 1.00 -0.27 0.00 0.00 -0.23 0.09 0.00 0.00 0.00 0.00 -0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.07 0.00 0.00 -0.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.33 0.14 0.33 2.39 + w28 4.81 0.00 0.00 0.00 0.00 0.00 -11.89 0.00 0.00 5.84 0.00 0.00 0.29 1.51 0.00 0.00 0.00 0.00 -2.43 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.45 0.00 0.00 -0.06 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.20 1.39 -0.20 42.02 + x11 0.67 0.00 0.00 0.00 0.00 0.00 -0.97 0.00 0.00 0.57 1.00 0.00 0.05 0.15 0.00 0.00 0.00 0.00 -0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.11 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.15 0.17 -0.15 0.52 + Z 4.87 0.00 0.00 0.00 0.00 0.00 6.27 0.00 0.00 -0.10 0.00 0.00 1.80 -0.05 0.00 0.00 0.00 0.00 0.37 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.30 0.00 0.00 1.38 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 3.24 999999.96 999996.76 8.72 + +=== Iteracao: 9 === + VB x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 a1 a2 b + x4 0.60 0.00 0.00 1.00 0.00 0.00 0.08 0.00 0.00 0.00 0.37 0.00 -0.13 0.01 0.00 0.00 0.00 0.00 -0.07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.08 0.00 0.00 -0.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.39 0.14 0.39 3.63 + w1 -9.41 0.00 0.00 0.00 0.00 0.00 6.49 0.00 0.00 0.00 -0.82 1.00 -0.57 -0.39 0.00 0.00 0.00 0.00 1.15 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.12 0.00 0.00 -1.21 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -2.07 -1.25 2.07 61.19 + x3 0.09 0.00 1.00 0.00 0.00 0.00 -0.25 0.00 0.00 0.00 -0.72 0.00 0.18 0.08 0.00 0.00 0.00 0.00 -0.09 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.14 0.00 0.00 0.07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.18 0.01 -0.18 1.06 + x6 -0.37 0.00 0.00 0.00 0.00 1.00 1.88 0.00 0.00 0.00 -0.98 0.00 0.02 -0.17 0.00 0.00 0.00 0.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.10 0.00 0.00 0.07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.27 -0.00 1.28 + w4 9.44 0.00 0.00 0.00 0.00 0.00 -12.88 0.00 0.00 0.00 -3.49 0.00 -0.77 0.62 1.00 0.00 0.00 0.00 -2.82 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.03 0.00 0.00 -0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.44 2.27 0.44 5.07 + w5 -4.05 0.00 0.00 0.00 0.00 0.00 16.55 0.00 0.00 0.00 -6.19 0.00 -0.37 -1.66 0.00 1.00 0.00 0.00 1.54 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.33 0.00 0.00 -1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -2.06 -1.40 2.06 31.61 + w6 5.49 0.00 0.00 0.00 0.00 0.00 -6.79 0.00 0.00 0.00 -2.39 0.00 1.16 1.37 0.00 0.00 1.00 0.00 -1.74 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.36 0.00 0.00 0.66 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2.60 0.56 -2.60 7.49 + w7 9.35 0.00 0.00 0.00 0.00 0.00 -9.43 0.00 0.00 0.00 8.44 0.00 -1.78 0.57 0.00 0.00 0.00 1.00 -0.99 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.02 0.00 0.00 -1.91 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -3.94 1.96 3.94 42.74 + w27 -2.03 0.00 0.00 0.00 0.00 0.00 3.05 0.00 0.00 0.00 2.44 0.00 -0.59 -0.56 0.00 0.00 0.00 0.00 0.66 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.22 0.00 0.00 -0.76 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 -0.85 -0.31 0.85 2.98 + w9 0.60 0.00 0.00 0.00 0.00 0.00 -3.31 0.00 0.00 0.00 13.58 0.00 -2.17 0.67 0.00 0.00 0.00 0.00 0.09 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.86 0.00 0.00 -2.19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -4.20 1.07 4.20 88.76 + w10 2.21 0.00 0.00 0.00 0.00 0.00 -8.96 0.00 0.00 0.00 8.71 0.00 -2.24 1.18 0.00 0.00 0.00 0.00 -2.12 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.86 0.00 0.00 -2.32 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -5.42 2.48 5.42 62.16 + w11 10.42 0.00 0.00 0.00 0.00 0.00 -26.85 0.00 0.00 0.00 21.95 0.00 -1.60 2.83 0.00 0.00 0.00 0.00 -3.14 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 -1.51 0.00 0.00 -0.96 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.36 3.53 0.36 76.33 + w12 -0.99 0.00 0.00 0.00 0.00 0.00 2.68 0.00 0.00 0.00 -3.63 0.00 0.62 -0.41 0.00 0.00 0.00 0.00 -0.46 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 -0.79 0.00 0.00 0.29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.71 0.29 -0.71 25.08 + w13 1.61 0.00 0.00 0.00 0.00 0.00 9.53 0.00 0.00 0.00 1.28 0.00 -3.35 -0.87 0.00 0.00 0.00 0.00 0.96 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.73 0.00 0.00 -2.89 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -7.14 -0.40 7.14 90.63 + w14 5.82 0.00 0.00 0.00 0.00 0.00 -6.80 0.00 0.00 0.00 9.24 0.00 0.29 1.12 0.00 0.00 0.00 0.00 -0.81 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 -1.93 0.00 0.00 -1.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.29 1.98 0.29 13.73 + w15 6.09 0.00 0.00 0.00 0.00 0.00 -7.69 0.00 0.00 0.00 14.81 0.00 -2.94 0.39 0.00 0.00 0.00 0.00 -0.58 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 -0.92 0.00 0.00 -2.41 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -5.53 2.19 5.53 48.26 + w16 -1.58 0.00 0.00 0.00 0.00 0.00 6.20 0.00 0.00 0.00 5.24 0.00 -0.51 0.35 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 -0.79 0.00 0.00 -1.43 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -2.38 0.41 2.38 40.53 + x5 -0.73 0.00 0.00 0.00 1.00 0.00 0.92 0.00 0.00 0.00 -0.02 0.00 -0.12 -0.04 0.00 0.00 0.00 0.00 0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.10 0.00 0.00 -0.15 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.37 -0.16 0.37 6.40 + w18 -0.49 0.00 0.00 0.00 0.00 0.00 9.55 0.00 0.00 0.00 6.32 0.00 0.49 -0.26 0.00 0.00 0.00 0.00 1.35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.05 1.00 0.00 -0.69 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.34 -1.07 -0.34 71.49 + w19 -7.62 0.00 0.00 0.00 0.00 0.00 10.27 0.00 0.00 0.00 -14.10 0.00 -0.58 -2.10 0.00 0.00 0.00 0.00 1.77 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.93 0.00 1.00 -0.49 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.54 -2.00 1.54 54.09 + x2 -0.68 1.00 0.00 0.00 0.00 0.00 1.44 0.00 0.00 0.00 0.72 0.00 -0.23 -0.13 0.00 0.00 0.00 0.00 0.29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.09 0.00 0.00 -0.28 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.59 -0.09 0.59 3.99 + w21 -12.30 0.00 0.00 0.00 0.00 0.00 9.33 0.00 0.00 0.00 -0.34 0.00 -2.57 -1.52 0.00 0.00 0.00 0.00 1.86 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.65 0.00 0.00 -2.07 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -4.25 -1.57 4.25 58.34 + w22 5.20 0.00 0.00 0.00 0.00 0.00 -11.64 0.00 0.00 0.00 8.31 0.00 1.11 1.25 0.00 0.00 0.00 0.00 -1.87 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.04 0.00 0.00 0.07 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 2.47 1.43 -2.47 41.42 + w23 5.88 0.00 0.00 0.00 0.00 0.00 -20.40 0.00 0.00 0.00 5.56 0.00 -0.54 2.40 0.00 0.00 0.00 0.00 -3.75 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -2.02 0.00 0.00 -0.40 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 -0.64 2.49 0.64 6.46 + w24 12.67 0.00 0.00 0.00 0.00 0.00 -14.52 0.00 0.00 0.00 9.89 0.00 0.92 2.09 0.00 0.00 0.00 0.00 -2.24 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.66 0.00 0.00 0.44 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 3.69 2.37 -3.69 41.37 + w25 -12.88 0.00 0.00 0.00 0.00 0.00 29.41 0.00 0.00 0.00 -11.35 0.00 -0.95 -2.81 0.00 0.00 0.00 0.00 3.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.64 0.00 0.00 -1.51 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 -4.70 -3.67 4.70 85.74 + w26 4.76 0.00 0.00 0.00 0.00 0.00 -7.76 0.00 0.00 0.00 7.20 0.00 0.00 0.99 0.00 0.00 0.00 0.00 -2.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.79 0.00 0.00 0.45 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 1.55 1.58 -1.55 5.60 + x9 0.85 0.00 0.00 0.00 0.00 0.00 -1.52 -1.00 1.00 0.00 0.47 0.00 -0.21 0.16 0.00 0.00 0.00 0.00 -0.19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.13 0.00 0.00 -0.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.27 0.22 0.27 2.63 + w28 -2.12 0.00 0.00 0.00 0.00 0.00 -1.91 0.00 0.00 0.00 -10.28 0.00 -0.20 -0.03 0.00 0.00 0.00 0.00 -1.39 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.31 0.00 0.00 -0.16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 -1.30 -0.40 1.30 36.69 + x10 1.19 0.00 0.00 0.00 0.00 0.00 -1.71 0.00 0.00 1.00 1.76 0.00 0.08 0.26 0.00 0.00 0.00 0.00 -0.18 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.20 0.00 0.00 0.02 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.26 0.31 -0.26 0.91 + Z 4.99 0.00 0.00 0.00 0.00 0.00 6.10 0.00 0.00 0.00 0.18 0.00 1.81 -0.03 0.00 0.00 0.00 0.00 0.35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.28 0.00 0.00 1.38 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 3.27 999999.99 999996.73 8.82 + +=== Iteracao: 10 === + VB x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 a1 a2 b + x4 0.58 0.00 0.00 1.00 0.00 0.00 0.16 0.00 0.00 0.00 0.35 0.00 -0.12 0.00 0.00 0.00 0.00 0.00 -0.06 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.07 0.00 0.00 -0.11 0.00 0.00 -0.00 0.00 0.00 0.00 0.00 0.00 -0.39 0.13 0.39 3.61 + w1 -8.45 0.00 0.00 0.00 0.00 0.00 3.19 0.00 0.00 0.00 0.08 1.00 -0.66 0.00 0.00 0.00 0.00 0.00 0.55 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.45 0.00 0.00 -1.27 0.00 0.00 0.16 0.00 0.00 0.00 0.00 0.00 -2.17 -0.85 2.17 62.23 + x3 -0.12 0.00 1.00 0.00 0.00 0.00 0.46 0.00 0.00 0.00 -0.91 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.04 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.07 0.00 0.00 0.08 0.00 0.00 -0.03 0.00 0.00 0.00 0.00 0.00 0.20 -0.08 -0.20 0.84 + x6 0.03 0.00 0.00 0.00 0.00 1.00 0.47 0.00 0.00 0.00 -0.59 0.00 -0.02 0.00 0.00 0.00 0.00 0.00 -0.01 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.04 0.00 0.00 0.04 0.00 0.00 0.07 0.00 0.00 0.00 0.00 0.00 -0.04 -0.10 0.04 1.73 + w4 7.92 0.00 0.00 0.00 0.00 0.00 -7.61 0.00 0.00 0.00 -4.93 0.00 -0.63 0.00 1.00 0.00 0.00 0.00 -1.86 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.51 0.00 0.00 -0.03 0.00 0.00 -0.26 0.00 0.00 0.00 0.00 0.00 -0.27 1.62 0.27 3.40 + w5 0.03 0.00 0.00 0.00 0.00 0.00 2.41 0.00 0.00 0.00 -2.33 0.00 -0.74 0.00 0.00 1.00 0.00 0.00 -1.06 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -1.07 0.00 0.00 -1.28 0.00 0.00 0.69 0.00 0.00 0.00 0.00 0.00 -2.50 0.33 2.50 36.09 + w6 2.13 0.00 0.00 0.00 0.00 0.00 4.86 0.00 0.00 0.00 -5.57 0.00 1.46 0.00 0.00 0.00 1.00 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.20 0.00 0.00 0.89 0.00 0.00 -0.57 0.00 0.00 0.00 0.00 0.00 2.97 -0.86 -2.97 3.80 + w7 7.96 0.00 0.00 0.00 0.00 0.00 -4.59 0.00 0.00 0.00 7.12 0.00 -1.66 0.00 0.00 0.00 0.00 1.00 -0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.54 0.00 0.00 -1.81 0.00 0.00 -0.24 0.00 0.00 0.00 0.00 0.00 -3.79 1.37 3.79 41.21 + w27 -0.66 0.00 0.00 0.00 0.00 0.00 -1.71 0.00 0.00 0.00 3.74 0.00 -0.71 0.00 0.00 0.00 0.00 0.00 -0.22 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.69 0.00 0.00 -0.86 0.00 0.00 0.23 0.00 0.00 0.00 1.00 0.00 -1.00 0.27 1.00 4.49 + w9 -1.04 0.00 0.00 0.00 0.00 0.00 2.37 0.00 0.00 0.00 12.03 0.00 -2.02 0.00 0.00 0.00 0.00 0.00 1.13 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.30 0.00 0.00 -2.08 0.00 0.00 -0.28 0.00 0.00 0.00 0.00 0.00 -4.02 0.38 4.02 86.97 + w10 -0.69 0.00 0.00 0.00 0.00 0.00 1.09 0.00 0.00 0.00 5.97 0.00 -1.98 0.00 0.00 0.00 0.00 0.00 -0.28 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.86 0.00 0.00 -2.12 0.00 0.00 -0.49 0.00 0.00 0.00 0.00 0.00 -5.11 1.26 5.11 58.98 + w11 3.47 0.00 0.00 0.00 0.00 0.00 -2.74 0.00 0.00 0.00 15.38 0.00 -0.96 0.00 0.00 0.00 0.00 0.00 1.28 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.88 0.00 0.00 -0.49 0.00 0.00 -1.18 0.00 0.00 0.00 0.00 0.00 0.40 0.59 -0.40 68.71 + w12 0.01 0.00 0.00 0.00 0.00 0.00 -0.79 0.00 0.00 0.00 -2.69 0.00 0.53 0.00 0.00 0.00 0.00 0.00 -1.09 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 -1.13 0.00 0.00 0.22 0.00 0.00 0.17 0.00 0.00 0.00 0.00 0.00 0.60 0.71 -0.60 26.18 + w13 3.74 0.00 0.00 0.00 0.00 0.00 2.15 0.00 0.00 0.00 3.29 0.00 -3.54 0.00 0.00 0.00 0.00 0.00 -0.40 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 -0.00 0.00 0.00 -3.04 0.00 0.00 0.36 0.00 0.00 0.00 0.00 0.00 -7.37 0.50 7.37 92.97 + w14 3.07 0.00 0.00 0.00 0.00 0.00 2.75 0.00 0.00 0.00 6.64 0.00 0.55 0.00 0.00 0.00 0.00 0.00 0.94 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 -0.99 0.00 0.00 -0.86 0.00 0.00 -0.47 0.00 0.00 0.00 0.00 0.00 0.01 0.82 -0.01 10.71 + w15 5.14 0.00 0.00 0.00 0.00 0.00 -4.39 0.00 0.00 0.00 13.91 0.00 -2.86 0.00 0.00 0.00 0.00 0.00 0.03 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 -0.59 0.00 0.00 -2.34 0.00 0.00 -0.16 0.00 0.00 0.00 0.00 0.00 -5.43 1.79 5.43 47.22 + w16 -2.44 0.00 0.00 0.00 0.00 0.00 9.18 0.00 0.00 0.00 4.42 0.00 -0.44 0.00 0.00 0.00 0.00 0.00 0.55 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 -0.50 0.00 0.00 -1.38 0.00 0.00 -0.15 0.00 0.00 0.00 0.00 0.00 -2.29 0.05 2.29 39.58 + x5 -0.63 0.00 0.00 0.00 1.00 0.00 0.55 0.00 0.00 0.00 0.08 0.00 -0.13 0.00 0.00 0.00 0.00 0.00 0.07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.06 0.00 0.00 -0.15 0.00 0.00 0.02 0.00 0.00 0.00 0.00 0.00 -0.38 -0.11 0.38 6.52 + w18 0.15 0.00 0.00 0.00 0.00 0.00 7.32 0.00 0.00 0.00 6.93 0.00 0.43 0.00 0.00 0.00 0.00 0.00 0.94 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.17 1.00 0.00 -0.73 0.00 0.00 0.11 0.00 0.00 0.00 0.00 0.00 0.27 -0.80 -0.27 72.19 + w19 -2.48 0.00 0.00 0.00 0.00 0.00 -7.58 0.00 0.00 0.00 -9.24 0.00 -1.05 0.00 0.00 0.00 0.00 0.00 -1.50 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.84 0.00 1.00 -0.84 0.00 0.00 0.87 0.00 0.00 0.00 0.00 0.00 -2.10 0.17 2.10 59.73 + x2 -0.37 1.00 0.00 0.00 0.00 0.00 0.35 0.00 0.00 0.00 1.02 0.00 -0.26 0.00 0.00 0.00 0.00 0.00 0.09 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.02 0.00 0.00 -0.30 0.00 0.00 0.05 0.00 0.00 0.00 0.00 0.00 -0.63 0.04 0.63 4.34 + w21 -8.57 0.00 0.00 0.00 0.00 0.00 -3.60 0.00 0.00 0.00 3.19 0.00 -2.91 0.00 0.00 0.00 0.00 0.00 -0.52 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.37 0.00 0.00 -2.32 1.00 0.00 0.63 0.00 0.00 0.00 0.00 0.00 -4.65 0.01 4.65 62.43 + w22 2.12 0.00 0.00 0.00 0.00 0.00 -0.97 0.00 0.00 0.00 5.40 0.00 1.39 0.00 0.00 0.00 0.00 0.00 0.09 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.02 0.00 0.00 0.28 0.00 1.00 -0.52 0.00 0.00 0.00 0.00 0.00 2.80 0.13 -2.80 38.05 + w3 2.45 0.00 0.00 0.00 0.00 0.00 -8.50 0.00 0.00 0.00 2.32 0.00 -0.22 1.00 0.00 0.00 0.00 0.00 -1.56 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.84 0.00 0.00 -0.17 0.00 0.00 0.42 0.00 0.00 0.00 0.00 0.00 -0.27 1.04 0.27 2.69 + w24 7.54 0.00 0.00 0.00 0.00 0.00 3.26 0.00 0.00 0.00 5.04 0.00 1.39 0.00 0.00 0.00 0.00 0.00 1.03 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.10 0.00 0.00 0.79 0.00 0.00 -0.87 1.00 0.00 0.00 0.00 0.00 4.25 0.20 -4.25 35.74 + w25 -5.99 0.00 0.00 0.00 0.00 0.00 5.49 0.00 0.00 0.00 -4.83 0.00 -1.58 0.00 0.00 0.00 0.00 0.00 -1.29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.73 0.00 0.00 -1.98 0.00 0.00 1.17 0.00 1.00 0.00 0.00 0.00 -5.45 -0.76 5.45 93.31 + w26 2.33 0.00 0.00 0.00 0.00 0.00 0.67 0.00 0.00 0.00 4.90 0.00 0.22 0.00 0.00 0.00 0.00 0.00 -0.78 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.05 0.00 0.00 0.61 0.00 0.00 -0.41 0.00 0.00 1.00 0.00 0.00 1.81 0.56 -1.81 2.93 + x9 0.45 0.00 0.00 0.00 0.00 0.00 -0.14 -1.00 1.00 0.00 0.09 0.00 -0.17 0.00 0.00 0.00 0.00 0.00 0.06 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.01 0.00 0.00 -0.05 0.00 0.00 -0.07 0.00 0.00 0.00 0.00 0.00 -0.22 0.06 0.22 2.20 + w28 -2.04 0.00 0.00 0.00 0.00 0.00 -2.20 0.00 0.00 0.00 -10.20 0.00 -0.21 0.00 0.00 0.00 0.00 0.00 -1.45 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.33 0.00 0.00 -0.17 0.00 0.00 0.01 0.00 0.00 0.00 0.00 1.00 -1.31 -0.36 1.31 36.78 + x10 0.54 0.00 0.00 0.00 0.00 0.00 0.54 0.00 0.00 1.00 1.15 0.00 0.14 0.00 0.00 0.00 0.00 0.00 0.24 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.03 0.00 0.00 0.06 0.00 0.00 -0.11 0.00 0.00 0.00 0.00 0.00 0.33 0.03 -0.33 0.20 + Z 5.06 0.00 0.00 0.00 0.00 0.00 5.88 0.00 0.00 0.00 0.24 0.00 1.80 0.00 0.00 0.00 0.00 0.00 0.31 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.26 0.00 0.00 1.38 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.00 3.261000000.02 999996.74 8.89 + +================================================================================ +Solução + +FO: 8.8870 +x1 = 0.0000 +x2 = -4.3388 +x3 = -0.8407 +x4 = 3.6057 +x5 = 6.5191 +x6 = 1.7292 +x7 = 0.0000 +x8 = -2.1956 +x9 = 0.2003 +x10 = 0.0000 + +R1 = 5.0000 <= 5.0000 <= 5.0000 +R2 = None <= -2.2321 <= 60.0000 +R3 = None <= 33.0000 <= 33.0000 +R4 = None <= 54.3092 <= 57.0000 +R5 = None <= 60.6043 <= 64.0000 +R6 = None <= 30.9148 <= 67.0000 +R7 = None <= 31.1974 <= 35.0000 +R8 = None <= 0.7883 <= 42.0000 +R9 = None <= 22.0000 <= 22.0000 +R10 = None <= -12.9650 <= 74.0000 +R11 = None <= -9.9781 <= 49.0000 +R12 = None <= 20.2931 <= 89.0000 +R13 = None <= 46.8214 <= 73.0000 +R14 = None <= -28.9666 <= 64.0000 +R15 = None <= 25.2878 <= 36.0000 +R16 = None <= -3.2153 <= 44.0000 +R17 = None <= -10.5820 <= 29.0000 +R18 = None <= 28.0000 <= 28.0000 +R19 = None <= 14.8055 <= 87.0000 +R20 = None <= 40.2664 <= 100.0000 +R21 = None <= 43.0000 <= 43.0000 +R22 = None <= 15.5688 <= 78.0000 +R23 = None <= 48.9527 <= 87.0000 +R24 = None <= 7.0000 <= 7.0000 +R25 = None <= 61.2576 <= 97.0000 +R26 = None <= -25.3125 <= 68.0000 +R27 = None <= 51.0702 <= 54.0000 +R28 = None <= 43.5139 <= 48.0000 +R29 = None <= 7.2213 <= 44.0000 +R30 = 38.0000 <= 38.0000 <= None diff --git a/main/simplex.py b/main/simplex.py index 871b34b..445c627 100644 --- a/main/simplex.py +++ b/main/simplex.py @@ -1,4 +1,5 @@ from tableau import Tableau +import os class Simplex: def __init__(self, objective_coeffs, constraints, @@ -13,8 +14,9 @@ def __init__(self, objective_coeffs, constraints, self.original_objective_type = objective_type self.orig_num_vars = len(objective_coeffs) self.var_signs = var_signs if var_signs else [">=0"] * self.orig_num_vars + self.original_constraints = constraints[:] - self.c, self.constraints, self._map_orig_to_internal = self._expand_variables( + self.c, self.constraints, self._map_orig_to_internal = self.expand_variables( objective_coeffs, constraints, self.var_signs ) @@ -27,17 +29,14 @@ def __init__(self, objective_coeffs, constraints, self.objective_type = "Max" self.num_vars = len(self.c) - self.M = 1000000 - self.tableau_obj = None - self.artificial_indices = [] - self.solution = None self.optimal_value = None + self.iteration_logs = [] - def _expand_variables(self, c, constraints, var_signs): + def expand_variables(self, c, constraints, var_signs): n = len(c) A = [list(coeffs) for (coeffs, _, _) in constraints] ops = [op for (_, op, _) in constraints] @@ -164,30 +163,28 @@ def simplex_iterations(self): """ max_iterations = 1000 iteration = 0 - + + self.iteration_logs.append(self.tableau_obj.format_tableau(iteration=0)) self.tableau_obj.print_tableau(iteration=0) while iteration < max_iterations: iteration += 1 pivot_col = self.find_pivot_column() - if pivot_col is None: if self.check_artificial_in_basis(): return "infeasible" return "optimal" - # find pivot row (variable leaving the basis) pivot_row = self.find_pivot_row(pivot_col) - if pivot_row is None: return "unbounded" self.pivot(pivot_row, pivot_col) - all_var_names = self.tableau_obj.get_all_var_names() self.tableau_obj.basis[pivot_row] = all_var_names[pivot_col] - + + self.iteration_logs.append(self.tableau_obj.format_tableau(iteration=iteration)) self.tableau_obj.print_tableau(iteration=iteration) return "max_iterations_reached" @@ -265,9 +262,7 @@ def check_artificial_in_basis(self): def extract_solution(self): internal_solution = [0.0] * self.num_vars - all_var_names = self.tableau_obj.get_all_var_names() - for i, var_name in enumerate(self.tableau_obj.basis): if var_name and var_name.startswith('x'): var_index = int(var_name[1:]) - 1 @@ -285,7 +280,37 @@ def extract_solution(self): sol[i] = internal_solution[plus] - internal_solution[minus] self.solution = sol - self.optimal_value = self.tableau_obj.tableau[-1][-1] if self.is_minimization: - self.optimal_value = -self.optimal_value \ No newline at end of file + self.optimal_value = -self.optimal_value + + def write_report(self, filepath): + os.makedirs(os.path.dirname(filepath), exist_ok=True) + lines = [] + + lines.append("Iterações do Simplex") + lines.append("=" * 80) + lines.extend(self.iteration_logs) + lines.append("=" * 80) + lines.append("Solução") + lines.append("") + lines.append(f"FO: {self.optimal_value:.4f}") + + for i, v in enumerate(self.solution, start=1): + lines.append(f"x{i} = {v:.4f}") + lines.append("") + + for k, (coeffs, op, rhs) in enumerate(self.original_constraints, start=1): + lhs = 0.0 + for j, a in enumerate(coeffs): + lhs += float(a) * float(self.solution[j] if j < len(self.solution) else 0.0) + if op == "<=": + line = f"R{k} = None <= {lhs:.4f} <= {float(rhs):.4f}" + elif op == ">=": + line = f"R{k} = {float(rhs):.4f} <= {lhs:.4f} <= None" + else: + line = f"R{k} = {float(rhs):.4f} <= {lhs:.4f} <= {float(rhs):.4f}" + lines.append(line) + + with open(filepath, "w", encoding="utf-8") as f: + f.write("\n".join(lines) + "\n") \ No newline at end of file diff --git a/main/tableau.py b/main/tableau.py index 204f79b..f204fc8 100644 --- a/main/tableau.py +++ b/main/tableau.py @@ -93,27 +93,19 @@ def build_tableau(self, slack_indices, artificial_indices=None, M=1000000, slack def get_all_var_names(self): return self.var_names + self.slack_vars + self.artificial_vars - # ========================================================== - # Impressão do tableau - # ========================================================== - def print_tableau(self, iteration=0): + def format_tableau(self, iteration=0): all_vars = self.get_all_var_names() cabecalho = ["VB"] + all_vars + ["b"] - largura = 8 - - print(f"=== Iteracao: {iteration} ===") - print(f"{cabecalho[0]:>15}", end="") - for elemento in cabecalho[1:]: - print(f"{elemento:>{largura}}", end="") - print() - + largura = 10 + lines = [] + lines.append(f"=== Iteracao: {iteration} ===") + lines.append(f"{cabecalho[0]:>15}" + "".join(f"{el:>{largura}}" for el in cabecalho[1:])) for i, var in enumerate(self.basis): - print(f"{var:>15}", end="") - for valor in self.tableau[i]: - print(f"{valor:>{largura}.2f}", end="") - print() - - print(f"{'Z':>15}", end="") - for valor in self.tableau[-1]: - print(f"{valor:>{largura}.2f}", end="") - print() \ No newline at end of file + row = f"{(var or ''):>15}" + "".join(f"{v:>{largura}.2f}" for v in self.tableau[i]) + lines.append(row) + obj = f"{'Z':>15}" + "".join(f"{v:>{largura}.2f}" for v in self.tableau[-1]) + lines.append(obj) + return "\n".join(lines) + "\n" + + def print_tableau(self, iteration=0): + print(self.format_tableau(iteration), end="") \ No newline at end of file From 9b872613669fc2c13f5e200c267fbe7e317617fd Mon Sep 17 00:00:00 2001 From: EricoMeger Date: Tue, 25 Nov 2025 08:47:22 -0300 Subject: [PATCH 12/15] explain parser's regex usage --- main/parser.py | 52 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/main/parser.py b/main/parser.py index 364f1c8..ce16af2 100644 --- a/main/parser.py +++ b/main/parser.py @@ -67,6 +67,19 @@ def parse(self): } def is_non_negative(self, line): + """ + x\d+\s*(>=|<=)\s*0$: + x\d+ - 'x' followed by one or more digits (variable index, e.g. x1, x2) + \s* - any number of spaces + (>=|<=) - either the ">=" or "<=" comparison operator + \s* - any number of spaces + 0 - the numeric bound zero + $ - end of line anchor to ensure the entire tail matches (so it wont match extra trailing chars) + + This pattern matches lines like: "x1 >= 0" or "x2 <= 0". + In addition, we also treat lines containing the word "livre" (Portuguese for "free") + as indicating a free variable (no sign restriction). + """ return re.match(r"x\d+\s*(>=|<=)\s*0$", line) is not None or "livre" in line.lower() def parse_non_negative(self, line): @@ -103,15 +116,16 @@ def parse_objective(self, line): raise ValueError("Objective function must be Max or Min.") """ - Regex atualizado para aceitar espaços entre coeficiente e variável: - ([+-]?\s*\d*)\s* - coeficiente com possíveis espaços após - x\s*(\d+) - 'x' seguido de possíveis espaços e depois o índice - - Exemplos que funciona: - - "3x1" (sem espaço) - - "3 x1" (com espaço) - - "+ 3x1" (sinal com espaço) - - "+3 x1" (combinação) + Explaining the regex: + ([+-]?\s*\d*) - 1st step, we search for the coefficient of the variable: + [+-]? - an optional '+' or '-' sign + \s* - followed by any number of spaces + \d* - followed by any number of digits (the coefficient itself) + \s*x\s*(\d+) - 2nd step, we look for the variable part: + \s* - any number of spaces + x - the character 'x' indicating a variable + \s* - any number of spaces + (\d+) - followed by one or more digits (the variable index, e.g. x1, x2, etc.) """ coeffs = re.findall(r'([+-]?\s*\d*)\s*x\s*(\d+)', line) @@ -145,13 +159,19 @@ def parse_constraint(self, line): var = int(var) parsed[var - 1] = raw_coeff - if "<=" in line: - comp = "<=" - elif ">=" in line: - comp = ">=" - else: - comp = "=" - + if "<=" in line: + comp = "<=" + elif ">=" in line: + comp = ">=" + else: + comp = "=" + + """ + (-?\d+)$ + -? - matches an optional negative sign + \d+ - matches one or more digits + $ - guarantees that the match is at the end of the line + """ b = int(re.findall(r'(-?\d+)$', line)[0]) self.constraints.append((parsed, comp, b)) From a21df45095228461f8dd00bf8eb927345bd5f615 Mon Sep 17 00:00:00 2001 From: IgorSPinto Date: Mon, 24 Nov 2025 17:23:00 -0300 Subject: [PATCH 13/15] refactor SimplexSolver and Tableau classes to enhance variable handling, improve tableau construction, and streamline objective row management --- main/tableau.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main/tableau.py b/main/tableau.py index f204fc8..3290bf8 100644 --- a/main/tableau.py +++ b/main/tableau.py @@ -53,6 +53,7 @@ def build_tableau(self, slack_indices, artificial_indices=None, M=1000000, slack num_cols = n + num_slack + num_artificial + 1 self.tableau = [[0.0] * num_cols for _ in range(m + 1)] + # coluna b for i in range(m): for j in range(n): self.tableau[i][j] = float(self.A[i][j]) @@ -107,5 +108,8 @@ def format_tableau(self, iteration=0): lines.append(obj) return "\n".join(lines) + "\n" + # ========================================================== + # Impressão do tableau + # ========================================================== def print_tableau(self, iteration=0): print(self.format_tableau(iteration), end="") \ No newline at end of file From 3b6a97835a5a951f50fc37886d8ffc5216eab2f1 Mon Sep 17 00:00:00 2001 From: EricoMeger Date: Mon, 1 Dec 2025 18:01:01 -0300 Subject: [PATCH 14/15] fix parser --- main/parser.py | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/main/parser.py b/main/parser.py index ce16af2..17c0465 100644 --- a/main/parser.py +++ b/main/parser.py @@ -1,23 +1,12 @@ -# parser.py import re class Parser: """ - Parser que lê arquivo input com formato: - Max 3x1 + 5x2 - x1 + 2x2 <= 6 - 3x1 + 2x2 <= 12 - x1 >= 0 - x2 free - - Retorna dicionário com: - { - "objective_type": "Max"/"Min", - "objective_coeffs": [...], - "constraints": [(row, comp, b), ...], - "num_vars": n, - "non_negative": [...] - } + Max 2x1 + 3x2 + 2x1 + x2 <= 10 + x1 + 3x2 <= 5 + x1 >= 0 + x2 >= 0 """ def __init__(self, filepath): @@ -174,4 +163,4 @@ def parse_constraint(self, line): """ b = int(re.findall(r'(-?\d+)$', line)[0]) - self.constraints.append((parsed, comp, b)) + self.constraints.append((parsed, comp, b)) \ No newline at end of file From 0e60c278f479abc23445912ff70d5a271c91da15 Mon Sep 17 00:00:00 2001 From: EricoMeger Date: Mon, 1 Dec 2025 18:01:39 -0300 Subject: [PATCH 15/15] fix tableau --- main/tableau.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/main/tableau.py b/main/tableau.py index 3290bf8..e0ce7c5 100644 --- a/main/tableau.py +++ b/main/tableau.py @@ -1,6 +1,3 @@ -# tableau.py -EPS = 1e-9 - class Tableau: def __init__(self, A, b, c): """ @@ -53,7 +50,6 @@ def build_tableau(self, slack_indices, artificial_indices=None, M=1000000, slack num_cols = n + num_slack + num_artificial + 1 self.tableau = [[0.0] * num_cols for _ in range(m + 1)] - # coluna b for i in range(m): for j in range(n): self.tableau[i][j] = float(self.A[i][j]) @@ -108,8 +104,5 @@ def format_tableau(self, iteration=0): lines.append(obj) return "\n".join(lines) + "\n" - # ========================================================== - # Impressão do tableau - # ========================================================== def print_tableau(self, iteration=0): print(self.format_tableau(iteration), end="") \ No newline at end of file