diff --git a/resources/MatlabInterface/@JEInterface/JEInterface.m b/resources/MatlabInterface/@JEInterface/JEInterface.m
index 4040928e..06076d81 100644
--- a/resources/MatlabInterface/@JEInterface/JEInterface.m
+++ b/resources/MatlabInterface/@JEInterface/JEInterface.m
@@ -1,41 +1,46 @@
-function int = JEInterface(interfaceName, fhandle, range, varargin)
+function int = JEInterface(fhandle, range, varargin)
% EvA2 Interface for Matlab
-% JEInterface(interfaceName, fhandle, range [, optset, defaultargs])
+% JEInterface(interfaceName, fhandle, range)
+% JEInterface(interfaceName, fhandle, range, defaultargs)
+% JEInterface(interfaceName, fhandle, range, defaultargs, options...)
+
+
% arguments:
-% interfaceName: a JEInterface instance needs to know its own
-% name as a String to allow callbacks from Java.
% fhandle: a function handle defining the optimization target.
% range: a 2 x dim array defining the solution subspace with lower and
-% upper bounds - or a scalar defining the bitwidth for binary problems.
-% optset: (optional) an optimset struct defining optimization parameters,
-% especially tolerance and maximum function calls. Defaults to the
-% EvA2 default values.
+% upper bounds - or a scalar defining the bitwidth for binary
+% problems.
% defaultArgs: (optional) additional constant argument to the target
% function, empty by default.
-% Recognized options are:
+% options: (optional) options as name-value pairs defining optimization parameters,
+% especially tolerance and maximum function calls.
+% Check makeOoptions for default settings.
+
+% Further options may be specified using setOptions with a JE options struct.
+% Main options are:
% TolX: convergence criterion in the solution space
% TolFun: convergence criterion in the target space
% MaxFunEvals: maximum number of function evaluations
% Display: 'off'/'final'/'notify'/'iter', where 'notify' corresponds to
-% displaying every k-th iteration, which k=10 as default.
+% displaying every k-th iteration, with k=10 as default.
% The termination criterion of a run is a combination of the TolX, TolFun and
% MaxFunEvals criteria. The run terminates if MaxFunEvals has been reached
% or the best solution changes both in domain and codomain less than TolX
-% and TolFun for a certain time, e.g. 100 evaluations.
+% and TolFun for a certain number of evaluations, which may be set using
+% TolXEvals and TolFunEvals, respectively.
% To ignore a criterion, set it to 0. E.g. to perform 10^5 evaluations in
% any case, set TolX=TolFun=0 and MaxFunEvals=10^5.
%
-% You may define a 2xdim range with a double valued function handle or for
+% Define a 2 x dim range with a double valued function, or for
% binary problems set a scalar as range defining the number of bits to be
% used. The values passed to the function handle will then be arrays of
% uint32, each of them representing 32 bits.
int.args = [];
-int.opts = optimset('MaxFunEvals', eva2.OptimizerFactory.getDefaultFitCalls, 'TolX', 1e-4, 'TolFun', 1e-4);
+int.opts = [];
int.finished = 1;
int.result = [];
int.resultArr = [];
-int.callback='';
int.f = '';
int.dim = 0;
int.range = [];
@@ -47,50 +52,51 @@ int.optParams = [];
int.optParamValues = [];
int.hexMask=hex2dec('ffffffff');
-if (isa(interfaceName, 'char'));
- int.callback = interfaceName;
-else
- error('Wrong first argument type, expected char');
-end
if (isa(fhandle, 'function_handle'))
int.f = fhandle;
else
error('Wrong second argument type, expected function_handle');
end
+disp('Setting up JEInterface...');
if (isa(range, 'double') && (size(range,1) == 2))
- int.dim=size(range, 2);
+ int.dim=size(range,2);
int.range=transpose(range);
+ s = sprintf('Double valued search space, dimension: %d', int.dim);
+ disp(s);
else
- %error('Wrong third argument type, expected double array of 2 x dim');
- if (size(range,1)==size(range,2)==1)
+ if (length(range)==1)
int.range=[];
int.dim=range;
+ s = sprintf('Binary valued search space, dimension: %d', int.dim);
+ disp(s);
+ else
+ error('Wrong third argument type, expected double array of 2 x dim (double ranges) or scalar (binary bit width).');
end
end
int = class(int,'JEInterface');
+int.opts = makeOptions(int);
-switch nargin
- case {3}
- case {4,5}
- if (isa(varargin{1}, 'struct'))
- int.opts = varargin{1};
- % DONT set default values if user leaves them blank
-% if (isempty(int.opts.TolX)) ; int.opts.TolX = 1e-4; end
-% if (isempty(int.opts.TolFun)) ; int.opts.TolFun = 1e-4; end
- else
- error('Wrong fifth argument type, expected optimset struct');
+if (nargin>2)
+ int.args = varargin{1};
+ disp('Fitness function argument: '); disp(int.args);
+ if (nargin > 3)
+ if (rem(nargin,2)==0)
+ error('Invalid number of arguments!');
end
- if (nargin > 4)
- int.args = varargin{2};
+ disp('Reading options...');
+ for i=2:2:nargin-2
+ int=setOpt(int, varargin{i}, varargin{i+1});
end
- otherwise
- error('Wrong number of arguments!')
-end
+ end
+end
% finally create the java object
int.mp = eva2.server.go.problems.MatlabProblem(int.dim, int.range);
+disp('Java object created');
+
+testEvalFunc(int);
diff --git a/resources/MatlabInterface/@JEInterface/getOpt.m b/resources/MatlabInterface/@JEInterface/getOpt.m
index fc0b24ae..71bb5c01 100644
--- a/resources/MatlabInterface/@JEInterface/getOpt.m
+++ b/resources/MatlabInterface/@JEInterface/getOpt.m
@@ -5,4 +5,4 @@ function val = getOpt(int, optName)
% optName: name of the option to change, e.g. 'MaxFunEvals'
% optVal: new value
-val = optimget(int.opts, optName);
\ No newline at end of file
+val = int.opts.(optName);
\ No newline at end of file
diff --git a/resources/MatlabInterface/@JEInterface/makeOptions.m b/resources/MatlabInterface/@JEInterface/makeOptions.m
new file mode 100644
index 00000000..c0b7e65d
--- /dev/null
+++ b/resources/MatlabInterface/@JEInterface/makeOptions.m
@@ -0,0 +1,65 @@
+function opts = makeOptions(int, varargin)
+% Create a JEInterface options set from scratch. Possible fields are:
+%'Display';
+%'MaxFunEvals';'MaxIter';'TolFun';'TolFunEvals';TolX';'TolXEvals', where
+% all but 'TolFunEvals', 'TolXEvals' are used similar to the optimset.
+% The latter two are interpreted as the numbers of evaluations required
+% to assume convergence. Default values are TolXEvals=TolFunEvals=200,
+% TolX=TolFun=1e-4, MaxFunEvals uses a default from EvA2.
+% Notice that this method creates a parameter set but does not assign it
+% to the interface instance. Use setOptions to do that.
+
+allfields = {'Display'; 'MaxFunEvals';'MaxIter';'TolFun';'TolFunEvals';...
+ 'TolX';'TolXEvals'};
+
+specialfields={'TolFunEvals', 'TolXEvals'};
+
+nvararg=nargin-1;
+if rem(nvararg,2)==1
+ error('Pass options in name-value pairs!');
+end
+
+% create cell array
+structinput = cell(2,length(allfields));
+% fields go in first row
+structinput(1,:) = allfields';
+% []'s go in second row
+structinput(2,:) = {[]};
+% turn it into correctly ordered comma separated list and call struct
+opts = struct(structinput{:});
+
+stdSet=optimset();
+
+% standard options:
+opts.('MaxFunEvals') = eva2.OptimizerFactory.getDefaultFitCalls;
+opts.('TolX') = 1e-4;
+opts.('TolXEvals') = 200;
+opts.('TolFun') = 1e-4;
+opts.('TolFunEvals') = 200;
+
+for i=1:nvararg/2
+ name=varargin{2*i-1};
+ value=varargin{(2*i)};
+ % parse arguments
+ if ~ischar(name)
+ error('Expected char parameter name at index %d!', 2*i+1);
+ else
+ optIndex=strmatch(name,allfields, 'exact');
+ if isempty(optIndex)
+ error('Unknown option %s !', name);
+ else
+ if ~isempty(strmatch(name, specialfields,'exact'))
+ % test for integer
+ if (~isscalar(value) || ~isnumeric(value) || round(value)<1)
+ error('invalid value type for %s, expecting numeric scalar > 1!', name);
+ end
+ value=round(value);
+ else
+ % test using optimset
+ optimset(stdSet, name, value);
+ end
+ % assign to struct
+ opts.(allfields{optIndex,:}) = value;
+ end
+ end
+end
\ No newline at end of file
diff --git a/resources/MatlabInterface/@JEInterface/optimize.m b/resources/MatlabInterface/@JEInterface/optimize.m
index b07cbb12..eba8455a 100644
--- a/resources/MatlabInterface/@JEInterface/optimize.m
+++ b/resources/MatlabInterface/@JEInterface/optimize.m
@@ -43,15 +43,14 @@ if ((nargin == 2) || (nargin == 3))
if (isempty(int.opts.TolX)) ; xTol = 1e-4; end
if (isempty(int.opts.TolFun)) ; fTol = 1e-4; end
- evalsForConv=100;
% construct Terminators
if ((xTol > 0) && (fTol > 0))
% both criteria are given, use combination
- convTerm = CombinedTerminator(FitnessConvergenceTerminator(fTol, evalsForConv, 1, 1), PhenotypeConvergenceTerminator(xTol, evalsForConv, 1, 1), 1);
+ convTerm = CombinedTerminator(FitnessConvergenceTerminator(fTol, int.opts.TolFunEvals, 1, 1), PhenotypeConvergenceTerminator(xTol, int.opts.TolXEvals, 1, 1), 1);
else if (xTol > 0) % only phenotye convergence
- convTerm = PhenotypeConvergenceTerminator(xTol, evalsForConv, 1, 1);
+ convTerm = PhenotypeConvergenceTerminator(xTol, int.opts.TolXEvals, 1, 1);
else if (fTol > 0 ) % only fitness covnergence
- convTerm = FitnessConvergenceTerminator(fTol, evalsForConv, 1, 1);
+ convTerm = FitnessConvergenceTerminator(fTol, int.opts.TolFunEvals, 1, 1);
else
convTerm = 'undef'; % signal that there is no terminator yet
end
diff --git a/resources/MatlabInterface/@JEInterface/setOpt.m b/resources/MatlabInterface/@JEInterface/setOpt.m
index 7330cb0f..64a6d71c 100644
--- a/resources/MatlabInterface/@JEInterface/setOpt.m
+++ b/resources/MatlabInterface/@JEInterface/setOpt.m
@@ -1,9 +1,13 @@
function int = setOpt(int, optName, optVal)
-% Set a single optimset value within the JI instance.
+% Set a single option value within the JI instance.
% Arguments:
% int: the JEInterface instance
% optName: name of the option to change, e.g. 'MaxFunEvals'
% optVal: new value
-opts = optimset(int.opts, optName, optVal);
+% this only makes sure the option actally exists and is valid
+makeOptions(int, optName, optVal);
+
+opts = int.opts;
+opts.(optName) = optVal;
int.opts = opts;
\ No newline at end of file
diff --git a/resources/MatlabInterface/@JEInterface/setOptions.m b/resources/MatlabInterface/@JEInterface/setOptions.m
index 85e5bac5..c72c470e 100644
--- a/resources/MatlabInterface/@JEInterface/setOptions.m
+++ b/resources/MatlabInterface/@JEInterface/setOptions.m
@@ -1,7 +1,25 @@
-function int = setOptions(int, options)
-% Set the optimization options for the interface.
+function int = setOptions(int, usrOpts)
+% Set the optimization options for the interface. The existing options are
+% overwritten by the given setings.
% parameters:
% int: an interface instance
-% options: an optimset instance
+% usrOpts: a JE options structure
+
+fn=fieldnames(usrOpts);
+
+options = int.opts;
+
+try
+ for i=1:length(fn)
+ % make sure all option fields and values are valid
+ % fn(i)
+ % ischar(fn(i))
+ makeOptions(int, char(fn(i)), usrOpts.(char(fn(i))));
+ options.(char(fn(i))) = usrOpts.(char(fn(i)));
+ end
+catch ME
+ error('invalid option "%s"... check makeOptions to learn about available options', char(fn(i)));
+
+end
int.opts = options;
\ No newline at end of file
diff --git a/resources/MatlabInterface/@JEInterface/setVerbose.m b/resources/MatlabInterface/@JEInterface/setVerbose.m
new file mode 100644
index 00000000..0a87f233
--- /dev/null
+++ b/resources/MatlabInterface/@JEInterface/setVerbose.m
@@ -0,0 +1,24 @@
+function int=setVerbose(int, bOn, varargin)
+% Activate debug output for the MatlabProblem.
+% setVerbose(JI, bOn [, dbgfile])
+% It is written to a file with given name or to matlabproblem-debug.log
+% if none is given.
+% JI: the interface instance
+% bOn: 1 activates debug output, 0 deactivates it
+% dbgfile: optional filename
+%
+
+if (nargin > 2)
+ if ischar(varargin{1})
+ fname=varargin{1};
+ disp('Writing debug output to ');
+ disp(fname);
+ else
+ disp('Invalid third argument, expected char. Using default output file name');
+ end
+else
+ fname=null;
+end
+
+int.mp.setDebugOut( bOn==1, fname);
+
diff --git a/resources/MatlabInterface/@JEInterface/testEvalFunc.m b/resources/MatlabInterface/@JEInterface/testEvalFunc.m
new file mode 100644
index 00000000..e076bc45
--- /dev/null
+++ b/resources/MatlabInterface/@JEInterface/testEvalFunc.m
@@ -0,0 +1,56 @@
+function testEvalFunc(int)
+% Test the fitness function output format.
+wordwidth=32;
+
+if (isempty(int.range)==1)
+ % binary problem
+ s=sprintf('Binary problem of bitwidth %d', int.dim);
+ disp(s);
+ numInts=ceil(int.dim/wordwidth);
+ % generate trial vector
+ x=ceil(rand(1,numInts).*(2^wordwidth));
+ overheadBits=numInts*wordwidth-int.dim;
+ x(numInts)=bitshift(x(numInts),-overheadBits); % shift right by overhead
+else
+ % double problem
+ x=rand(1, int.dim);
+ s=sprintf('Real valued problem in %d dimensions and range %s ', int.dim, mat2str(int.range));
+ disp(s);
+ for i=1:int.dim
+ x(i)=int.range(i,1)+x(i)*(int.range(i,2)-int.range(i,1));
+ end
+end
+
+disp('Testing value: ')
+disp(x);
+
+try
+ if (isempty(int.args))
+ res = feval(int.f, x);
+ else
+ res = feval(int.f, x, int.args);
+ end
+catch ME
+ disp('Function evaluation failed:');
+ disp(ME.message);
+ error('Test failed!');
+end
+
+disp('Function returned: ');
+disp(res);
+
+if (min(size(res)) > 1)
+ disp('Warning: unable to optimize matrix representations - use 1 times m output only');
+else
+ if (size(res,1)>1)
+ disp('Warning: use dimensions 1 times m instead of m times 1');
+ else
+ if ~(sum(isnumeric(res))==size(res,1)*size(res,2))
+ disp('Warning: result seems to contain non-numeric elements!');
+ else
+ disp('Ok.');
+ end
+ end;
+end
+
+
\ No newline at end of file
diff --git a/src/eva2/EvAInfo.java b/src/eva2/EvAInfo.java
index e9c97282..22179143 100644
--- a/src/eva2/EvAInfo.java
+++ b/src/eva2/EvAInfo.java
@@ -4,6 +4,8 @@ package eva2;
* Main product and version information strings.
*
* --- Changelog
+ * 2.031: Some updates to the OptimizerFactory. Review of the MatlabInterface with adding an own options structure.
+ * Better access to the EvAClient, which now may have a RemoteStateListener added monitoring the optimization run.
* 2.030: Added an EnumEditor to access enums easily through the GUI, which will replace SelectedTags sometimes.
* IPOP-ES and RankMuCMA mutator have been added lately (wow!).
* Cleaned up the IndividualInterface and reduced the usage of InterfaceESIndividual. This
diff --git a/src/eva2/OptimizerFactory.java b/src/eva2/OptimizerFactory.java
index e59f8046..6d4cc4d1 100644
--- a/src/eva2/OptimizerFactory.java
+++ b/src/eva2/OptimizerFactory.java
@@ -35,7 +35,6 @@ import eva2.server.go.operators.selection.InterfaceSelection;
import eva2.server.go.operators.selection.SelectBestIndividuals;
import eva2.server.go.operators.terminators.CombinedTerminator;
import eva2.server.go.operators.terminators.EvaluationTerminator;
-import eva2.server.go.operators.terminators.FitnessConvergenceTerminator;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.AbstractOptimizationProblem;
import eva2.server.go.strategies.ClusterBasedNichingEA;
@@ -67,9 +66,8 @@ import eva2.server.modules.GOParameters;
* the methods initialize the respective optimization procedure. To perform an
* optimization one has to do the following:
* InterfaceOptimizer optimizer = OptimizerFactory.createCertainOptimizer(arguments);
- * EvaluationTerminator terminator = new EvaluationTerminator();
- * terminator.setFitnessCalls(numOfFitnessCalls);
- * while (!terminator.isTerminated(mc.getPopulation())) mc.optimize();
+ * EvaluationTerminator terminator = new EvaluationTerminator(numOfFitnessCalls);
+ * while (!terminator.isTerminated(optimizer.getPopulation())) optimizer.optimize();
*
*
*
@@ -80,7 +78,7 @@ import eva2.server.modules.GOParameters;
* @date 17.04.2007
*/
public class OptimizerFactory {
- private static InterfaceTerminator term = null;
+ private static InterfaceTerminator userTerm = null;
public final static int STD_ES = 1;
@@ -110,24 +108,6 @@ public class OptimizerFactory {
private static OptimizerRunnable lastRunnable = null;
- /**
- * Add an InterfaceTerminator to any new optimizer in a boolean combination.
- * The old and the given terminator will be combined as in (TOld && TNew) if
- * bAnd is true, and as in (TOld || TNew) if bAnd is false.
- *
- * @param newTerm
- * a new InterfaceTerminator instance
- * @param bAnd
- * indicate the boolean combination
- */
- public static void addTerminator(InterfaceTerminator newTerm, boolean bAnd) {
- if (OptimizerFactory.term == null)
- OptimizerFactory.term = term;
- else
- setTerminator(new CombinedTerminator(OptimizerFactory.term,
- newTerm, bAnd));
- }
-
/**
* This method optimizes the given problem using differential evolution.
*
@@ -501,10 +481,8 @@ public class OptimizerFactory {
}
// /////////////////////////// Termination criteria
- public static InterfaceTerminator defaultTerminator() {
- if (term == null)
- term = new EvaluationTerminator(defaultFitCalls);
- return term;
+ public static InterfaceTerminator makeDefaultTerminator() {
+ return new EvaluationTerminator(defaultFitCalls);
}
/**
@@ -582,21 +560,38 @@ public class OptimizerFactory {
public static OptimizerRunnable getOptRunnable(final int optType,
AbstractOptimizationProblem problem, int fitCalls,
String outputFilePrefix) {
+ return getOptRunnable(optType, problem, new EvaluationTerminator(fitCalls), outputFilePrefix);
+ }
+
+ /**
+ * Produce a runnable optimizer from a strategy identifier, a problem instance and with a given
+ * terminator. Output is written to a file if the prefix String is given. If the terminator is null
+ * the current user-defined terminator will be used and if none is set, the default number of fitness
+ * calls will be performed.
+ *
+ * @param optType
+ * @param problem
+ * @param terminator
+ * @param outputFilePrefix
+ * @return a runnable optimizer
+ */
+ public static OptimizerRunnable getOptRunnable(final int optType,
+ AbstractOptimizationProblem problem, InterfaceTerminator terminator,
+ String outputFilePrefix) {
OptimizerRunnable opt = null;
GOParameters params = getParams(optType, problem);
if (params != null) {
opt = new OptimizerRunnable(params, outputFilePrefix);
- if (fitCalls != defaultFitCalls)
- opt.getGOParams().setTerminator(
- new EvaluationTerminator(fitCalls));
+ if (terminator != null) opt.getGOParams().setTerminator(terminator);
+ else opt.getGOParams().setTerminator(getTerminator());
}
return opt;
}
-
+
// /////////////////////////// constructing a default OptimizerRunnable
/**
- * Produce a runnable optimizer from a strategy identifier, a problem instance and with the default
- * number of fitness calls to be performed. Output is written to a file if the prefix String is given.
+ * Produce a runnable optimizer from a strategy identifier, a problem instance and with the current
+ * static terminator in use. Output is written to a file if the prefix String is given.
* @see #getOptRunnable(int, AbstractOptimizationProblem, int, String)
* @param optType
* @param problem
@@ -605,17 +600,17 @@ public class OptimizerFactory {
*/
public static OptimizerRunnable getOptRunnable(final int optType,
AbstractOptimizationProblem problem, String outputFilePrefix) {
- return getOptRunnable(optType, problem, defaultFitCalls,
- outputFilePrefix);
+ return getOptRunnable(optType, problem, getTerminator(), outputFilePrefix);
}
/**
- * Return the current default terminator.
+ * Return the current user-defined or, if none was set, the default terminator.
*
* @return the current default terminator
*/
public static InterfaceTerminator getTerminator() {
- return OptimizerFactory.term;
+ if (OptimizerFactory.userTerm != null) return OptimizerFactory.userTerm;
+ else return makeDefaultTerminator();
}
/**
@@ -638,7 +633,7 @@ public class OptimizerFactory {
*/
public static GOParameters makeESParams(EvolutionStrategies es,
AbstractOptimizationProblem problem) {
- return makeParams(es, es.getLambda(), problem, randSeed, defaultTerminator());
+ return makeParams(es, es.getLambda(), problem, randSeed, makeDefaultTerminator());
}
/**
@@ -651,7 +646,7 @@ public class OptimizerFactory {
* @return
*/
public static GOParameters makeParams(InterfaceOptimizer opt, int popSize, AbstractOptimizationProblem problem) {
- return makeParams(opt, popSize, problem, randSeed, defaultTerminator());
+ return makeParams(opt, popSize, problem, randSeed, makeDefaultTerminator());
}
public static GOParameters makeParams(InterfaceOptimizer opt,
@@ -709,17 +704,39 @@ public class OptimizerFactory {
* @param optType
* @param problem
* @param outputFilePrefix
- * @return
+ * @return the OptimizerRunnable instance just started
*/
- public static OptimizerRunnable optimizeInThread(final int optType,
- AbstractOptimizationProblem problem, String outputFilePrefix) {
- OptimizerRunnable runnable = getOptRunnable(optType, problem,
- outputFilePrefix);
- if (runnable != null)
- new Thread(runnable).start();
- return runnable;
+ public static OptimizerRunnable optimizeInThread(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) {
+ return optimizeInThread(getOptRunnable(optType, problem, outputFilePrefix));
+ }
+
+ /**
+ * Create a runnable optimization Runnable and directly start it in an own
+ * thread. The Runnable will notify waiting threads and set the isFinished
+ * flag when the optimization is complete. If the optType is invalid, null
+ * will be returned.
+ *
+ * @param params
+ * @param outputFilePrefix
+ * @return the OptimizerRunnable instance just started
+ */
+ public static OptimizerRunnable optimizeInThread(GOParameters params, String outputFilePrefix) {
+ return optimizeInThread(new OptimizerRunnable(params, outputFilePrefix));
}
+ /**
+ * Start a runnable optimizer in a concurrent thread.
+ * @param runnable
+ * @return the started runnable
+ */
+ public static OptimizerRunnable optimizeInThread(OptimizerRunnable runnable) {
+ if (runnable != null) {
+ new Thread(runnable).start();
+ lastRunnable = runnable;
+ }
+ return runnable;
+ }
+
// ///////////////////////////// Optimize a given parameter instance
public static BitSet optimizeToBinary(GOParameters params,
String outputFilePrefix) {
@@ -810,12 +827,30 @@ public class OptimizerFactory {
return (lastRunnable == null) ? null : postProcess(lastRunnable, ppp);
}
+ /**
+ * Post process the given runnable with given parameters. The runnable will
+ * not be stored.
+ *
+ * @param runnable
+ * @param steps
+ * @param sigma
+ * @param nBest
+ * @return
+ */
public static Population postProcess(OptimizerRunnable runnable, int steps,
double sigma, int nBest) {
PostProcessParams ppp = new PostProcessParams(steps, sigma, nBest);
return postProcess(runnable, ppp);
}
+ /**
+ * Post process the given runnable with given parameters. The runnable will
+ * not be stored.
+ *
+ * @param runnable
+ * @param ppp
+ * @return
+ */
public static Population postProcess(OptimizerRunnable runnable,
InterfacePostProcessParams ppp) {
runnable.setDoRestart(true);
@@ -845,6 +880,14 @@ public class OptimizerFactory {
nBest));
}
+ /**
+ * Post process the given runnable with given parameters. Return the solution set
+ * as a vector of BitSets. The runnable will not be stored.
+ *
+ * @param runnable
+ * @param ppp
+ * @return
+ */
public static Vector postProcessBinVec(OptimizerRunnable runnable,
InterfacePostProcessParams ppp) {
Population resPop = postProcess(runnable, ppp);
@@ -875,7 +918,15 @@ public class OptimizerFactory {
return postProcessDblVec(runnable, new PostProcessParams(steps, sigma,
nBest));
}
-
+
+ /**
+ * Post process the given runnable with given parameters. Return the solution set
+ * as a vector of double arrays. The runnable will not be stored.
+ *
+ * @param runnable
+ * @param ppp
+ * @return
+ */
public static Vector postProcessDblVec(
OptimizerRunnable runnable, InterfacePostProcessParams ppp) {
Population resPop = postProcess(runnable, ppp);
@@ -906,7 +957,15 @@ public class OptimizerFactory {
return postProcessIndVec(runnable, new PostProcessParams(steps, sigma,
nBest));
}
-
+
+ /**
+ * Post process the given runnable with given parameters. Return the solution set
+ * as a vector of AbstractEAIndividuals. The runnable will not be stored.
+ *
+ * @param runnable
+ * @param ppp
+ * @return
+ */
public static Vector postProcessIndVec(
OptimizerRunnable runnable, InterfacePostProcessParams ppp) {
Population resPop = postProcess(runnable, ppp);
@@ -922,19 +981,48 @@ public class OptimizerFactory {
}
///////////////////////////// termination management
+ /**
+ * Replace the current user-defined terminator by the given one.
+ *
+ * @param term
+ */
+ public static void setTerminator(InterfaceTerminator term) {
+ OptimizerFactory.userTerm = term;
+ }
+
+ /**
+ * Add a new InterfaceTerminator to the current user-defined optimizer in a boolean combination.
+ * The old and the given terminator will be combined as in (TOld && TNew) if
+ * bAnd is true, and as in (TOld || TNew) if bAnd is false.
+ * If there was no user-defined terminator (or it was set to null) the new one is used without conjunction.
+ *
+ * @param newTerm
+ * a new InterfaceTerminator instance
+ * @param bAnd
+ * indicate the boolean combination
+ */
+ public static void addTerminator(InterfaceTerminator newTerm, boolean bAnd) {
+ if (OptimizerFactory.userTerm == null)
+ OptimizerFactory.userTerm = newTerm;
+ else
+ setTerminator(new CombinedTerminator(OptimizerFactory.userTerm,
+ newTerm, bAnd));
+ }
+
+ /**
+ * Convenience method setting an EvaluationTerminator with the given
+ * number of evaluations.
+ *
+ * @param maxEvals
+ */
public static void setEvaluationTerminator(int maxEvals) {
setTerminator(new EvaluationTerminator(maxEvals));
}
- public static void setFitnessConvergenceTerminator(double fitThresh) {
- setTerminator(new FitnessConvergenceTerminator(fitThresh, 100, true,
- true));
- }
-
- public static void setTerminator(InterfaceTerminator term) {
- OptimizerFactory.term = term;
- }
-
+ /**
+ * Return the termination message of the last runnable, if available.
+ * @return
+ */
public static String terminatedBecause() {
return (lastRunnable != null) ? lastRunnable.terminatedBecause() : null;
}
@@ -947,12 +1035,12 @@ public class OptimizerFactory {
*/
public static final GOParameters hillClimbing(
AbstractOptimizationProblem problem) {
- return makeParams(new HillClimbing(), 50, problem, randSeed, defaultTerminator());
+ return makeParams(new HillClimbing(), 50, problem, randSeed, makeDefaultTerminator());
}
public static final GOParameters monteCarlo(
AbstractOptimizationProblem problem) {
- return makeParams(new MonteCarloSearch(), 50, problem, randSeed, defaultTerminator());
+ return makeParams(new MonteCarloSearch(), 50, problem, randSeed, makeDefaultTerminator());
}
public static final GOParameters cbnES(AbstractOptimizationProblem problem) {
@@ -967,7 +1055,7 @@ public class OptimizerFactory {
cbn.setDifferentationCA(clustering);
cbn.setShowCycle(0); // don't do graphical output
- return makeParams(cbn, 100, problem, randSeed, defaultTerminator());
+ return makeParams(cbn, 100, problem, randSeed, makeDefaultTerminator());
}
public static final GOParameters clusteringHillClimbing(
@@ -982,7 +1070,7 @@ public class OptimizerFactory {
chc.setNotifyGuiEvery(0);
chc.setStepSizeThreshold(0.000001);
chc.setSigmaClust(0.05);
- return makeParams(chc, 100, problem, randSeed, defaultTerminator());
+ return makeParams(chc, 100, problem, randSeed, makeDefaultTerminator());
}
public static final GOParameters cmaES(AbstractOptimizationProblem problem) {
@@ -1052,7 +1140,7 @@ public class OptimizerFactory {
de.setK(0.6);
de.setLambda(0.6);
de.setMt(0.05);
- return makeParams(de, 50, problem, randSeed, defaultTerminator());
+ return makeParams(de, 50, problem, randSeed, makeDefaultTerminator());
}
public static final GOParameters standardES(
@@ -1082,7 +1170,7 @@ public class OptimizerFactory {
GeneticAlgorithm ga = new GeneticAlgorithm();
ga.setElitism(true);
- return makeParams(ga, 100, problem, randSeed, defaultTerminator());
+ return makeParams(ga, 100, problem, randSeed, makeDefaultTerminator());
}
public static final GOParameters standardPSO(
@@ -1090,10 +1178,10 @@ public class OptimizerFactory {
ParticleSwarmOptimization pso = new ParticleSwarmOptimization();
pso.setPhiValues(2.05, 2.05);
pso.getTopology().setSelectedTag("Grid");
- return makeParams(pso, 30, problem, randSeed, defaultTerminator());
+ return makeParams(pso, 30, problem, randSeed, makeDefaultTerminator());
}
public static final GOParameters tribes(AbstractOptimizationProblem problem) {
- return makeParams(new Tribes(), 1, problem, randSeed, defaultTerminator());
+ return makeParams(new Tribes(), 1, problem, randSeed, makeDefaultTerminator());
}
}
diff --git a/src/eva2/OptimizerRunnable.java b/src/eva2/OptimizerRunnable.java
index de308899..db285844 100644
--- a/src/eva2/OptimizerRunnable.java
+++ b/src/eva2/OptimizerRunnable.java
@@ -4,6 +4,8 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.BitSet;
+import wsi.ra.jproxy.RemoteStateListener;
+
import eva2.server.go.IndividualInterface;
import eva2.server.go.InterfaceGOParameters;
import eva2.server.go.InterfaceTerminator;
@@ -88,6 +90,10 @@ public class OptimizerRunnable implements Runnable {
this.listener = lsnr;
if (listener != null) proc.getStatistics().addTextListener(listener);
}
+
+ public void addRemoteStateListener(RemoteStateListener rsl) {
+ if (proc != null) proc.addListener(rsl);
+ }
public void setDoRestart(boolean restart) {
doRestart = restart;
diff --git a/src/eva2/server/go/problems/MatlabEvalMediator.java b/src/eva2/server/go/problems/MatlabEvalMediator.java
index 91e21947..5494150d 100644
--- a/src/eva2/server/go/problems/MatlabEvalMediator.java
+++ b/src/eva2/server/go/problems/MatlabEvalMediator.java
@@ -1,8 +1,5 @@
package eva2.server.go.problems;
-import java.lang.reflect.Array;
-import java.util.BitSet;
-
import eva2.gui.BeanInspector;
/**
@@ -34,7 +31,7 @@ public class MatlabEvalMediator implements Runnable {
boolean quit = false;
volatile Object optSolution = null;
volatile Object[] optSolSet = null;
-// MatlabProblem mp = null;
+ MatlabProblem mp = null;
// no good: even when waiting for only 1 ms the Matlab execution time increases by a factor of 5-10
final static int sleepTime = 0;
@@ -45,7 +42,7 @@ public class MatlabEvalMediator implements Runnable {
* @return
*/
double[] requestEval(MatlabProblem mp, Object x) {
-// this.mp = mp;
+ this.mp = mp;
question = x;
// System.err.println("IN REQUESTEVAL, x is " + BeanInspector.toString(x));
if (question.getClass().isArray()) {
@@ -54,11 +51,12 @@ public class MatlabEvalMediator implements Runnable {
// BitSet b = (BitSet)x;
// Integer.decode()
//
+ if (question == null) System.err.println("Error: requesting evaluation for null array!");
} else System.err.println("Error, requesting evaluation for non array!");
requesting = true;
// int k=0;
-// System.out.println("Requesting eval for " + BeanInspector.toString(x) + ", req state is " + requesting + "\n");
+ mp.log("-- Requesting eval for " + BeanInspector.toString(x) + ", req state is " + requesting + "\n");
while (requesting && !quit) {
// wait for matlab to answer the question
if (sleepTime > 0) try { Thread.sleep(sleepTime); } catch(Exception e) {};
@@ -67,8 +65,9 @@ public class MatlabEvalMediator implements Runnable {
// }
// k++;
}
-// System.out.println("Requesting done \n");
+ mp.log("-- Requesting done\n");
// matlab is finished, answer is here
+ //return null;
return getAnswer(); // return to JE with answer
}
@@ -102,11 +101,12 @@ public class MatlabEvalMediator implements Runnable {
* @return
*/
public Object getQuestion() {
-// mp.log("-- Question: " + BeanInspector.toString(question) + "\n");
+ mp.log("-- Question: " + BeanInspector.toString(question) + "\n");
return question;
}
double[] getAnswer() {
+ mp.log("-- mediator delivering " + BeanInspector.toString(answer) + "\n");
return answer;
}
@@ -116,10 +116,14 @@ public class MatlabEvalMediator implements Runnable {
* @param y
*/
public void setAnswer(double[] y) {
-// mp.log("-- setAnswer: " + BeanInspector.toString(y) + "\n");
// System.err.println("answer is " + BeanInspector.toString(y));
+ if (y==null) {
+ System.err.println("Error: Matlab function returned null array - this is bad.");
+ System.err.println("X-value was " + BeanInspector.toString(getQuestion()));
+ }
answer = y;
requesting = false; // answer is finished, break request loop
+ mp.log("-- setAnswer: " + BeanInspector.toString(y) + ", req state is " + requesting + "\n");
}
void setFinished(boolean val) {
diff --git a/src/eva2/server/go/problems/MatlabProblem.java b/src/eva2/server/go/problems/MatlabProblem.java
index 7329cb01..c4c52034 100644
--- a/src/eva2/server/go/problems/MatlabProblem.java
+++ b/src/eva2/server/go/problems/MatlabProblem.java
@@ -30,13 +30,13 @@ import eva2.server.stat.InterfaceTextListener;
*/
public class MatlabProblem extends AbstractOptimizationProblem implements InterfaceTextListener, Serializable {
private static final long serialVersionUID = 4913310869887420815L;
- public static final boolean TRACE = true;
+ public static boolean TRACE = false;
transient OptimizerRunnable runnable = null;
protected boolean allowSingleRunnable = true;
protected int problemDimension = 10;
transient PrintStream dos = null;
private double range[][] = null;
- private static final String defTestOut = "matlabproblem-testout.dat";
+ private static String defTestOut = "matlabproblem-debug.log";
int verbosityLevel = 0;
private MatlabEvalMediator handler = null;
private boolean isDouble = true;
@@ -123,18 +123,35 @@ public class MatlabProblem extends AbstractOptimizationProblem implements Interf
// System.err.println("range: " + BeanInspector.toString(range));
initTemplate();
// res = new ResultArr();
- if ((dos == null) && TRACE) {
- try {
- dos = new PrintStream(new FileOutputStream(outFile));
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
+
+ setDebugOut(TRACE, defTestOut);
// log("range is " + BeanInspector.toString(range)+ "\n");
// log("template len: " + ((ESIndividualDoubleData)m_Template).getDGenotype().length + "\n");
}
+ /**
+ * If swtch is true and no output file is open yet, open a new one which will be used for debug output.
+ * if fname is null, the default filename will be used.
+ * if swtch is false, close the output file and deactivate debug output.
+ *
+ * @param swtch
+ * @param fname
+ */
+ public void setDebugOut(boolean swtch, String fname) {
+ TRACE=swtch;
+ if (!swtch && (dos != null)) {
+ dos.close();
+ dos = null;
+ } else if ((dos == null) && swtch) {
+ try {
+ dos = new PrintStream(new FileOutputStream(fname==null ? defTestOut : fname));
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
public void setStatsOutput(int verboLevel) {
if ((verboLevel >= 0) && (verboLevel <= 3)) {
verbosityLevel = verboLevel;
@@ -386,10 +403,10 @@ public class MatlabProblem extends AbstractOptimizationProblem implements Interf
@Override
public void evaluate(AbstractEAIndividual indy) {
- log("evaluating " + BeanInspector.toString(indy) + "\n");
+ log("evaluating " + AbstractEAIndividual.getDefaultStringRepresentation(indy) + "\n");
double[] res = handler.requestEval(this, AbstractEAIndividual.getIndyData(indy));
+ log("evaluated to " + BeanInspector.toString(res) + "\n");
indy.SetFitness(res);
-// System.err.println("evaluated to " + BeanInspector.toString(res));
}
@Override
diff --git a/src/eva2/server/go/problems/WaitForEvARunnable.java b/src/eva2/server/go/problems/WaitForEvARunnable.java
index 311f774e..3acef52e 100644
--- a/src/eva2/server/go/problems/WaitForEvARunnable.java
+++ b/src/eva2/server/go/problems/WaitForEvARunnable.java
@@ -19,24 +19,23 @@ class WaitForEvARunnable implements Runnable {
public void run() {
if (runnable != null) {
mp.log("\nStarting optimize runnable!\n");
-
synchronized (runnable) {
try {
// whole optimization thread goes in here
new Thread(runnable).start();
- mp.log("Starting optimize thread done!\n");
+ mp.log("Started optimize thread\n");
runnable.wait();
// wait for the runnable to finish
- mp.log("After wait!\n");
+ mp.log("runnable continues...\n");
} catch (InterruptedException e) {
e.printStackTrace();
mp.log("WaitForEvARunnable was interrupted with " + e.getMessage());
}
}
try {
- mp.log("runnable.getDoubleSolution: " + BeanInspector.toString(runnable.getDoubleSolution()));
- mp.log("runnable.getIntegerSolution: " + BeanInspector.toString(runnable.getIntegerSolution()));
- mp.log("\ngetAllSols best: " + AbstractEAIndividual.getDefaultDataString(runnable.getGOParams().getOptimizer().getAllSolutions().getSolutions().getBestEAIndividual()));
+ mp.log("runnable.getDoubleSolution: " + BeanInspector.toString(runnable.getDoubleSolution()) + "\n");
+ mp.log("runnable.getIntegerSolution: " + BeanInspector.toString(runnable.getIntegerSolution()) + "\n");
+ mp.log("getAllSols best: " + AbstractEAIndividual.getDefaultDataString(runnable.getGOParams().getOptimizer().getAllSolutions().getSolutions().getBestEAIndividual()) + "\n");
mp.log("\n");
// write results back to matlab
mp.exportResultToMatlab(runnable);
diff --git a/src/eva2/server/go/strategies/ClusterBasedNichingEA.java b/src/eva2/server/go/strategies/ClusterBasedNichingEA.java
index c41cb8e6..c6c3c337 100644
--- a/src/eva2/server/go/strategies/ClusterBasedNichingEA.java
+++ b/src/eva2/server/go/strategies/ClusterBasedNichingEA.java
@@ -150,13 +150,13 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis
population.incrGeneration();
}
- private void plot() {
+ private void plot(int gen) {
double[] a = new double[2];
a[0] = 0.0;
a[1] = 0.0;
if (this.m_Problem instanceof TF1Problem) {
// now i need to plot the pareto fronts
- Plot plot = new Plot("TF3Problem", "y1", "y2", a, a);
+ Plot plot = new Plot("TF3Problem at gen. "+gen, "y1", "y2", a, a);
plot.setUnconnectedPoint(0,0,0);
plot.setUnconnectedPoint(1,5,0);
GraphPointSet mySet = new GraphPointSet(10, plot.getFunctionArea());
@@ -191,7 +191,7 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis
InterfaceDataTypeDouble tmpIndy1, best;
Population pop;
- this.m_Topology = new TopoPlot("CBN-Species","x","y",a,a);
+ this.m_Topology = new TopoPlot("CBN-Species at gen. " + gen,"x","y",a,a);
this.m_Topology.gridx = 60;
this.m_Topology.gridy = 60;
this.m_Topology.setTopology((Interface2DBorderProblem)this.m_Problem);
@@ -358,9 +358,9 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis
// plot the populations
if (this.m_ShowCycle > 0) {
if ((this.m_Undifferentiated.getGeneration() == 0) || (this.m_Undifferentiated.getGeneration() == 1) || (this.m_Undifferentiated.getGeneration() == 2)) {
- this.plot();
+ this.plot(this.m_Undifferentiated.getGeneration());
} else {
- if (this.m_Undifferentiated.getGeneration()%this.m_ShowCycle == 0) this.plot();
+ if (this.m_Undifferentiated.getGeneration()%this.m_ShowCycle == 0) this.plot(this.m_Undifferentiated.getGeneration());
}
}
@@ -706,7 +706,7 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis
* @return description
*/
public String globalInfo() {
- return "This is a versatible species based niching EA method.";
+ return "This is a versatile species based niching EA method.";
}
/** This method will return a naming String
* @return The name of the algorithm