Adding explicit data types to the Matlab interface. Now integer problems can be tackled, too.
This commit is contained in:
parent
628499aab9
commit
e0e78a1ad3
@ -1,12 +1,14 @@
|
||||
function int = JEInterface(fhandle, range, varargin)
|
||||
function int = JEInterface(fhandle, datatype, range, varargin)
|
||||
% EvA2 Interface for Matlab
|
||||
% JEInterface(fhandle, range)
|
||||
% JEInterface(fhandle, range, initRange)
|
||||
% JEInterface(fhandle, range, initRange, defaultargs)
|
||||
% JEInterface(fhandle, range, initRange, defaultargs, options...)
|
||||
% JEInterface(fhandle, datatype, range)
|
||||
% JEInterface(fhandle, datatype, range, initRange)
|
||||
% JEInterface(fhandle, datatype, range, initRange, defaultargs)
|
||||
% JEInterface(fhandle, datatype, range, initRange, defaultargs, options...)
|
||||
%
|
||||
% Arguments:
|
||||
% fhandle: a function handle defining the optimization target.
|
||||
% datatype: symbol 'int', 'double', or 'binary' denoting the problem data
|
||||
% type
|
||||
% range: a 2 x dim array defining the solution subspace with lower and
|
||||
% upper bounds; or a scalar defining the bitwidth for binary
|
||||
% problems.
|
||||
@ -52,11 +54,22 @@ int.mediator = '';
|
||||
int.optParams = [];
|
||||
int.optParamValues = [];
|
||||
int.hexMask=hex2dec('ffffffff');
|
||||
int.dataType=''; % to be set later!
|
||||
|
||||
if (isa(fhandle, 'function_handle'))
|
||||
int.f = fhandle;
|
||||
else
|
||||
error('Wrong second argument type, expected function_handle');
|
||||
error('Wrong first argument type, expected function_handle');
|
||||
end
|
||||
|
||||
if (strcmp(datatype,'double'))
|
||||
int.dataType=eva2.server.go.problems.MatlabProblemDataTypeEnum.typeDouble;
|
||||
elseif strcmp(datatype, 'int')
|
||||
int.dataType=eva2.server.go.problems.MatlabProblemDataTypeEnum.typeInteger;
|
||||
elseif strcmp(datatype, 'binary')
|
||||
int.dataType=eva2.server.go.problems.MatlabProblemDataTypeEnum.typeBinary;
|
||||
else
|
||||
error('Invalid data type, select double, int, or binary!');
|
||||
end
|
||||
|
||||
disp('Setting up JEInterface...');
|
||||
@ -79,7 +92,7 @@ end
|
||||
int = class(int,'JEInterface');
|
||||
int.opts = makeOptions(int);
|
||||
|
||||
if (nargin>2)
|
||||
if (nargin>3)
|
||||
int.initialRange=varargin{1};
|
||||
|
||||
if (isa(varargin{1}, 'double') && (size(varargin{1},1) == 2))
|
||||
@ -91,15 +104,15 @@ if (nargin>2)
|
||||
disp(s);
|
||||
end
|
||||
|
||||
if (nargin>3)
|
||||
if (nargin>4)
|
||||
int.args = varargin{2};
|
||||
disp('Fitness function argument: '); disp(int.args);
|
||||
if (nargin > 4)
|
||||
if (rem(nargin,2)==1)
|
||||
if (nargin > 5)
|
||||
if (rem(nargin,2)==0)
|
||||
error('Invalid number of arguments!');
|
||||
end
|
||||
disp('Reading options:');
|
||||
for i=3:2:nargin-2
|
||||
for i=3:2:nargin-3
|
||||
int=setOpt(int, varargin{i}, varargin{i+1});
|
||||
end
|
||||
end
|
||||
@ -107,11 +120,15 @@ if (nargin>2)
|
||||
end
|
||||
display(getOptions(int));
|
||||
% finally create the java object
|
||||
if (isempty(int.initialRange))
|
||||
int.mp = eva2.server.go.problems.MatlabProblem(int.dim, int.range);
|
||||
if (isempty(int.initialRange)) % binary case
|
||||
int.mp = eva2.server.go.problems.MatlabProblem(int.dim, int.dataType, int.range);
|
||||
else
|
||||
if (isempty(int.range) || eq(size(int.range), size(int.initialRange)))
|
||||
int.mp = eva2.server.go.problems.MatlabProblem(int.dim, int.range, int.initialRange);
|
||||
% size(int.range);
|
||||
% size(int.initialRange);
|
||||
% eq(size(int.range), size(int.initialRange))
|
||||
% disp('-------');
|
||||
if (isempty(int.range) || (sum(eq(size(int.range), size(int.initialRange)))==2))
|
||||
int.mp = eva2.server.go.problems.MatlabProblem(int.dim, int.dataType, int.range, int.initialRange);
|
||||
%int.mp.getIndividualTemplate().setMutationOperator( ...
|
||||
% eva2.server.go.operators.mutation.MutateEAMixer(eva2.server.go.operators.mutation.MutateGASwapBits, eva2.server.go.operators.mutation.MutateGAUniform));
|
||||
else
|
||||
|
@ -2,7 +2,7 @@ function testEvalFunc(int)
|
||||
% Test the fitness function output format.
|
||||
wordwidth=32;
|
||||
|
||||
if (isempty(int.range))
|
||||
if (strcmp(int.dataType,eva2.server.go.problems.MatlabProblemDataTypeEnum.typeBinary))
|
||||
% binary problem
|
||||
s=sprintf('Binary problem of bitwidth %d', int.dim);
|
||||
disp(s);
|
||||
@ -13,7 +13,7 @@ if (isempty(int.range))
|
||||
%x(numInts)=bitshift(x(numInts),-overheadBits); % shift right by overhead
|
||||
bs=eva2.tools.math.RNG.randomBitSet(0.5, int.dim);
|
||||
x=convertUnsignedJE(int, bs);
|
||||
else
|
||||
elseif strcmp(int.dataType,eva2.server.go.problems.MatlabProblemDataTypeEnum.typeDouble)
|
||||
% double problem
|
||||
x=rand(1, int.dim);
|
||||
s=sprintf('Real valued problem in %d dimensions and range %s ', int.dim, mat2str(int.range));
|
||||
@ -21,8 +21,16 @@ else
|
||||
for i=1:int.dim
|
||||
x(i)=int.range(i,1)+x(i)*(int.range(i,2)-int.range(i,1));
|
||||
end
|
||||
elseif strcmp(int.dataType,eva2.server.go.problems.MatlabProblemDataTypeEnum.typeInteger)
|
||||
% integer problem
|
||||
s=sprintf('Real valued problem in %d dimensions and range %s ', int.dim, mat2str(int.range));
|
||||
disp(s);
|
||||
size(int.range)
|
||||
%x=int.range(1,:)+ceil(rand(1,int.dim).*int.range(2,:)-int.range(1,:));
|
||||
x=(int.range(:,1)+ceil(rand(int.dim,1).*int.range(:,2)-int.range(:,1)))';
|
||||
else
|
||||
error('Invalid data type in testEvalFunc.m!');
|
||||
end
|
||||
|
||||
if (isempty(int.range))
|
||||
msg=sprintf('\nTesting value: %d, bin.: %s', x, dec2bin(x, int.dim));
|
||||
else
|
||||
|
@ -233,17 +233,22 @@ public class MatlabEvalMediator {
|
||||
}
|
||||
|
||||
void setSolution(Object sol) {
|
||||
//System.out.println("setting Sol");
|
||||
// System.err.println("setting obj Sol " + BeanInspector.toString(sol));
|
||||
optSolution = sol;
|
||||
}
|
||||
|
||||
void setSolutionSet(double[][] solSet) {
|
||||
// System.err.println("setting SolSet " + ((solSet != null) ? solSet.length : 0));
|
||||
// System.err.println("setting dbl SolSet " + ((solSet != null) ? solSet.length : 0));
|
||||
optSolSet = solSet;
|
||||
}
|
||||
|
||||
void setSolutionSet(BitSet[] solSet) {
|
||||
// System.err.println("setting SolSet " + ((solSet != null) ? solSet.length : 0));
|
||||
// System.err.println("setting bs SolSet " + ((solSet != null) ? solSet.length : 0));
|
||||
optSolSet = solSet;
|
||||
}
|
||||
|
||||
void setSolutionSet(int[][] solSet) {
|
||||
// System.err.println("setting int SolSet " + ((solSet != null) ? solSet.length : 0));
|
||||
optSolSet = solSet;
|
||||
}
|
||||
|
||||
@ -252,7 +257,7 @@ public class MatlabEvalMediator {
|
||||
* @return
|
||||
*/
|
||||
public Object getSolution() {
|
||||
// System.err.println("getting Sol");
|
||||
// System.err.println("getting Sol " + BeanInspector.toString(optSolution));
|
||||
return optSolution;
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,10 @@ import eva2.server.go.PopulationInterface;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
import eva2.server.go.individuals.ESIndividualDoubleData;
|
||||
import eva2.server.go.individuals.GAIndividualBinaryData;
|
||||
import eva2.server.go.individuals.GIIndividualIntegerData;
|
||||
import eva2.server.go.individuals.InterfaceDataTypeBinary;
|
||||
import eva2.server.go.individuals.InterfaceDataTypeDouble;
|
||||
import eva2.server.go.individuals.InterfaceDataTypeInteger;
|
||||
import eva2.server.go.operators.postprocess.InterfacePostProcessParams;
|
||||
import eva2.server.go.operators.postprocess.PostProcess;
|
||||
import eva2.server.go.operators.postprocess.PostProcessParams;
|
||||
@ -50,16 +52,16 @@ public class MatlabProblem extends AbstractOptimizationProblem implements Interf
|
||||
// transient PrintStream resOutStream = null;
|
||||
int verbosityLevel = 0;
|
||||
private MatlabEvalMediator handler = null;
|
||||
private boolean isDouble = true;
|
||||
// private boolean isDouble = true;
|
||||
private MatlabProblemDataTypeEnum dataType = MatlabProblemDataTypeEnum.typeDouble;
|
||||
private double[][] initialRange = null; // the initial range for double-valued problems
|
||||
|
||||
public static boolean hideFromGOE = true;
|
||||
|
||||
|
||||
// transient private double[] currArray = null;
|
||||
// private String mtCmd = null;
|
||||
|
||||
public MatlabProblem(MatlabProblem o) {
|
||||
// this.matlab = o.matlab;
|
||||
this.m_Template=null;
|
||||
this.handler = o.handler;
|
||||
this.runnable = o.runnable;
|
||||
@ -69,7 +71,7 @@ public class MatlabProblem extends AbstractOptimizationProblem implements Interf
|
||||
// this.res = new ResultArr();
|
||||
// if (o.res != null) if (o.res.get() != null) res.set(o.res.get());
|
||||
this.range = o.range;
|
||||
this.isDouble = o.isDouble;
|
||||
this.dataType = o.dataType;
|
||||
this.initialRange = o.initialRange;
|
||||
// this.mtCmd = o.mtCmd;
|
||||
// currArray = null;
|
||||
@ -79,61 +81,104 @@ public class MatlabProblem extends AbstractOptimizationProblem implements Interf
|
||||
return new MatlabProblem(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor of a real valued problem.
|
||||
* @param dim
|
||||
* @param range
|
||||
*/
|
||||
// public MatlabProblem(int dim, double[][] range) {
|
||||
// init(dim, ProblemDataTypeEnum.typeDouble, range, null, defTestOut);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Constructor of a binary problem with given bit length.
|
||||
* @param dim
|
||||
*/
|
||||
public MatlabProblem(int dim) {
|
||||
this(dim, (double[][])null);
|
||||
}
|
||||
|
||||
public MatlabProblem(int dim, double[][] range) {
|
||||
init(dim, range, null, defTestOut);
|
||||
init(dim, MatlabProblemDataTypeEnum.typeBinary, null, null, defTestOut);
|
||||
}
|
||||
|
||||
public MatlabProblem(int dim, double[][] range, double[][] initRange) {
|
||||
init(dim, range, initRange, defTestOut);
|
||||
/**
|
||||
* Constructor of a real valued problem with initialization range.
|
||||
* @param dim
|
||||
* @param range
|
||||
* @param initRange
|
||||
*/
|
||||
// public MatlabProblem(int dim, double[][] range, double[][] initRange) {
|
||||
// init(dim, ProblemDataTypeEnum.typeDouble, range, initRange, defTestOut);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Constructor of real or integer valued problem, the range will be converted
|
||||
* to integer in the latter case.
|
||||
*
|
||||
* @param dim
|
||||
* @param datType
|
||||
* @param range
|
||||
*/
|
||||
public MatlabProblem(int dim, MatlabProblemDataTypeEnum datType, double[][] range) {
|
||||
init(dim, datType, range, null, defTestOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor of real or integer valued problem with initialization range.
|
||||
* The ranges will be converted to integer in the latter case.
|
||||
*
|
||||
* @param dim
|
||||
* @param datType
|
||||
* @param range
|
||||
*/
|
||||
public MatlabProblem(int dim, MatlabProblemDataTypeEnum datType, double[][] range, double[][] initRange) {
|
||||
init(dim, datType, range, initRange, defTestOut);
|
||||
}
|
||||
|
||||
public MatlabProblem(int dim, double lower, double upper) {
|
||||
this(dim, null);
|
||||
double[][] range = new double[dim][2];
|
||||
for (int i=0; i<dim; i++) {
|
||||
range[dim][0] = lower;
|
||||
range[dim][1] = upper;
|
||||
}
|
||||
}
|
||||
|
||||
// public MatlabProblem(int dim, double lower, double upper) {
|
||||
// this(dim, null);
|
||||
// double[][] range = new double[dim][2];
|
||||
// for (int i=0; i<dim; i++) {
|
||||
// range[dim][0] = lower;
|
||||
// range[dim][1] = upper;
|
||||
// }
|
||||
// }
|
||||
|
||||
protected void initTemplate() {
|
||||
if (isDouble) {
|
||||
if (m_Template == null) m_Template = new ESIndividualDoubleData();
|
||||
switch (dataType) {
|
||||
case typeDouble:
|
||||
if (m_Template == null || !(m_Template instanceof ESIndividualDoubleData)) m_Template = new ESIndividualDoubleData();
|
||||
if (getProblemDimension() > 0) { // avoid evil case setting dim to 0 during object init
|
||||
((InterfaceDataTypeDouble)this.m_Template).setDoubleDataLength(getProblemDimension());
|
||||
((InterfaceDataTypeDouble)this.m_Template).SetDoubleRange(range);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
case typeBinary:
|
||||
///// binary alternative
|
||||
if (m_Template == null) m_Template = new GAIndividualBinaryData(getProblemDimension());
|
||||
|
||||
///// Integer alternative
|
||||
/*if (m_Template == null) m_Template = new GAIndividualIntegerData();
|
||||
int intLen = 1+((getProblemDimension()-1)/32);
|
||||
int lastIntCodingBits = getProblemDimension()-((intLen-1)*32);
|
||||
if (lastIntCodingBits > 32) System.err.println("ERROR in MatlabProblem:initTemplate");
|
||||
((GAIndividualIntegerData)m_Template).setIntegerDataLength(intLen);
|
||||
((GAIndividualIntegerData)m_Template).SetIntRange(Integer.MIN_VALUE, Integer.MAX_VALUE);
|
||||
if (lastIntCodingBits < 32) ((GAIndividualIntegerData)m_Template).SetIntRange(intLen-1, 0, (int)Math.pow(2, lastIntCodingBits)-1);
|
||||
*/ /////
|
||||
// System.err.println("integer length is "+((GAIndividualIntegerData)m_Template).getIntegerData().length);
|
||||
// System.err.println("Range is " + BeanInspector.toString(((GAIndividualIntegerData)m_Template).getIntRange()));
|
||||
// m_Template = new GAIndividualBinaryData();
|
||||
// ((GAIndividualBinaryData)m_Template).setBinaryDataLength(getProblemDimension());
|
||||
if (m_Template == null || !(m_Template instanceof GAIndividualBinaryData)) m_Template = new GAIndividualBinaryData(getProblemDimension());
|
||||
break;
|
||||
case typeInteger:
|
||||
int[][] intRange=makeIntRange(range);
|
||||
if (m_Template == null || !(m_Template instanceof GIIndividualIntegerData)) m_Template = new GIIndividualIntegerData(intRange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private int[][] makeIntRange(double[][] r) {
|
||||
int[][] intRange=new int[r.length][r[0].length];
|
||||
for (int i=0; i<r.length; i++){
|
||||
for (int j=0; j<r[0].length; j++) {
|
||||
intRange[i][j]=(int)r[i][j];
|
||||
}
|
||||
}
|
||||
return intRange;
|
||||
}
|
||||
|
||||
public void setMediator(MatlabEvalMediator h) {
|
||||
handler = h;
|
||||
handler.setMatlabProblem(this);
|
||||
}
|
||||
|
||||
public void initProblem() {
|
||||
init(this.problemDimension, range, initialRange, defTestOut);
|
||||
init(this.problemDimension, dataType, range, initialRange, defTestOut);
|
||||
}
|
||||
|
||||
public static FitnessConvergenceTerminator makeFitConvTerm(double thresh, int stagnPeriod) {
|
||||
@ -154,7 +199,7 @@ public class MatlabProblem extends AbstractOptimizationProblem implements Interf
|
||||
* @param initRange
|
||||
* @param outFile
|
||||
*/
|
||||
private void init(int dim, double[][] globalRange, double[][] initRange, String outFile) {
|
||||
private void init(int dim, MatlabProblemDataTypeEnum datType, double[][] globalRange, double[][] initRange, String outFile) {
|
||||
this.problemDimension = dim;
|
||||
// if ((rng != null) && (dim != rng.length)) throw new ArrayIndexOutOfBoundsException("Mismatching dimension and range!");
|
||||
if (globalRange!=null) { // these may be Matlab objects, so I do it by foot, just to be sure not to clone them within Matlab instead of here
|
||||
@ -173,8 +218,8 @@ public class MatlabProblem extends AbstractOptimizationProblem implements Interf
|
||||
|
||||
if (Arrays.deepEquals(initialRange, range)) initialRange=null;
|
||||
|
||||
if (range==null) isDouble = false;
|
||||
else isDouble = true;
|
||||
dataType=datType; // store the data type
|
||||
log("### Data type is " + dataType);
|
||||
|
||||
// System.err.println("isDouble: " + isDouble);
|
||||
// System.err.println("range: " + BeanInspector.toString(range));
|
||||
@ -411,34 +456,42 @@ public class MatlabProblem extends AbstractOptimizationProblem implements Interf
|
||||
|
||||
void exportResultPopulationToMatlab(Population pop) {
|
||||
if ((pop != null) && (pop.size()>0)) {
|
||||
if (isDouble) {
|
||||
double[][] solSet = new double[pop.size()][];
|
||||
switch(dataType) {
|
||||
case typeDouble:
|
||||
double[][] rsolSet = new double[pop.size()][];
|
||||
for (int i=0; i<pop.size(); i++) {
|
||||
solSet[i]=((InterfaceDataTypeDouble)pop.getEAIndividual(i)).getDoubleData();
|
||||
rsolSet[i]=((InterfaceDataTypeDouble)pop.getEAIndividual(i)).getDoubleData();
|
||||
}
|
||||
handler.setSolutionSet(solSet);
|
||||
} else {
|
||||
BitSet[] solSet = new BitSet[pop.size()];
|
||||
handler.setSolutionSet(rsolSet);
|
||||
break;
|
||||
case typeBinary:
|
||||
BitSet[] bsolSet = new BitSet[pop.size()];
|
||||
for (int i=0; i<pop.size(); i++) {
|
||||
solSet[i]=((InterfaceDataTypeBinary)pop.getEAIndividual(i)).getBinaryData();
|
||||
bsolSet[i]=((InterfaceDataTypeBinary)pop.getEAIndividual(i)).getBinaryData();
|
||||
}
|
||||
handler.setSolutionSet(solSet);
|
||||
handler.setSolutionSet(bsolSet);
|
||||
break;
|
||||
case typeInteger:
|
||||
int[][] isolSet = new int[pop.size()][];
|
||||
for (int i=0; i<pop.size(); i++) {
|
||||
isolSet[i]=((InterfaceDataTypeInteger)pop.getEAIndividual(i)).getIntegerData();
|
||||
}
|
||||
handler.setSolutionSet(isolSet);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (isDouble) handler.setSolutionSet((double[][])null);
|
||||
else handler.setSolutionSet((BitSet[])null);
|
||||
switch(dataType) {
|
||||
case typeDouble: handler.setSolutionSet((double[][])null); break;
|
||||
case typeBinary: handler.setSolutionSet((BitSet[])null); break;
|
||||
case typeInteger: handler.setSolutionSet((int[][])null); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void exportResultToMatlab(OptimizerRunnable runnable) {
|
||||
if (isDouble) handler.setSolution(runnable.getDoubleSolution());
|
||||
else handler.setSolution(runnable.getBinarySolution());
|
||||
public void exportResultToMatlab(OptimizerRunnable runnable) {
|
||||
handler.setSolution(getIntermediateResult());
|
||||
}
|
||||
|
||||
// void exportResultToMatlab(double[] result) {
|
||||
// handler.setSolution(result);
|
||||
// }
|
||||
|
||||
/**
|
||||
* To be called by the executing thread to inform that the thread is finished.
|
||||
* We
|
||||
@ -448,10 +501,16 @@ public class MatlabProblem extends AbstractOptimizationProblem implements Interf
|
||||
}
|
||||
|
||||
public Object getIntermediateResult() {
|
||||
if (runnable == null) return null;
|
||||
else {
|
||||
if (isDouble) return runnable.getDoubleSolution();
|
||||
else return runnable.getIntegerSolution();
|
||||
if (runnable == null) {
|
||||
System.err.println("Warning, runnable is null in MatlabProblem!");
|
||||
return null;
|
||||
} else {
|
||||
switch(dataType) {
|
||||
case typeDouble: return runnable.getDoubleSolution();
|
||||
case typeBinary: return runnable.getBinarySolution();
|
||||
case typeInteger: return runnable.getIntegerSolution();
|
||||
default: System.err.println("Warning, incompatible data type in MatlabProblem!");return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
package eva2.server.go.problems;
|
||||
|
||||
public enum MatlabProblemDataTypeEnum {
|
||||
typeDouble, typeBinary, typeInteger;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user