Source code for XLEMOO.utilities

from .LEMOO import LEMOO
from .ruleset_interpreter import extract_skoped_rules
from desdeo_problem.problem import MOProblem

import numpy as np

[docs]def parse_skoped_rules(lemoo: LEMOO, problem: MOProblem) -> dict: """Parses the rules from a trained LEMOO model that utilizes skoped rules in its learning mode and returns a dict with an entry for each variable describing its upper and lower bounds according to the extracted rules. Args: lemoo (LEMOO): A trained LEMOO model. problem (MOProblem): A multiobjective optimization problem. Returns: dict: A dict with each key representing a variable rules have been parsed for. Each entry is a dict with keys representing either the '>' or '<=' operator. The value behind the keys represented by these operators is the corresponding lower or upper bound of the variable, respectively. Example: ``{'x0': {'>': 2.5, <=': 5.2}}``. """ rules, accuracies = extract_skoped_rules(lemoo.current_ml_model) problem_lower_bounds = problem.get_variable_lower_bounds() problem_upper_bounds = problem.get_variable_upper_bounds() rules_for_vars = {f"X_{i}": {">": [problem_lower_bounds[i], -1], "<=": [problem_upper_bounds[i], -1]} for i in range(problem.n_of_variables)} for accuracy, rule in zip(accuracies, rules): for key in rule: var_name = key[0] op = key[1] # check accuracy if rules_for_vars[var_name][op][1] < accuracy: # update accuracy rules_for_vars[var_name][op][1] = accuracy if op == "<=": # tighten rule, if necessary if float(rule[(var_name, op)]) <= rules_for_vars[var_name][op][0]: rules_for_vars[var_name][op][0] = float(rule[(var_name, op)]) elif op == ">": # tighten rule, if necessary if float(rule[(var_name, op)]) > rules_for_vars[var_name][op][0]: rules_for_vars[var_name][op][0] = float(rule[(var_name, op)]) return rules_for_vars
[docs]def complete_missing_rules(lemoo: LEMOO, rules_for_vars: dict) -> dict: """Completes the missing rules contained in a dict. For the contents of the dict, see the function :func:`parse_skoped_rules`. The completing of the missing rules utilizes the final population generated by a trained LEMOO model by taking the lower and upper bounds of the population for each variables with missing bounds in the rules defined in `rules_for_vars`. Args: lemoo (LEMOO): A trained LEMOO model. rules_for_vars (dict): A dict with each key representing a variable. Each entry contains another dict representing a variable's upper and lower bounds. See :func:`parse_skoped_rules` for additional details. Returns: dict: A dictionary with completed missing rules. If a rule was completed utilizing the bounds in the population, its accuracy is set to -1. """ lower_bounds = np.min(lemoo._generation_history[-1].individuals, axis=0) upper_bounds = np.max(lemoo._generation_history[-1].individuals, axis=0) # if there are no upper or lower bound for some vars in the rules, use the min or max from the population for var_i, var_name in enumerate(rules_for_vars): for op in rules_for_vars[var_name]: if op == "<=": if rules_for_vars[var_name][op][1] == -1: # replace missing rule with bound from population rules_for_vars[var_name][op][0] = upper_bounds[var_i] if op == ">": if rules_for_vars[var_name][op][1] == -1: rules_for_vars[var_name][op][0] = lower_bounds[var_i] return rules_for_vars