File size: 6,782 Bytes
2fc2c1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#!/Users/pranab/Tools/anaconda/bin/python

# Package imports
import os
import sys
import numpy as np
import sklearn as sk
import random
import jprops
import abc 
import math
import random
sys.path.append(os.path.abspath("../lib"))
from util import *

#base parameter search
class BaseParameterSearch(object):
	__metaclass__ = abc.ABCMeta
	 
	def __init__(self, verbose):
		self.verbose = verbose
		self.parameters = []
		self.paramData = {}	
		self.currentParams = []
		self.curIter = 0
		self.bestSolution = None
	
	# add param name and type
	def addParam(self, param):
		self.parameters.append(param)
	
	# add param data	
	def addParamVaues(self, paramName, paramData):
		self.paramData[paramName] = paramData
	
	# max iterations	
	def setMaxIter(self, maxIter):
		self.maxIter = maxIter
	
	@abc.abstractmethod
	def prepare(self):
		pass

	@abc.abstractmethod
	def nextParamValues(self):
		pass

	@abc.abstractmethod
	def setCost(self, cost):
		pass

	# get best solution
	def getBestSolution(self):
		return self.bestSolution
		
#enumerate through provided list of param values
class GuidedParameterSearch:
	def __init__(self, verbose=False):
		self.verbose = verbose
		self.parameters = []
		self.paramData = {}	
		self.paramIndexes = []
		self.numParamValues = []
		self.currentParams = []
		self.bestSolution = None
	
	# max iterations	
	def setMaxIter(self,maxIter):
		self.maxIter = maxIter
		
	# add param name and type
	def addParam(self, param):
		self.parameters.append(param)
	
	# add param data	
	def addParamVaues(self, paramName, paramData):
		self.paramData[paramName] = paramData
	
	# prepare
	def prepare(self):
		self.numParams = len(self.parameters)
		for i in range(self.numParams):
			self.paramIndexes.append(0)
			
			#number of values for each parameter
			paramName = self.parameters[i][0]
			self.numParamValues.append(len(self.paramData[paramName]))
		self.curParamIndex = 0
		
		paramValueCombList = []
		paramValueComb = []
		paramValueCombList.append(paramValueComb)
		
		# all params
		for i in range(self.numParams):
			paramValueCombListTemp = []
			for paramValueComb in paramValueCombList:
				# all param values
				for j in range(self.numParamValues[i]):
					paramValueCombTemp = paramValueComb[:]
					paramValueCombTemp.append(j)
					paramValueCombListTemp.append(paramValueCombTemp)
			paramValueCombList = paramValueCombListTemp
		self.paramValueCombList = paramValueCombList
		self.numParamValueComb = len(self.paramValueCombList)
		self.curParamValueCombIndx = 0;
		
	# next param combination
	def nextParamValues(self):
		retParamNameValue = None
		if self.curParamValueCombIndx < len(self.paramValueCombList):
			retParamNameValue = []
			curParams = self.paramValueCombList[self.curParamValueCombIndx]
			print (curParams)
			for i in range(len(curParams)):
				paramName = self.parameters[i][0]
				paramValue = self.paramData[paramName][curParams[i]]
				retParamNameValue.append((paramName, paramValue))
			self.curParamValueCombIndx = self.curParamValueCombIndx + 1
			self.currentParams = retParamNameValue
		return 	retParamNameValue
			
	# set cost of current parameter set
	def setCost(self, cost):
		if self.bestSolution is not None:
			if cost < self.bestSolution[1]:
				self.bestSolution = (self.currentParams, cost)
		else:
			self.bestSolution = (self.currentParams, cost)
			
	# get best solution
	def getBestSolution(self):
		return 	self.bestSolution
		
#random search through provided list of parameter values
class RandomParameterSearch(BaseParameterSearch):
	def __init__(self, verbose=False):
		super(RandomParameterSearch, self).__init__(verbose)
		

	# prepare
	def prepare(self):
		pass

	# next param combination
	def nextParamValues(self):
		retParamNameValue = None
		if (self.curIter < self.maxIter):
			retParamNameValue = []
			for pName, pValues in self.paramData.iteritems():
				pValue = selectRandomFromList(pValues)
				retParamNameValue.append((pName, pValue))
			self.curIter = self.curIter + 1
			self.currentParams = retParamNameValue
		return retParamNameValue
				
	# set cost of current parameter set
	def setCost(self, cost):
		if self.bestSolution is not None:
			if cost < self.bestSolution[1]:
				self.bestSolution = (self.currentParams, cost)
		else:
			self.bestSolution = (self.currentParams, cost)
			
#random search through provided list of parameter values
class SimulatedAnnealingParameterSearch(BaseParameterSearch):
	def __init__(self, verbose=False):
		self.curSolution = None
		self.nextSolution = None
		super(SimulatedAnnealingParameterSearch, self).__init__(verbose)

	# prepare
	def prepare(self):
		pass
		
	def setTemp(self, temp):
		self.temp = temp	
		
	def setTempReductionRate(self, tempRedRate):
		self.tempRedRate = tempRedRate	

	# next param combination
	def nextParamValues(self):
		retParamNameValue = None
		if (self.curIter == 0):
			#initial random solution
			retParamNameValue = []
			for pName, pValues in self.paramData.iteritems():
				pValue = selectRandomFromList(pValues)
				retParamNameValue.append((pName, pValue))
			self.curIter = self.curIter + 1
			self.currentParams = retParamNameValue
		elif (self.curIter < self.maxIter):
			#perturb current solution
			retParamNameValue = []
			
			#randomly mutate one parameter value
			(pNameSel, pValue) = selectRandomFromList(self.currentParams)
			pValueNext = selectRandomFromList(self.paramData[pNameSel])
			while (pValueNext == pValue):
				pValueNext = selectRandomFromList(self.paramData[pNameSel])
			
			#copy	
			for (pName, pValue) in self.currentParams:
				if (pName == pNameSel):
					pValueNew = pValueNext
				else:
					pValueNew = pValue
				retParamNameValue.append((pName, pValueNew))
			self.curIter = self.curIter + 1
			self.currentParams = retParamNameValue
		return retParamNameValue		
				
	# set cost of current parameter set
	def setCost(self, cost):
		if self.curSolution is None:
			self.curSolution = (self.currentParams, cost)
			self.bestSolution = (self.currentParams, cost)
		else:
			self.nextSolution = (self.currentParams, cost)
			if (self.nextSolution[1] < self.curSolution[1]):
				if (self.verbose):
					print ("next soln better")
				self.curSolution = self.nextSolution
				if (self.nextSolution[1] < self.bestSolution[1]):
					if (self.verbose):
						print ("next soln better than best")
					self.bestSolution = self.nextSolution
			else:
				if (self.verbose):
					print ("next soln worst")
				pr = math.exp((self.curSolution[1] - self.nextSolution[1]) / self.temp)
				if (pr > random.random()):
					self.curSolution = self.nextSolution
					if (self.verbose):
						print ("next soln worst but accepted")
				else:
					if (self.verbose):
						print ("next soln worst and rejected")
				
			self.temp = self.temp * self.tempRedRate