/** * return a random individual (other than i unless i is the only member in the population). * * @param individuals List // List<DPSOIndividual> * @param i int * @param gen int unused * @param params HashMap must contain an entry <"thread.id",Integer val> * @return DPSOIndividual */ public DPSOIndividual getBestIndividual(List individuals, int i, int gen, HashMap params) { final int indsz = individuals.size(); final int id = ((Integer) params.get("thread.id")).intValue(); final RndUtil rndgen = RndUtil.getInstance(id); int j = rndgen.getRandom().nextInt(indsz); if (j == i) { if (i < indsz / 2) ++j; else if (i > 0) --j; // if i==0 && i>=indsz/2 ==> indsz <= 1 thus keep j=0 } DPSOIndividual ret = (DPSOIndividual) individuals.get(j); return ret; }
/** * run as <CODE> * java -cp <classpath> tests.DDETest <params_file> [random_seed] [maxfuncevals] * </CODE>. The params_file must contain lines of the following form: * * <ul> * <li>class,dde.function, <fullclasspathname> mandatory, the java class name defining the * function to be optimized, which must accept as arguments either <CODE>double[]</CODE> or * <CODE>VectorIntf</CODE> objects. * <li>class,dde.localoptimizer, <fullclasspathname> optional the java class name of an * object implementing the LocalOptimizerIntf defined in the popt4jlib.GradientDescent * package, to be used as further optimizer of the best solution found by the DE process. * <li>dde.numdimensions, $num$ mandatory, the dimension of the domain of the function to be * minimized. * <li>dde.numtries, $num$ optional, the total number of "tries", default is 100. * <li>dde.numthreads, $num$ optional, the number of threads to use, default is 1. * <li>rndgen,$num$,$num2$ mandatory, specifies the starting random seed to use for each of the * $num2$ threads to use (the value num2 must equal the number given in the line for * dde.numthreads). * <li>dde.popsize, $num$ optional, the total population size in each iteration, default is 10. * <li>dde.w, $num$ optional, the "weight" of the DE process, a double number in [0,2], default * is 1.0 * <li>dde.px, $num$ optional, the "crossover rate" of the DE process, a double number in [0,1], * default is 0.9 * <li>dde.minargval, $num$ optional, a double number that is a lower bound for all variables of * the optimization process, i.e. all variables must satisfy x_i ≥ $num$, default is * -infinity * <li>dde.maxargval, $num$ optional, a double number that is an upper bound for all variables * of the optimization process, i.e. all variables must satisfy x_i ≤ $num$, default is * +infinity * <li>dde.minargval$i$, $num$ optional, a double number that is a lower bound for the i-th * variable of the optimization process, i.e. variable must satisfy x_i ≥ $num$, default * is -infinity * <li>dde.maxargval$i$, $num$ optional, a double number that is an upper bound for the i-th * variable of the optimization process, i.e. variable must satisfy x_i ≤ $num$, default * is +infinity * <li>dde.de/best/1/binstrategy, $val$ optional, a boolean value that if present and true, * indicates that the DE/best/1/bin strategy should be used in evolving the population * instead of the DE/rand/1/bin strategy, default is false * <li>dde.nondeterminismok, $val$ optional, a boolean value indicating whether the method * should return always the same value given the same parameters and same random seed(s). * The method can be made to run much faster in a multi-core setting if this flag is set to * true (at the expense of deterministic results) getting the CPU utilization to reach * almost 100% as opposed to around 60% otherwise, default is false * <li>dde.countfuncevals, $val$ optional, a boolean value indicating whether or not the process * should be counting the number of function evaluations it performs, default is false * <li><"dde.dmpaddress", String location> optional, if existing, specifies the location * of a distributed Msg-Passing server that implements the basic send/recv operations as * specified in <CODE>parallel.distributed.DActiveMsgPassingCoordinatorLongLivedConnSrv[Clt] * </CODE> default is null * <li><"dde.dmpport", Integer port> optional, if existing, specifies the port number of a * distributed Msg-Passing server implementing the basic send/recv operations as specified * in <CODE>parallel.distributed.DActiveMsgPassingCoordinatorLongLivedConnSrv[Clt]</CODE> * default is null * <li><"dde.dmpthisprocessid", Integer myid> optional, if existing, it indicates the id * of this process (this is the number to use in a recvData(myid) call on the * DActiveMsgPassingCoordinatorLongLivedConnClt object) default is null * <li><"dde.dmpnextprocessid", Integer id> optional, if existing, it indicates the id of * the process to which this process should be sending "migrants" to; (this is the number to * use as the "send address" in a sendData(myid, id, data) DActiveblahblah call); default is * null * <li><"dde.numgensbetweenmigrations", Integer num> optional, if existing, it indicates * the number of generations that must pass between two successive "migrations" between DDE * island-processes; default is 10 * <li><"dde.nummigrants",Integer num> optional, if it exists, indicates how many migrants * will be sent and received from each dde process; default is 10 * <li><"dde.reducerhost", String host> optional, if existing, it indicates the address in * which the reducer server resides; default is null * <li><"dde.reducerport", Integer port> optional, if existing, it indicates the address * in which the reducer server process listens at; default is -1 * </ul> * * <p>Notice that in case of running DDE in a distributed manner, there are two important * constraints: * * <ul> * <li>First of all, the various processes participating in the distributed DDE process must * have their dde.dmpthisprocessid and dde.dmpnextprocessid parameters set up so that the * flow of migration forms an exact ring, e.g. for a 3-process DDE we have that DDE_0 sends * migrants to DDE_1 which sends migrants to DDE_2 which sends migrants to DDE_0. * <li>The constraint dde.numgensbetweenmigrations ≤ dde.numtries must hold. * </ul> * * Otherwise, there is no way for processes to block in at least one migration cycle (and thereby * have the DReduceSrv know the total number of processes before the final reduce operation), and * therefore the distributed reduce operation afterwards is not guaranteed to work properly. * * <p>if the second optional argument is passed in, it overrides the random seed specified in the * params_file (specified as the 1st arg in cmd-line). * * <p>The optional third argument, if present, overrides any max. limit set on the number of * function evaluations allowed. After this limit, the function will always return * Double.MAX_VALUE instead, and won't increase the evaluation count. Obviously, for this limit to * be enforced, the "dde.countfuncevals" flag must be set to true in the params_file (1st arg in * the command line) * * @param args String[] */ public static void main(String[] args) { try { long start_time = System.currentTimeMillis(); HashMap params = utils.DataMgr.readPropsFromFile(args[0]); if (args.length > 1) { long seed = Long.parseLong(args[1]); RndUtil.getInstance().setSeed(seed); // updates all extra instances too! } if (args.length > 2) { long num = Long.parseLong(args[2]); params.put("maxfuncevalslimit", new Long(num)); } FunctionIntf func = (FunctionIntf) params.get("dde.function"); if (params.containsKey("dde.countfuncevals") && ((Boolean) params.get("dde.countfuncevals")).booleanValue() == true) { FunctionBase wrapper_func = new FunctionBase(func); params.put("dde.function", wrapper_func); func = wrapper_func; } DDE opter = new DDE(params); utils.PairObjDouble p = opter.minimize(func); VectorIntf arg = (VectorIntf) p.getArg(); System.out.print("best soln found:["); for (int i = 0; i < arg.getNumCoords(); i++) System.out.print(arg.getCoord(i) + " "); System.out.println("] VAL=" + p.getDouble()); // final local optimization utils.PairObjDouble p2 = null; LocalOptimizerIntf lasdst = (LocalOptimizerIntf) params.get("dde.localoptimizer"); if (lasdst != null) { VectorIntf x0 = arg.newInstance(); // arg.newCopy(); params.put("gradientdescent.x0", x0); lasdst.setParams(params); p2 = lasdst.minimize(func); VectorIntf xf = (VectorIntf) p2.getArg(); System.out.print("Optimized (via a GradientDescent local method) best soln found:["); for (int i = 0; i < xf.getNumCoords(); i++) System.out.print(xf.getCoord(i) + " "); System.out.println("] VAL=" + p2.getDouble()); } if (func instanceof FunctionBase) System.err.println("total function evaluations=" + ((FunctionBase) func).getEvalCount()); long dur = System.currentTimeMillis() - start_time; double val = (p2 == null || p2.getDouble() >= Double.MAX_VALUE) ? p.getDouble() : p2.getDouble(); System.out.println("total time (msecs): " + dur); if (func instanceof FunctionBase) System.out.println( "VVV," + val + ",TTT," + dur + ",NNN," + ((FunctionBase) func).getEvalCount() + ",PPP,DDE,FFF," + args[0]); // for parser program to extract from output } catch (Exception e) { e.printStackTrace(); System.exit(-1); } }