You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

lsape_solver.py 3.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. Created on Mon Jun 22 15:37:36 2020
  5. @author: ljia
  6. """
  7. import numpy as np
  8. from scipy.optimize import linear_sum_assignment
  9. class LSAPESolver(object):
  10. def __init__(self, cost_matrix=None):
  11. """
  12. /*!
  13. * @brief Constructs solver for LSAPE problem instance.
  14. * @param[in] cost_matrix Pointer to the LSAPE problem instance that should be solved.
  15. */
  16. """
  17. self._cost_matrix = cost_matrix
  18. self._model = 'ECBP'
  19. self._greedy_method = 'BASIC'
  20. self._solve_optimally = True
  21. self._minimal_cost = 0
  22. self._row_to_col_assignments = []
  23. self._col_to_row_assignments = []
  24. self._dual_var_rows = [] # @todo
  25. self._dual_var_cols = [] # @todo
  26. def clear_solution(self):
  27. """Clears a previously computed solution.
  28. """
  29. self._minimal_cost = 0
  30. self._row_to_col_assignments.clear()
  31. self._col_to_row_assignments.clear()
  32. self._row_to_col_assignments.append([]) # @todo
  33. self._col_to_row_assignments.append([])
  34. self._dual_var_rows = [] # @todo
  35. self._dual_var_cols = [] # @todo
  36. def set_model(self, model):
  37. """
  38. /*!
  39. * @brief Makes the solver use a specific model for optimal solving.
  40. * @param[in] model The model that should be used.
  41. */
  42. """
  43. self._solve_optimally = True
  44. self._model = model
  45. def solve(self, num_solutions=1):
  46. """
  47. /*!
  48. * @brief Solves the LSAPE problem instance.
  49. * @param[in] num_solutions The maximal number of solutions that should be computed.
  50. */
  51. """
  52. self.clear_solution()
  53. if self._solve_optimally:
  54. row_ind, col_ind = linear_sum_assignment(self._cost_matrix) # @todo: only hungarianLSAPE ('ECBP') can be used.
  55. self._row_to_col_assignments[0] = col_ind
  56. self._col_to_row_assignments[0] = np.argsort(col_ind) # @todo: might be slow, can use row_ind
  57. self._compute_cost_from_assignments()
  58. if num_solutions > 1:
  59. pass # @todo:
  60. else:
  61. print('here is non op.')
  62. pass # @todo: greedy.
  63. # self._
  64. def minimal_cost(self):
  65. """
  66. /*!
  67. * @brief Returns the cost of the computed solutions.
  68. * @return Cost of computed solutions.
  69. */
  70. """
  71. return self._minimal_cost
  72. def get_assigned_col(self, row, solution_id=0):
  73. """
  74. /*!
  75. * @brief Returns the assigned column.
  76. * @param[in] row Row whose assigned column should be returned.
  77. * @param[in] solution_id ID of the solution where the assignment should be looked up.
  78. * @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.
  79. */
  80. """
  81. return self._row_to_col_assignments[solution_id][row]
  82. def get_assigned_row(self, col, solution_id=0):
  83. """
  84. /*!
  85. * @brief Returns the assigned row.
  86. * @param[in] col Column whose assigned row should be returned.
  87. * @param[in] solution_id ID of the solution where the assignment should be looked up.
  88. * @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.
  89. */
  90. """
  91. return self._col_to_row_assignments[solution_id][col]
  92. def num_solutions(self):
  93. """
  94. /*!
  95. * @brief Returns the number of solutions.
  96. * @returns Actual number of solutions computed by solve(). Might be smaller than @p num_solutions.
  97. */
  98. """
  99. return len(self._row_to_col_assignments)
  100. def _compute_cost_from_assignments(self): # @todo
  101. self._minimal_cost = np.sum(self._cost_matrix[range(0, len(self._row_to_col_assignments[0])), self._row_to_col_assignments[0]])

A Python package for graph kernels, graph edit distances and graph pre-image problem.