Formulação Matemática da Função de Fitness 📐
No Algoritmo Genético do Monvix, o objetivo é minimizar uma função de perda quadrática ponderada com barreiras de penalidade estritas para violações de piso (Barrier Penalty Method).
🎯 Equação Geral da Função de Perda
A função de perda (Loss Function) de um indivíduo é calculada por:
A aptidão (Fitness) evolucionária é definida como o inverso negativo da perda:
Indivíduos com menor perda possuem maior aptidão e, portanto, maior probabilidade de serem selecionados no torneio de reprodução.
⚖️ Vetor de Pesos de Importância ()
O vetor de pesos determina a gravidade com que o algoritmo penaliza o desvio em relação ao alvo ideal :
| Balde () | Peso Base () | Peso com Gasto Declarado | Justificativa |
|---|---|---|---|
| Alimentação | 5.0 | 30.0 | Se o usuário declarou compras de supermercado, o algoritmo trata a meta com máxima rigidez. |
| Transporte | 2.5 | 20.0 | Alta rigidez quando custos de deslocamento são informados. |
| Saúde | 4.0 | 20.0 | Preservação de planos de saúde e medicamentos contínuos. |
| Quitação de Dívidas | 8.0 | 8.0 | Alta pressão para eliminar juros compostos negativos. |
| Reserva de Emergência | 3.5 | 3.5 | Proteção de liquidez conforme vínculo empregatício. |
| Apoio Familiar | 3.0 | 3.0 | Escalonado por dependentes residentes. |
| Investimentos & Futuro | 3.0 | 3.0 | Alavanca de longo prazo. |
| Lazer & Estilo de Vida | 1.5 | 1.5 | Balde de maior flexibilidade e absorção de choques orçamentários. |
🛡️ A Barreira de Penalidade de Piso ()
O termo:
onde é o piso mínimo admissível para o balde .
A constante atua como uma barreira multiplicativa extremamente íngreme. Se qualquer mutação estocástica gerar um indivíduo cuja alocação de alimentos ou saúde fique abaixo do piso mínimo , sua perda dispara em ordens de magnitude. No passo seguinte de seleção por torneio, esse indivíduo é sumariamente descartado da linhagem genética.
🔍 Implementação no Código-Fonte
O cálculo exato implementado em app/ga/optimizer.py aproveita operações vetorizadas do NumPy em C:
@staticmethod
def _evaluate_loss(
individual: np.ndarray,
targets: np.ndarray,
floors: np.ndarray,
weights: np.ndarray,
) -> float:
target_penalty = np.sum(weights * ((individual - targets) ** 2))
floor_violations = np.maximum(0.0, floors - individual)
return float(target_penalty + 1500.0 * np.sum(floor_violations**2))