mono.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. """Mono-objective evaluators classes
  2. """
  3. # main imports
  4. from macop.evaluators.base import Evaluator
  5. class KnapsackEvaluator(Evaluator):
  6. """Knapsack evaluator class which enables to compute knapsack solution using specific `_data`
  7. - stores into its `_data` dictionary attritute required measures when computing a knapsack solution
  8. - `_data['worths']` stores knapsack objects worths information
  9. - `compute` method enables to compute and associate a score to a given knapsack solution
  10. Example:
  11. >>> import random
  12. >>>
  13. >>> # binary solution import
  14. >>> from macop.solutions.discrete import BinarySolution
  15. >>>
  16. >>> # evaluator import
  17. >>> from macop.evaluators.discrete.mono import KnapsackEvaluator
  18. >>> solution_data = [1, 0, 0, 1, 1, 0, 1, 0]
  19. >>> size = len(solution_data)
  20. >>> solution = BinarySolution(solution_data, size)
  21. >>>
  22. >>> # evaluator initialization (worths objects passed into data)
  23. >>> worths = [ random.randint(5, 20) for i in range(size) ]
  24. >>> evaluator = KnapsackEvaluator(data={'worths': worths})
  25. >>>
  26. >>> # compute solution score
  27. >>> evaluator.compute(solution)
  28. 40
  29. """
  30. def compute(self, solution):
  31. """Apply the computation of fitness from solution
  32. Args:
  33. solution: {:class:`~macop.solutions.base.Solution`} -- Solution instance
  34. Returns:
  35. {float}: fitness score of solution
  36. """
  37. fitness = 0
  38. for index, elem in enumerate(solution.data):
  39. fitness += self._data['worths'][index] * elem
  40. return fitness
  41. class QAPEvaluator(Evaluator):
  42. """Quadratic Assignment Problem (QAP) evaluator class which enables to compute qap solution using specific `_data`
  43. Solutions use for this evaluator are with type of `macop.solutions.discrete.CombinatoryIntegerSolution`
  44. - stores into its `_data` dictionary attritute required measures when computing a QAP solution
  45. - `_data['F']` matrix of size n x n with flows data between facilities (stored as numpy array)
  46. - `_data['D']` matrix of size n x n with distances data between locations (stored as numpy array)
  47. - `compute` method enables to compute and associate a score to a given QAP solution
  48. Example:
  49. >>> import random
  50. >>> import numpy as np
  51. >>>
  52. >>> # combinatory solution import
  53. >>> from macop.solutions.discrete import CombinatoryIntegerSolution
  54. >>>
  55. >>> # evaluator import
  56. >>> from macop.evaluators.discrete.mono import QAPEvaluator
  57. >>>
  58. >>> # define problem data using QAP example instance
  59. >>> qap_instance_file = 'examples/instances/qap/qap_instance.txt'
  60. >>> n = 100 # problem size
  61. >>>
  62. >>> # loading data
  63. >>> f = open(qap_instance_file, 'r')
  64. >>> file_data = f.readlines()
  65. >>> D_lines = file_data[1:n + 1]
  66. >>> D_data = ''.join(D_lines).replace('\\n', '')
  67. >>> F_lines = file_data[n:2 * n + 1]
  68. >>> F_data = ''.join(F_lines).replace('\\n', '')
  69. >>> D_matrix = np.fromstring(D_data, dtype=float, sep=' ').reshape(n, n)
  70. >>> F_matrix = np.fromstring(F_data, dtype=float, sep=' ').reshape(n, n)
  71. >>> f.close()
  72. >>>
  73. >>> # create evaluator instance using loading data
  74. >>> evaluator = QAPEvaluator(data={'F': F_matrix, 'D': D_matrix})
  75. >>>
  76. >>> # create new random combinatory solution using n, the instance QAP size
  77. >>> solution = CombinatoryIntegerSolution.random(n)
  78. >>>
  79. >>> # compute solution score
  80. >>> evaluator.compute(solution)
  81. 6397983.0
  82. """
  83. def compute(self, solution):
  84. """Apply the computation of fitness from solution
  85. Args:
  86. solution: {:class:`~macop.solutions.base.Solution`} -- QAP solution instance
  87. Returns:
  88. {float}: fitness score of solution
  89. """
  90. fitness = 0
  91. for index_i, val_i in enumerate(solution.data):
  92. for index_j, val_j in enumerate(solution.data):
  93. fitness += self._data['F'][index_i,
  94. index_j] * self._data['D'][val_i,
  95. val_j]
  96. return fitness
  97. class UBQPEvaluator(Evaluator):
  98. """Unconstrained Binary Quadratic Programming (UBQP) evaluator class which enables to compute UBQP solution using specific `_data`
  99. - stores into its `_data` dictionary attritute required measures when computing a UBQP solution
  100. - `_data['Q']` matrix of size n x n with real values data (stored as numpy array)
  101. - `compute` method enables to compute and associate a score to a given UBQP solution
  102. Example:
  103. >>> import random
  104. >>> import numpy as np
  105. >>>
  106. >>> # binary solution import
  107. >>> from macop.solutions.discrete import BinarySolution
  108. >>>
  109. >>> # evaluator import
  110. >>> from macop.evaluators.discrete.mono import UBQPEvaluator
  111. >>>
  112. >>> # define problem data using UBQP example instance
  113. >>> ubqp_instance_file = 'examples/instances/ubqp/ubqp_instance.txt'
  114. >>> n = 100 # problem size
  115. >>>
  116. >>> # loading data
  117. >>> f = open(ubqp_instance_file, 'r')
  118. >>> file_data = f.readlines()
  119. >>>
  120. >>> # get all string floating point values of matrix
  121. >>> Q_data = ''.join([ line.replace('\\n', '') for line in file_data[8:] ])
  122. >>> # load the concatenate obtained string
  123. >>> Q_matrix = np.fromstring(Q_data, dtype=float, sep=' ').reshape(n, n)
  124. >>> f.close()
  125. >>>
  126. >>> # create evaluator instance using loading data
  127. >>> evaluator = UBQPEvaluator(data={'Q': Q_matrix})
  128. >>>
  129. >>> # create new random combinatory solution using n, the instance QAP size
  130. >>> solution = BinarySolution.random(n)
  131. >>>
  132. >>> # compute solution score
  133. >>> evaluator.compute(solution)
  134. 477.0
  135. """
  136. def compute(self, solution):
  137. """Apply the computation of fitness from solution
  138. Args:
  139. solution: {:class:`~macop.solutions.base.Solution`} -- UBQP solution instance
  140. Returns:
  141. {float}: fitness score of solution
  142. """
  143. fitness = 0
  144. for index_i, val_i in enumerate(solution.data):
  145. for index_j, val_j in enumerate(solution.data):
  146. fitness += self._data['Q'][index_i, index_j] * val_i * val_j
  147. return fitness