| @@ -0,0 +1,122 @@ | |||
| #!/usr/bin/env python3 | |||
| # -*- coding: utf-8 -*- | |||
| """ | |||
| Created on Mon Jun 22 15:37:36 2020 | |||
| @author: ljia | |||
| """ | |||
| import numpy as np | |||
| from scipy.optimize import linear_sum_assignment | |||
| class LSAPESolver(object): | |||
| def __init__(self, cost_matrix=None): | |||
| """ | |||
| /*! | |||
| * @brief Constructs solver for LSAPE problem instance. | |||
| * @param[in] cost_matrix Pointer to the LSAPE problem instance that should be solved. | |||
| */ | |||
| """ | |||
| self.__cost_matrix = cost_matrix | |||
| self.__model = 'ECBP' | |||
| self.__greedy_method = 'BASIC' | |||
| self.__solve_optimally = True | |||
| self.__minimal_cost = 0 | |||
| self.__row_to_col_assignments = [] | |||
| self.__col_to_row_assignments = [] | |||
| self.__dual_var_rows = [] # @todo | |||
| self.__dual_var_cols = [] # @todo | |||
| def clear_solution(self): | |||
| """Clears a previously computed solution. | |||
| """ | |||
| self.__minimal_cost = 0 | |||
| self.__row_to_col_assignments.clear() | |||
| self.__col_to_row_assignments.clear() | |||
| self.__row_to_col_assignments.append([]) # @todo | |||
| self.__col_to_row_assignments.append([]) | |||
| self.__dual_var_rows = [] # @todo | |||
| self.__dual_var_cols = [] # @todo | |||
| def set_model(self, model): | |||
| """ | |||
| /*! | |||
| * @brief Makes the solver use a specific model for optimal solving. | |||
| * @param[in] model The model that should be used. | |||
| */ | |||
| """ | |||
| self.__solve_optimally = True | |||
| self.__model = model | |||
| def solve(self, num_solutions=1): | |||
| """ | |||
| /*! | |||
| * @brief Solves the LSAPE problem instance. | |||
| * @param[in] num_solutions The maximal number of solutions that should be computed. | |||
| */ | |||
| """ | |||
| self.clear_solution() | |||
| if self.__solve_optimally: | |||
| row_ind, col_ind = linear_sum_assignment(self.__cost_matrix) # @todo: only hungarianLSAPE ('ECBP') can be used. | |||
| self.__row_to_col_assignments[0] = col_ind | |||
| self.__col_to_row_assignments[0] = np.argsort(col_ind) # @todo: might be slow, can use row_ind | |||
| self.__compute_cost_from_assignments() | |||
| if num_solutions > 1: | |||
| pass # @todo: | |||
| else: | |||
| print('here is non op.') | |||
| pass # @todo: greedy. | |||
| # self.__ | |||
| def minimal_cost(self): | |||
| """ | |||
| /*! | |||
| * @brief Returns the cost of the computed solutions. | |||
| * @return Cost of computed solutions. | |||
| */ | |||
| """ | |||
| return self.__minimal_cost | |||
| def get_assigned_col(self, row, solution_id=0): | |||
| """ | |||
| /*! | |||
| * @brief Returns the assigned column. | |||
| * @param[in] row Row whose assigned column should be returned. | |||
| * @param[in] solution_id ID of the solution where the assignment should be looked up. | |||
| * @returns Column to which @p row is assigned to in solution with ID @p solution_id or ged::undefined() if @p row is not assigned to any column. | |||
| */ | |||
| """ | |||
| return self.__row_to_col_assignments[solution_id][row] | |||
| def get_assigned_row(self, col, solution_id=0): | |||
| """ | |||
| /*! | |||
| * @brief Returns the assigned row. | |||
| * @param[in] col Column whose assigned row should be returned. | |||
| * @param[in] solution_id ID of the solution where the assignment should be looked up. | |||
| * @returns Row to which @p col is assigned to in solution with ID @p solution_id or ged::undefined() if @p col is not assigned to any row. | |||
| */ | |||
| """ | |||
| return self.__col_to_row_assignments[solution_id][col] | |||
| def num_solutions(self): | |||
| """ | |||
| /*! | |||
| * @brief Returns the number of solutions. | |||
| * @returns Actual number of solutions computed by solve(). Might be smaller than @p num_solutions. | |||
| */ | |||
| """ | |||
| return len(self.__row_to_col_assignments) | |||
| def __compute_cost_from_assignments(self): # @todo | |||
| self.__minimal_cost = np.sum(self.__cost_matrix[range(0, len(self.__row_to_col_assignments[0])), self.__row_to_col_assignments[0]]) | |||