diff --git a/data/DABConfigFileCristina b/data/DABConfigFileCristina new file mode 100755 index 0000000..8de700e --- /dev/null +++ b/data/DABConfigFileCristina @@ -0,0 +1,20 @@ +[Bees] +#Number of employed bees +nemployed: 2 +#Number of onlooker bees +nonlooker: 1 +#Modification factor used by the onlooker bees +onlookerModFactor: 0.0001 +#Number of iterations before a solution is abandoned +iterationsAbandoned: 5 +#probability for an employed to change a parameter (defined as 1/value) +probEmployedChange: 4 + +[Algorithm] +#Execution time +time: 50000 +#Size of the queue that stores the solutions that haven't been set yet +pendingSize: 50 +objective: min + +[General] diff --git a/data/param_cristina.xml b/data/param_cristina.xml new file mode 100755 index 0000000..3e70e66 --- /dev/null +++ b/data/param_cristina.xml @@ -0,0 +1,48 @@ + + + +0 +x0 +0 +int +1 +-100 +100 + + +1 +x1 +0 +int +1 +-100 +100 + + +2 +x2 +0 +int +1 +-100 +100 + + +3 +x3 +0 +int +1 +-100 +100 + + +4 +x4 +0 +int +1 +-100 +100 + + diff --git a/src/CristinaData.py b/src/CristinaData.py new file mode 100755 index 0000000..3daf64b --- /dev/null +++ b/src/CristinaData.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python +# vim: set fileencoding=utf-8 : + +############################################################################# +# Copyright 2013 by Antonio Gomez and Miguel Cardenas # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################# + +import os +import sys +from array import array +from xml.dom import minidom +import Utils as u +from Parameter import Parameter + +__author__ = ' AUTHORS: Antonio Gomez (antonio.gomez@csiro.au)' + +__version__ = ' REVISION: 1.0 - 15-01-2014' + +""" +HISTORY + Version 0.1 (12-04-2013): Creation of the file. + Version 1.0 (15-01-2014): Fist stable version. +""" + + +class CristinaData (object): + """ + This class stores all the data required by VMEC. + It also provides methods to read the input xml file that, for each + parameter, specifies the min/max/default values, the gap, the index,... + It can also create an XML output file with the data it contains + """ + def __init__(self): + self.__numParams = 0 + self.__maxRange = 0 + self.__fInput = None + self.__params = [] + return + + def __del__(self): + try: + del self.__params[:] + except: + pass + + #returns the number of parameters that can be actually modified + def getNumParams(self): + return self.__numParams + + """ + Returns a list of doubles with the values of the modificable parameters + """ + def getValsOfParameters(self): + buff = array('f', [0]) * self.__numParams + for i in range(self.__numParams): + buff[i] = float(self.__params[i].get_value()) + return buff + + """ + Receives as parameter (buff) a list of values corresponding to + the values that the parameters that can be modified must take. + Goes through all of the parameters and changes the values of the + modificable parameters to the value specified in this list + """ + + def setValsOfParameters(self, buff): + u.logger.debug("CristinaData. Setting parameters (number: " + + str(len(buff)) + ")") + for i in range(len(buff)): + self.__params[i].set_value(buff[i]) + + def setParameters(self, parameters): + for param in parameters: + self.assign_parameter(param) + """ + Return a list with all the parameters (list of Parameter objects) + """ + def getParameters(self): + return self.__params + + """ + Assign a parameter with a new value to an older version of the + same parameter + """ + def assign_parameter(self, parameter): + index = parameter.get_index() + if index >= len(self.__params): + self.__params.append(parameter) + + def getMaxRange(self): + return self.__maxRange + + """ + Method that reads the xml input file. Puts into memory all the data + contained in that file (min-max values, initial value, gap,...) + Argument: + - filepath: path to the XML input file + """ + + def initialize(self, filepath): + try: + if not os.path.exists(filepath): + filepath = "../" + filepath + xmldoc = minidom.parse(filepath) + pNode = xmldoc.childNodes[0] + for node in pNode.childNodes: + if node.nodeType == node.ELEMENT_NODE: + c = Parameter() + for node_param in node.childNodes: + if node_param.nodeType == node_param.ELEMENT_NODE: + if node_param.localName == "type": + c.set_type(node_param.firstChild.data) + if node_param.localName == "value": + c.set_value(node_param.firstChild.data) + if node_param.localName == "min_value": + c.set_min_value(node_param.firstChild.data) + if node_param.localName == "max_value": + c.set_max_value(node_param.firstChild.data) + if node_param.localName == "index": + c.set_index(node_param.firstChild.data) + if node_param.localName == "name": + c.set_name(node_param.firstChild.data) + if node_param.localName == "gap": + c.set_gap(node_param.firstChild.data) + try: + self.assign_parameter(c) + self.__numParams += 1 + values = 1 + int(round((c.get_max_value() - + c.get_min_value()) / c.get_gap())) + self.__maxRange = max(values, self.__maxRange) + except ValueError as e: + u.logger.warning("Problem calculating max range: " + + str(e) + " . Fileno: " + str(sys.exc_info()[2].tb_lineno)) + pass + u.logger.debug("Number of parameters " + + str(self.__numParams) + "(" + + str(len(self.__params)) + ")") + except Exception as e: + u.logger.error("CristinaData (" + + str(sys.exc_info()[2].tb_lineno) + + "). Problem reading input xml file: " + str(e)) + sys.exit(111) + return diff --git a/src/SolutionCristina.py b/src/SolutionCristina.py index 897d5e9..ceec0f7 100755 --- a/src/SolutionCristina.py +++ b/src/SolutionCristina.py @@ -30,13 +30,15 @@ from SolutionBase import SolutionBase import Utils as u +from CristinaData import CristinaData class SolutionCristina (SolutionBase): def __init__(self, infile): SolutionBase.__init__(self, infile) #TODO: Implemement how data is initialized - self.__data = None + self.__data = CristinaData() + self.__data.initialize(infile) return def initialize(self, data): @@ -57,3 +59,12 @@ def getParameters(self): def getParametersValues(self): return self.__data.getValsOfParameters() + + def setParametersValues(self, buff): + self.__data.setValsOfParameters(buff) + + def setParameters(self, params): + self.__data.setParameters(params) + + def getData(self): + return self.__data diff --git a/src/SolutionsQueue.py b/src/SolutionsQueue.py index a1b52c5..e42521b 100755 --- a/src/SolutionsQueue.py +++ b/src/SolutionsQueue.py @@ -120,12 +120,12 @@ def PutSolution(self, solution, value, agent_idx, sources=3): for i in range(len(self.__queue)): origins.add(self.__queue[i][2]) if util.objective == util.objectiveType.MAXIMIZE: - if (self.__queue[i][1] > value and - self.__queue[i][1] >= 0.0): + if (float(self.__queue[i][1]) > value and + float(self.__queue[i][1]) >= 0.0): continue if util.objective == util.objectiveType.MINIMIZE: - if (self.__queue[i][1] < value and - self.__queue[i][1] >= 0.0): + if (float(self.__queue[i][1]) < value and + float(self.__queue[i][1]) >= 0.0): continue if (i > self.__maxSize / 10 and len(origins) <= 1 and agent_idx in origins): @@ -169,7 +169,7 @@ def LoadQueue(self): value = float(sol_tuple[1]) inserted = False for i in range(len(self.__queue)): - if self.__queue[i][1] < value: + if float(self.__queue[i][1]) < value: continue self.__queue.insert(i - 1, sol_tuple) inserted = True @@ -338,7 +338,7 @@ def GetTupleOnPriorityByValue(self, value): total_val = self.GetTotalSolutionsValues() for i in range(self.qSize()): if util.objective == util.objectiveType.MINIMIZE: - temp_sum += float(1.0 / self.__queue[i][1]) + temp_sum += float(1.0 / float(self.__queue[i][1])) else: temp_sum += float(self.__queue[i][1]) util.logger.debug("TempSum: " + str(temp_sum) + "/" + diff --git a/src/SolverDAB.py b/src/SolverDAB.py index fabecd0..66aabf3 100644 --- a/src/SolverDAB.py +++ b/src/SolverDAB.py @@ -825,6 +825,8 @@ def receiveSolutions(self): solutionTemp = SolutionFusion(self.__infile) elif self.__problem_type == u.problem_type.NONSEPARABLE: solutionTemp = SolutionNonSeparable(self.__infile) + elif self.__problem_type == u.problem_type.CRISTINA: + solutionTemp = SolutionCristina(self.__infile) if solutionTemp is None: u.logger.error("Solution is None after creation (type " + str(self.__problem_type) + ")")