diff options
Diffstat (limited to '')
57 files changed, 4658 insertions, 0 deletions
diff --git a/nlpsolver/Extension_nlpsolver.mk b/nlpsolver/Extension_nlpsolver.mk new file mode 100644 index 000000000..8ec0e1afc --- /dev/null +++ b/nlpsolver/Extension_nlpsolver.mk @@ -0,0 +1,35 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# + +$(eval $(call gb_Extension_Extension,nlpsolver,nlpsolver/src/com/sun/star/comp/Calc/NLPSolver)) + +$(eval $(call gb_Extension_use_default_description,nlpsolver,nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/description-en-US.txt)) +$(eval $(call gb_Extension_use_default_license,nlpsolver)) + +$(eval $(call gb_Extension_add_file,nlpsolver,components.rdb,$(SRCDIR)/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/components.rdb)) +$(eval $(call gb_Extension_add_file,nlpsolver,nlpsolver.jar,$(call gb_Jar_get_target,nlpsolver))) +$(eval $(call gb_Extension_add_file,nlpsolver,EvolutionarySolver.jar,$(call gb_Jar_get_target,EvolutionarySolver))) + +$(eval $(call gb_Extension_add_file,nlpsolver,locale/NLPSolverCommon_en_US.default,$(SRCDIR)/nlpsolver/src/locale/NLPSolverCommon_en_US.default)) +$(eval $(call gb_Extension_add_file,nlpsolver,locale/NLPSolverStatusDialog_en_US.default,$(SRCDIR)/nlpsolver/src/locale/NLPSolverStatusDialog_en_US.default)) + +$(eval $(call gb_Extension_localize_properties,nlpsolver,locale/NLPSolverCommon_en_US.properties,$(SRCDIR)/nlpsolver/src/locale/NLPSolverCommon_en_US.properties)) +$(eval $(call gb_Extension_localize_properties,nlpsolver,locale/NLPSolverStatusDialog_en_US.properties,$(SRCDIR)/nlpsolver/src/locale/NLPSolverStatusDialog_en_US.properties)) + +$(eval $(call gb_Extension_add_helpfiles,nlpsolver,$(SRCDIR)/nlpsolver/help/en, \ + com.sun.star.comp.Calc.NLPSolver/Options.xhp \ + com.sun.star.comp.Calc.NLPSolver/Usage.xhp \ +)) + +$(eval $(call gb_Extension_add_helptreefile,nlpsolver,$(SRCDIR)/nlpsolver/help/en,help.tree,com.sun.star.comp.Calc.NLPSolver/help.tree,com.sun.star.comp.Calc.NLPSolver)) + + +# vim: set noet sw=4 ts=4: diff --git a/nlpsolver/Jar_EvolutionarySolver.mk b/nlpsolver/Jar_EvolutionarySolver.mk new file mode 100644 index 000000000..5dad01a71 --- /dev/null +++ b/nlpsolver/Jar_EvolutionarySolver.mk @@ -0,0 +1,51 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you 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 . +# + +$(eval $(call gb_Jar_Jar,EvolutionarySolver)) + +$(eval $(call gb_Jar_set_packageroot,EvolutionarySolver,net/adaptivebox)) + +$(eval $(call gb_Jar_set_manifest,EvolutionarySolver,$(SRCDIR)/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/Manifest.mf)) + +$(eval $(call gb_Jar_add_sourcefiles,EvolutionarySolver,\ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/goodness/ACRComparator \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/goodness/BCHComparator \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/goodness/IGoodnessCompareEngine \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/global/BasicBound \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/global/RandomGenerator \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/global/IUpdateCycleEngine \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/encode/EvalStruct \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/encode/EvalElement \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/encode/IEncodeEngine \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/ILocationEngine \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/BasicPoint \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/DesignSpace \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/DesignDim \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/problem/ProblemEncoder \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/knowledge/Library \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/knowledge/ILibEngine \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/knowledge/SearchPoint \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/DEPSAgent \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/behavior/PSGTBehavior \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/behavior/AbsGTBehavior \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/behavior/DEGTBehavior \ + nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/sco/SCAgent \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/nlpsolver/Jar_nlpsolver.mk b/nlpsolver/Jar_nlpsolver.mk new file mode 100644 index 000000000..3203b012d --- /dev/null +++ b/nlpsolver/Jar_nlpsolver.mk @@ -0,0 +1,51 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you 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 . +# + +$(eval $(call gb_Jar_Jar,nlpsolver)) + +$(eval $(call gb_Jar_use_jars,nlpsolver,\ + libreoffice \ + java_uno \ + EvolutionarySolver \ +)) + +$(eval $(call gb_Jar_set_packageroot,nlpsolver,com)) + +$(eval $(call gb_Jar_set_manifest,nlpsolver,$(SRCDIR)/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/Manifest.mf)) + +$(eval $(call gb_Jar_add_sourcefiles,nlpsolver,\ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/Registration \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/PropertyInfo \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/BaseControl \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/ProgressBar \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/Button \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/LabeledControl \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/Label \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/DummyEvolutionarySolverStatusDialog \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/IEvolutionarySolverStatusDialog \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/EvolutionarySolverStatusUno \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/BaseDialog \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/DEPSSolverImpl \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/SCOSolverImpl \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/BaseEvolutionarySolver \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/ResourceManager \ + nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/BaseNLPSolver \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/nlpsolver/Makefile b/nlpsolver/Makefile new file mode 100644 index 000000000..ccb1c85a0 --- /dev/null +++ b/nlpsolver/Makefile @@ -0,0 +1,7 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- + +module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST)))) + +include $(module_directory)/../solenv/gbuild/partial_build.mk + +# vim: set noet sw=4 ts=4: diff --git a/nlpsolver/Module_nlpsolver.mk b/nlpsolver/Module_nlpsolver.mk new file mode 100644 index 000000000..6cb9e821b --- /dev/null +++ b/nlpsolver/Module_nlpsolver.mk @@ -0,0 +1,30 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you 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 . +# + +$(eval $(call gb_Module_Module,nlpsolver)) + +ifeq ($(ENABLE_JAVA),TRUE) +$(eval $(call gb_Module_add_targets,nlpsolver,\ + Jar_EvolutionarySolver \ + Jar_nlpsolver \ + Extension_nlpsolver \ +)) +endif + +# vim: set noet sw=4 ts=4: diff --git a/nlpsolver/README.md b/nlpsolver/README.md new file mode 100644 index 000000000..4f929e0d3 --- /dev/null +++ b/nlpsolver/README.md @@ -0,0 +1,7 @@ +# New Linear Programming Solver (nlpsolver) + +This extension integrates into LibreOffice Calc and offers new Solver engines to use for optimizing +nonlinear programming models. + +As there is no known upstream source for `nlpsolver/ThirdParty/EvolutionarySolver`, +the code is considered internal and can be modified like any other internal code. diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/Manifest.mf b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/Manifest.mf new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/Manifest.mf @@ -0,0 +1,2 @@ + + diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/DEPSAgent.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/DEPSAgent.java new file mode 100644 index 000000000..3a08df39f --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/DEPSAgent.java @@ -0,0 +1,128 @@ +package net.adaptivebox.deps; + +/** + * Description: The description of agent with hybrid differential evolution and particle swarm. + * + * @ Author Create/Modi Note + * Xiaofeng Xie Jun 10, 2004 + * Xiaofeng Xie Jul 01, 2008 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + * + * @version 1.0 + * @Since MAOS1.0 + * + * @References: + * [1] Zhang W J, Xie X F. DEPSO: hybrid particle swarm with differential + * evolution operator. IEEE International Conference on Systems, Man & Cybernetics, + * Washington D C, USA, 2003: 3816-3821 + * [2] X F Xie, W J Zhang. SWAF: swarm algorithm framework for numerical + * optimization. Genetic and Evolutionary Computation Conference (GECCO), + * Seattle, WA, USA, 2004: 238-250 + * -> an agent perspective + */ + +import net.adaptivebox.deps.behavior.AbsGTBehavior; +import net.adaptivebox.deps.behavior.DEGTBehavior; +import net.adaptivebox.deps.behavior.PSGTBehavior; +import net.adaptivebox.global.RandomGenerator; +import net.adaptivebox.goodness.IGoodnessCompareEngine; +import net.adaptivebox.knowledge.ILibEngine; +import net.adaptivebox.knowledge.Library; +import net.adaptivebox.knowledge.SearchPoint; +import net.adaptivebox.problem.ProblemEncoder; +import net.adaptivebox.space.BasicPoint; + +public class DEPSAgent { + + // Describes the problem to be solved + private ProblemEncoder problemEncoder; + + // Forms the goodness landscape + private IGoodnessCompareEngine qualityComparator; + + // store the point that generated in current learning cycle + private SearchPoint trailPoint; + + // temp variable + private AbsGTBehavior selectGTBehavior; + + // the own memory: store the point that generated in old learning cycle + private BasicPoint pold_t; + + // the own memory: store the point that generated in last learning cycle + private BasicPoint pcurrent_t; + + // the own memory: store the personal best point + private SearchPoint pbest_t; + + // Generate-and-test behaviors. + private DEGTBehavior deGTBehavior; + private PSGTBehavior psGTBehavior; + + private double switchP = 0.5; + + public DEPSAgent(ProblemEncoder encoder, DEGTBehavior deGTBehavior, PSGTBehavior psGTBehavior, + double switchP, IGoodnessCompareEngine comparer, SearchPoint pbest) { + this.switchP = switchP; + + problemEncoder = encoder; + + qualityComparator = comparer; + + trailPoint = problemEncoder.getFreshSearchPoint(); + pold_t = problemEncoder.getFreshSearchPoint(); + pcurrent_t = problemEncoder.getFreshSearchPoint(); + pbest_t = pbest; + + this.deGTBehavior = deGTBehavior; + this.deGTBehavior.setMemPoints(pbest_t, pcurrent_t, pold_t); + + this.psGTBehavior = psGTBehavior; + this.psGTBehavior.setMemPoints(pbest_t, pcurrent_t, pold_t); + } + + public void setSpecComparator(IGoodnessCompareEngine comparer) { + qualityComparator = comparer; + } + + private AbsGTBehavior getGTBehavior() { + if (RandomGenerator.doubleZeroOneRandom() < switchP) { + return deGTBehavior; + } else { + return psGTBehavior; + } + } + + public void setGTBehavior(AbsGTBehavior gtBehavior) { + gtBehavior.setMemPoints(pbest_t, pcurrent_t, pold_t); + } + + public void generatePoint() { + // generates a new point in the search space (S) based on + // its memory and the library + selectGTBehavior = getGTBehavior(); + selectGTBehavior.generateBehavior(trailPoint, problemEncoder); + + // evaluate into goodness information + problemEncoder.evaluate(trailPoint); + } + + public void learn() { + selectGTBehavior.testBehavior(trailPoint, qualityComparator); + } + + public SearchPoint getMGState() { + return trailPoint; + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/behavior/AbsGTBehavior.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/behavior/AbsGTBehavior.java new file mode 100644 index 000000000..2701c9dee --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/behavior/AbsGTBehavior.java @@ -0,0 +1,43 @@ +/** + * Description: The description of generate-and-test behavior. + * + * + * Author Create/Modi Note + * Xiaofeng Xie May 17, 2004 + * Xiaofeng Xie Jul 01, 2008 + * + * @version 1.0 + * @Since MAOS1.0 + * + * @References: + * [1] X F Xie, W J Zhang. SWAF: swarm algorithm framework for numerical + * optimization. Genetic and Evolutionary Computation Conference (GECCO), + * Seattle, WA, USA, 2004: 238-250 + * -> a generate-and-test behavior + */ +package net.adaptivebox.deps.behavior; + +import net.adaptivebox.goodness.IGoodnessCompareEngine; +import net.adaptivebox.knowledge.ILibEngine; +import net.adaptivebox.knowledge.Library; +import net.adaptivebox.knowledge.SearchPoint; +import net.adaptivebox.problem.ProblemEncoder; +import net.adaptivebox.space.BasicPoint; + +abstract public class AbsGTBehavior implements ILibEngine { + // The referred social library + protected Library socialLib; + + // the own memory: store the personal best point + protected SearchPoint pbest_t; + + public void setLibrary(Library lib) { + socialLib = lib; + } + + abstract public void setMemPoints(SearchPoint pbest, BasicPoint pcurrent, BasicPoint pold); + + abstract public void generateBehavior(SearchPoint trailPoint, ProblemEncoder problemEncoder); + + abstract public void testBehavior(SearchPoint trailPoint, IGoodnessCompareEngine qualityComparator); +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/behavior/DEGTBehavior.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/behavior/DEGTBehavior.java new file mode 100644 index 000000000..c9ca0ef82 --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/behavior/DEGTBehavior.java @@ -0,0 +1,122 @@ +/** + * Description: The description of differential evolution Generate-and-Test Behavior. + + #Supported parameters: + NAME VALUE_type Range DefaultV Description + FACTOR real (0, 1.2] 0.5 DEAgent: scale constant + CR real [0, 1] 0.9 DEAgent: crossover constant + //Other choices for FACTOR and CR: (0.5, 0.1) + + * + * Author Create/Modi Note + * Xiaofeng Xie May 11, 2004 + * Xiaofeng Xie Jul 01, 2008 + * + * @version 1.0 + * @Since MAOS1.0 + * + * @References: + * [1] Storn R, Price K. Differential evolution - a simple and efficient + * heuristic for global optimization over continuous spaces. Journal of + * Global Optimization, 1997, 11: 341-359 + * The original differential evolution idea + * [2] X F Xie, W J Zhang. SWAF: swarm algorithm framework for numerical + * optimization. Genetic and Evolutionary Computation Conference (GECCO), + * Seattle, WA, USA, 2004: 238-250 + * -> a generate-and-test behavior + */ + +package net.adaptivebox.deps.behavior; + +import net.adaptivebox.global.RandomGenerator; +import net.adaptivebox.goodness.IGoodnessCompareEngine; +import net.adaptivebox.knowledge.Library; +import net.adaptivebox.knowledge.SearchPoint; +import net.adaptivebox.problem.ProblemEncoder; +import net.adaptivebox.space.BasicPoint; + +public class DEGTBehavior extends AbsGTBehavior { + //Number of differential vectors, normally be 1 or 2 + private static final int DVNum = 2; + + //scale constant: (0, 1.2], normally be 0.5 + public double MIN_FACTOR = 0.5; + + //scale constant: (0, 1.2], normally be 0.5 + public double MAX_FACTOR = 0.5; + + //crossover constant: [0, 1], normally be 0.1 or 0.9 + public double CR = 0.9; + + @Override + public void setMemPoints(SearchPoint pbest, BasicPoint pcurrent, BasicPoint pold) { + pbest_t = pbest; + } + + /** + * Crossover and mutation for a single vector element done in a single step. + * + * @param index Index of the trial vector element to be changed. + * @param trialVector Trial vector reference. + * @param globalVector Global best found vector reference. + * @param differenceVectors List of vectors used for difference delta + * calculation. + */ + private void crossoverAndMutation(int index, double trialVector[], double globalVector[], + BasicPoint differenceVectors[]) { + double delta = 0D; + + for (int i = 0; i < differenceVectors.length; i++) { + delta += (i % 2 == 0 ? +1D : -1D) * differenceVectors[i].getLocation()[index]; + } + + trialVector[index] = globalVector[index] + RandomGenerator.doubleRangeRandom(MIN_FACTOR, MAX_FACTOR) * delta; + } + + @Override + public void generateBehavior(SearchPoint trailPoint, ProblemEncoder problemEncoder) { + BasicPoint[] referPoints = getReferPoints(); + int DIMENSION = problemEncoder.getDesignSpace().getDimension(); + int guaranteeIndex = RandomGenerator.intRangeRandom(0, DIMENSION - 1); + + double[] trailVector = trailPoint.getLocation(); + double[] locaclVector = pbest_t.getLocation(); + double[] globalVector = socialLib.getGbest().getLocation(); + + /* Handle first part of the trial vector. */ + for (int index = 0; index < guaranteeIndex; index++) { + if (CR <= RandomGenerator.doubleZeroOneRandom()) { + trailVector[index] = locaclVector[index]; + continue; + } + + crossoverAndMutation(index, trailVector, globalVector, referPoints); + } + + /* Guarantee for at least one change in the trial vector. */ + crossoverAndMutation(guaranteeIndex, trailVector, globalVector, referPoints); + + /* Handle second part of the trial vector. */ + for (int index = guaranteeIndex + 1; index < DIMENSION; index++) { + if (CR <= RandomGenerator.doubleZeroOneRandom()) { + trailVector[index] = locaclVector[index]; + continue; + } + + crossoverAndMutation(index, trailVector, globalVector, referPoints); + } + } + + @Override + public void testBehavior(SearchPoint trailPoint, IGoodnessCompareEngine qualityComparator) { + Library.replace(qualityComparator, trailPoint, pbest_t); + } + + private SearchPoint[] getReferPoints() { + SearchPoint[] referPoints = new SearchPoint[DVNum * 2]; + for (int i = 0; i < referPoints.length; i++) { + referPoints[i] = socialLib.getRandomPoint(); + } + return referPoints; + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/behavior/PSGTBehavior.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/behavior/PSGTBehavior.java new file mode 100644 index 000000000..68bf5a10e --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/deps/behavior/PSGTBehavior.java @@ -0,0 +1,132 @@ +/** + * Description: The description of particle swarm (PS) Generate-and-test Behavior. + * + #Supported parameters: + NAME VALUE_type Range DefaultV Description + c1 real [0, 2] 1.494 PSAgent: learning factor for pbest + c2 real [0, 2] 1.494 PSAgent: learning factor for gbest + w real [0, 1] 0.729 PSAgent: inertia weight + CL real [0, 0.1] 0 PSAgent: chaos factor + //Other choices for c1, c2, w, and CL: (2, 2, 0.4, 0.001) + + * Author Create/Modi Note + * Xiaofeng Xie May 11, 2004 + * Xiaofeng Xie Jul 01, 2008 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + * + * @version 1.0 + * @Since MAOS1.0 + * + * References: + * [1] Kennedy J, Eberhart R C. Particle swarm optimization. IEEE Int. Conf. on + * Neural Networks, Perth, Australia, 1995: 1942-1948 + * For original particle swarm idea + * [2] Shi Y H, Eberhart R C. A Modified Particle Swarm Optimizer. IEEE Inter. Conf. + * on Evolutionary Computation, Anchorage, Alaska, 1998: 69-73 + * For the inertia weight: adjust the trade-off between exploitation & exploration + * [3] Clerc M, Kennedy J. The particle swarm - explosion, stability, and + * convergence in a multidimensional complex space. IEEE Trans. on Evolutionary + * Computation. 2002, 6 (1): 58-73 + * Constriction factor: ensures the convergence + * [4] Xie X F, Zhang W J, Yang Z L. A dissipative particle swarm optimization. + * Congress on Evolutionary Computation, Hawaii, USA, 2002: 1456-1461 + * The CL parameter + * [5] Xie X F, Zhang W J, Bi D C. Optimizing semiconductor devices by self- + * organizing particle swarm. Congress on Evolutionary Computation, Oregon, USA, + * 2004: 2017-2022 + * Further experimental analysis on the convergence of PSO + * [6] X F Xie, W J Zhang. SWAF: swarm algorithm framework for numerical + * optimization. Genetic and Evolutionary Computation Conference (GECCO), + * Seattle, WA, USA, 2004: 238-250 + * -> a generate-and-test behavior + * + */ + +package net.adaptivebox.deps.behavior; + +import net.adaptivebox.global.RandomGenerator; +import net.adaptivebox.goodness.IGoodnessCompareEngine; +import net.adaptivebox.knowledge.Library; +import net.adaptivebox.knowledge.SearchPoint; +import net.adaptivebox.problem.ProblemEncoder; +import net.adaptivebox.space.BasicPoint; +import net.adaptivebox.space.DesignSpace; + +public class PSGTBehavior extends AbsGTBehavior { + // Two normally choices for (c1, c2, weight), i.e., (2, 2, 0.4), or (1.494, + // 1.494, 0.729) The first is used in dissipative PSO (cf. [4]) as CL>0, and + // the second is achieved by using constriction factors (cf. [3]) + public double c1 = 2; + public double c2 = 2; + + //inertia weight + public double weight = 0.4; + + //See ref[4], normally be 0.001~0.005 + public double CL = 0; + + // the own memory: store the point that generated in old learning cycle + private BasicPoint pold_t; + + // the own memory: store the point that generated in last learning cycle + private BasicPoint pcurrent_t; + + @Override + public void setMemPoints(SearchPoint pbest, BasicPoint pcurrent, BasicPoint pold) { + pcurrent_t = pcurrent; + pbest_t = pbest; + pold_t = pold; + } + + @Override + public void generateBehavior(SearchPoint trailPoint, ProblemEncoder problemEncoder) { + DesignSpace designSpace = problemEncoder.getDesignSpace(); + + double[] pold_t_location = pold_t.getLocation(); + double[] pbest_t_location = pbest_t.getLocation(); + double[] pcurrent_t_location = pcurrent_t.getLocation(); + double[] gbest_t_location = socialLib.getGbest().getLocation(); + double[] trailPointLocation = trailPoint.getLocation(); + + int DIMENSION = designSpace.getDimension(); + for (int b = 0; b < DIMENSION; b++) { + if (RandomGenerator.doubleZeroOneRandom() < CL) { + designSpace.mutationAt(trailPointLocation, b); + continue; + } + + double deltaxb = weight * (pcurrent_t_location[b] - pold_t_location[b]) + + c1 * RandomGenerator.doubleZeroOneRandom() * (pbest_t_location[b] - pcurrent_t_location[b]) + + c2 * RandomGenerator.doubleZeroOneRandom() * (gbest_t_location[b] - pcurrent_t_location[b]); + + // limitation for delta_x + double deltaxbm = 0.5 * designSpace.getMagnitudeIn(b); + + if (deltaxb < -deltaxbm) { + deltaxb = -deltaxbm; + } else if (deltaxb > deltaxbm) { + deltaxb = deltaxbm; + } + + trailPointLocation[b] = pcurrent_t_location[b] + deltaxb; + } + } + + @Override + public void testBehavior(SearchPoint trailPoint, IGoodnessCompareEngine qualityComparator) { + Library.replace(qualityComparator, trailPoint, pbest_t); + pold_t.importLocation(pcurrent_t); + pcurrent_t.importLocation(trailPoint); + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/encode/EvalElement.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/encode/EvalElement.java new file mode 100644 index 000000000..85e50c9f9 --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/encode/EvalElement.java @@ -0,0 +1,68 @@ +/** + * Description: provide the information for evaluating of a response (target) + * + * Author Create/Modi Note + * Xiaofeng Xie Mar 1, 2003 + * Xiaofeng Xie May 11, 2004 +* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + */ + +package net.adaptivebox.encode; + +import net.adaptivebox.global.BasicBound; + +public class EvalElement { + + // The weight for each response (target) + private static final double weight = 1; + /** + * The expected range of the response value, forms the following objective: + * + * <pre> + * NO minValue maxValue : THE ELEMENT OF BasicBound + * 1 MINDOUBLE, MINDOUBLE: the minimize objective + * 2 MAXDOUBLE, MAXDOUBLE: the maximize objective + * 3 MINDOUBLE, v : the less than constraint {@literal (<v)} + * 4 v , MAXDOUBLE: the larger than constraint {@literal (>v)} + * 5 v1 , v2 : the region constraint, i.e. belongs to [v1, v2] + * + * OPTIM type: the No.1 and No.2 + * CONS type: the last three + * </pre> + */ + public BasicBound targetBound = new BasicBound(); + + public boolean isOptType() { + return ((targetBound.minValue == BasicBound.MINDOUBLE && targetBound.maxValue == BasicBound.MINDOUBLE) + || (targetBound.minValue == BasicBound.MAXDOUBLE && targetBound.maxValue == BasicBound.MAXDOUBLE)); + } + + public double evaluateCONS(double targetValue) { + if (targetValue < targetBound.minValue) { + return weight * (targetBound.minValue - targetValue); + } + if (targetValue > targetBound.maxValue) { + return weight * (targetValue - targetBound.maxValue); + } + return 0; + } + + public double evaluateOPTIM(double targetValue) { + if (targetBound.maxValue == BasicBound.MINDOUBLE) { // min mode + return weight * targetValue; + } else { // max + return -weight * targetValue; + } + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/encode/EvalStruct.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/encode/EvalStruct.java new file mode 100644 index 000000000..db37ddb39 --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/encode/EvalStruct.java @@ -0,0 +1,56 @@ +/** + * Description: provide the information for evaluating a set of targets values + * into encoded information (For formation the goodness landscape by comparing) + * + * Author Create/Modi Note + * Xiaofeng Xie Mar 1, 2003 + * Xiaofeng Xie May 11, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + * + * @References: + * [1] Deb K. An efficient constraint handling method for genetic algorithms. + * Computer Methods in Applied Mechanics and Engineering, 2000, 186(2-4): 311-338 + */ + +package net.adaptivebox.encode; + +public class EvalStruct { + // The information for evaluating all the responses + private EvalElement[] evalElems = null; + + public EvalStruct(int elemsNum) { + evalElems = new EvalElement[elemsNum]; + } + + public void setElemAt(EvalElement dim, int index) { + evalElems[index] = dim; + } + + // convert response values into encoded information double[2] + public void evaluate(double[] evalRes, double[] targetValues) { + evalRes[0] = evalRes[1] = 0; + for (int i = 0; i < evalElems.length; i++) { + if (evalElems[i].isOptType()) { + // The objectives (OPTIM type) + // The multi-objective will be translated into single-objective + evalRes[1] += evalElems[i].evaluateOPTIM(targetValues[i]); + } else { + // The constraints (CONS type) + // If evalRes[0] equals to 0, then be a feasible point, i.e. satisfies + // all the constraints + evalRes[0] += evalElems[i].evaluateCONS(targetValues[i]); + } + } + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/encode/IEncodeEngine.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/encode/IEncodeEngine.java new file mode 100644 index 000000000..56f791c41 --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/encode/IEncodeEngine.java @@ -0,0 +1,24 @@ +/** + * Description: provide the encoded information for objectives + * + * Author Create/Modi Note + * Xiaofeng Xie Feb 10, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + */ + +package net.adaptivebox.encode; + +public interface IEncodeEngine { + double[] getEncodeInfo(); +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/global/BasicBound.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/global/BasicBound.java new file mode 100644 index 000000000..6ed1089d9 --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/global/BasicBound.java @@ -0,0 +1,64 @@ +/** + * Description: provide a bound, and the corresponding operations + * + * Author Create/Modi Note + * Xiaofeng Xie Oct. 9, 2002 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + */ + +package net.adaptivebox.global; + +public class BasicBound { + public static final double MINDOUBLE = -1e308; + public static final double MAXDOUBLE = 1e308; + + public double minValue = MINDOUBLE; + public double maxValue = MAXDOUBLE; + + public BasicBound() { + } + + public BasicBound(double min, double max) { + minValue = Math.min(min, max); + maxValue = Math.max(min, max); + } + + public double getLength() { + return Math.abs(maxValue - minValue); + } + + public double boundAdjust(double value) { + if (value > maxValue) { + value = maxValue; + } else if (value < minValue) { + value = minValue; + } + return value; + } + + public double annulusAdjust(double value) { + if (value > maxValue) { + double extendsLen = (value - maxValue) % getLength(); + value = minValue + extendsLen; + } else if (value < minValue) { + double extendsLen = (minValue - value) % getLength(); + value = maxValue - extendsLen; + } + return value; + } + + public double getRandomValue() { + return RandomGenerator.doubleRangeRandom(minValue, maxValue); + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/global/IUpdateCycleEngine.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/global/IUpdateCycleEngine.java new file mode 100644 index 000000000..0b4db684f --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/global/IUpdateCycleEngine.java @@ -0,0 +1,24 @@ +/** + * Description: provide the interface for updating according to the cycle number + * + * Author Create/Modi Note + * Xiaofeng Xie Feb 18, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + */ + +package net.adaptivebox.global; + +public interface IUpdateCycleEngine { + void updateCycle(int t); +}
\ No newline at end of file diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/global/RandomGenerator.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/global/RandomGenerator.java new file mode 100644 index 000000000..245149e87 --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/global/RandomGenerator.java @@ -0,0 +1,108 @@ +/** + * Description: For generating random numbers. + * + * Author Create/Modi Note + * Xiaofeng Xie Feb 22, 2001 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + * + * @version 1.0 + * @Since MAOS1.0 + */ + +package net.adaptivebox.global; + +import java.util.Random; +import java.security.SecureRandom; + +public class RandomGenerator { + /** + * Pseudo-random number generator instance. + */ + private static Random PRNG = new Random(); + + /** + * Switch between weaker, but faster pseudo-random number generator and + * stronger, but slower. + * + * @param stronger activation of secure pseudo random generator flag + */ + public static void useStrongerGenerator(boolean stronger) { + if(stronger == true) { + PRNG = new SecureRandom(); + } else { + PRNG = new Random(); + } + } + + /** + * This function returns a random integer number between the lowLimit and + * upLimit. + * + * @param lowLimit lower limits upLimit The upper limits (between which the + * random number is to be generated) + * @return int return value Example: for find [0,1,2] + */ + public static int intRangeRandom(int lowLimit, int upLimit) { + int num = lowLimit + PRNG.nextInt(upLimit - lowLimit + 1); + return num; + } + + /** + * This function returns a random float number between the lowLimit and upLimit. + * + * @param lowLimit lower limits upLimit The upper limits (between which the + * random number is to be generated) + * @return double return value + */ + public static double doubleRangeRandom(double lowLimit, double upLimit) { + double num = lowLimit + PRNG.nextDouble() * (upLimit - lowLimit); + return num; + } + + /** + * This function returns a random float number between the zero (inclusive) and one (exclusive). + * + * @return double value in the range [0, 1) + */ + public static double doubleZeroOneRandom() { + return PRNG.nextDouble(); + } + + public static int[] randomSelection(int maxNum, int times) { + if (maxNum < 0) { + maxNum = 0; + } + + if (times < 0) { + times = 0; + } + + int[] all = new int[maxNum]; + for (int i = 0; i < all.length; i++) { + all[i] = i; + } + + /* https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle */ + int[] indices = new int[Math.min(maxNum, times)]; + for (int i = 0, j, value; i < indices.length; i++) { + j = intRangeRandom(i, all.length - 1); + + value = all[j]; + all[j] = all[i]; + indices[i] = all[i] = value; + } + + return indices; + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/goodness/ACRComparator.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/goodness/ACRComparator.java new file mode 100644 index 000000000..284549506 --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/goodness/ACRComparator.java @@ -0,0 +1,91 @@ +/** + * Description: For comparison of goodness in landscape with loosed constraints + * which varied adaptively according to the social information. + * + * Applied domain: efficiently for ridge class feasible space (SF), such as + * the problem with equality constraints + * + * Author Create/Modi Note + * Xiaofeng Xie Jun 24, 2003 Created + * Xiaofeng Xie May 11, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + * + * @version 1.0 + * @Since MAOS1.2 + * + * [1] Xie X F, Zhang W J, Bi D C. Handling equality constraints by adaptive + * relaxing rule for swarm algorithms. Congress on Evolutionary Computation, + * Oregon, USA, 2004 + */ + +package net.adaptivebox.goodness; + +import net.adaptivebox.global.IUpdateCycleEngine; +import net.adaptivebox.knowledge.Library; + +public class ACRComparator implements IGoodnessCompareEngine, IUpdateCycleEngine { + private final Library socialPool; + private double epsilon_t = 0; + + private static final double RU = 0.75; + private static final double RL = 0.25; + private static final double BETAF = 0.618; + private static final double BETAL = 0.618; + private static final double BETAU = 1.382; + + private final double T; + + private static final double TthR = 0.5; + + public ACRComparator(Library lib, int T) { + socialPool = lib; + this.T = T; + + // set the (epsilon_t|t=0) as the maximum CONS value among the SearchPoints in the library + epsilon_t = lib.getExtremalVcon(true); + } + + private static int compare(double data1, double data2) { + if (data1 < data2) + return LESS_THAN; + else if (data1 > data2) + return LARGER_THAN; + else + return EQUAL_TO; + } + + public int compare(double[] fit1, double[] fit2) { + if (Math.max(fit1[0], fit2[0]) <= Math.max(0, epsilon_t)) { // epsilon>0 + return compare(fit1[1], fit2[1]); + } else { + return compare(fit1[0], fit2[0]); + } + } + + public void updateCycle(int t) { + // calculates the ratio + double rn = (double) socialPool.getVconThanNum(epsilon_t) / (double) socialPool.getPopSize(); + + if (t > TthR * T && T != -1) { // Forcing sub-rule + epsilon_t *= BETAF; + } else { // Ratio-keeping sub-rules + if (rn > RU) { + epsilon_t *= BETAL; // Shrink + } + if (rn < RL) { + epsilon_t *= BETAU; // Relax + } + } + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/goodness/BCHComparator.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/goodness/BCHComparator.java new file mode 100644 index 000000000..8140650dd --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/goodness/BCHComparator.java @@ -0,0 +1,46 @@ +/** + * Description: For formation the basic goodness landscape. + * + * Author Create/Modi Note + * Xiaofeng Xie Jun 24, 2003 Created + * Xiaofeng Xie May 11, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + * + * @version 1.0 + * @Since MAOS1.2 + * + * [1] Deb K. An efficient constraint handling method for genetic algorithms. + * Computer Methods in Applied Mechanics and Engineering, 2000, 186(2-4): 311-338 + */ + +package net.adaptivebox.goodness; + +public class BCHComparator implements IGoodnessCompareEngine { + + /* check the magnitude of two array, the frontal is more important */ + private static int compareArray(double[] fit1, double[] fit2) { + for (int i = 0; i < fit1.length; i++) { + if (fit1[i] > fit2[i]) { + return LARGER_THAN; // Large than + } else if (fit1[i] < fit2[i]) { + return LESS_THAN; // Less than + } + } + return IGoodnessCompareEngine.EQUAL_TO; // same + } + + public int compare(double[] fit1, double[] fit2) { + return compareArray(fit1, fit2); + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/goodness/IGoodnessCompareEngine.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/goodness/IGoodnessCompareEngine.java new file mode 100644 index 000000000..17a85993d --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/goodness/IGoodnessCompareEngine.java @@ -0,0 +1,41 @@ +/** + * Description: For comparison of goodness. + * + * Author Create/Modi Note + * Xiaofeng Xie Feb 19, 2004 + * Xiaofeng Xie May 11, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + * + * @version 1.0 + * @Since MAOS1.2 + */ + +package net.adaptivebox.goodness; + +public abstract interface IGoodnessCompareEngine { + int LARGER_THAN = 2; + int EQUAL_TO = 1; + int LESS_THAN = 0; + + /** + * check the magnitude of two IEncodeEngine + * + * LARGER_THAN: goodness1 is worse than goodness2 + * + * LESS_THAN: goodness1 is better than goodness2 + * + * EQUAL_TO : goodness1 is equal to goodness2 + */ + int compare(double[] goodness1, double[] goodness2); +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/knowledge/ILibEngine.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/knowledge/ILibEngine.java new file mode 100644 index 000000000..b4787c30c --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/knowledge/ILibEngine.java @@ -0,0 +1,27 @@ + +/** + * Description: set the library. + * + * Author Create/Modi Note + * Xiaofeng Xie May 14, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + * + * @version 1.1 + * @Since MAOS1.0 + */ +package net.adaptivebox.knowledge; + +public interface ILibEngine { + void setLibrary(Library lib); +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/knowledge/Library.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/knowledge/Library.java new file mode 100644 index 000000000..76e57ac76 --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/knowledge/Library.java @@ -0,0 +1,106 @@ + +/** + * Description: Contains a set of points. + * + * Author Create/Modi Note + * Xiaofeng Xie Mar 7, 2003 + * Xiaofeng Xie May 3, 2003 + * Xiaofeng Xie May 11, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + * + * @version 1.1 + * @Since MAOS1.0 + */ +package net.adaptivebox.knowledge; + +import net.adaptivebox.global.BasicBound; +import net.adaptivebox.global.RandomGenerator; +import net.adaptivebox.goodness.IGoodnessCompareEngine; +import net.adaptivebox.problem.ProblemEncoder; + +public class Library { + private final SearchPoint[] libPoints; + private int gIndex = -1; + + public Library(int number, ProblemEncoder problemEncoder) { + libPoints = new SearchPoint[number]; + for (int i = 0; i < number; i++) { + libPoints[i] = problemEncoder.getEncodedSearchPoint(); + } + } + + public SearchPoint getGbest() { + return getSelectedPoint(gIndex); + } + + public void refreshGbest(IGoodnessCompareEngine qualityComparator) { + gIndex = tournamentSelection(qualityComparator, getPopSize() - 1, true); + } + + public int getPopSize() { + return libPoints.length; + } + + public SearchPoint getSelectedPoint(int index) { + return libPoints[index]; + } + + public SearchPoint getRandomPoint() { + return libPoints[RandomGenerator.intRangeRandom(0, libPoints.length - 1)]; + } + + public static boolean replace(IGoodnessCompareEngine comparator, SearchPoint outPoint, + SearchPoint tobeReplacedPoint) { + boolean isBetter = false; + if (comparator.compare(outPoint.getEncodeInfo(), + tobeReplacedPoint.getEncodeInfo()) < IGoodnessCompareEngine.LARGER_THAN) { + tobeReplacedPoint.importPoint(outPoint); + isBetter = true; + } + return isBetter; + } + + public int tournamentSelection(IGoodnessCompareEngine comparator, int times, boolean isBetter) { + int[] indices = RandomGenerator.randomSelection(getPopSize(), times); + int currentIndex = indices[0]; + for (int i = 1; i < indices.length; i++) { + int compareValue = comparator.compare(libPoints[indices[i]].getEncodeInfo(), + libPoints[currentIndex].getEncodeInfo()); + if (isBetter == (compareValue < IGoodnessCompareEngine.LARGER_THAN)) { + currentIndex = indices[i]; + } + } + return currentIndex; + } + + public double getExtremalVcon(boolean isMAX) { + double val = BasicBound.MINDOUBLE; + for (int i = 0; i < libPoints.length; i++) { + if (libPoints[i].getEncodeInfo()[0] > val == isMAX) { + val = libPoints[i].getEncodeInfo()[0]; + } + } + return val; + } + + public int getVconThanNum(double allowedCons) { + int num = 0; + for (int i = 0; i < libPoints.length; i++) { + if (libPoints[i].getEncodeInfo()[0] <= allowedCons) { + num++; + } + } + return num; + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/knowledge/SearchPoint.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/knowledge/SearchPoint.java new file mode 100644 index 000000000..df13efc74 --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/knowledge/SearchPoint.java @@ -0,0 +1,70 @@ +/** + * Description: provide the location and encoded goodness information + * + * Author Create/Modi Note + * Xiaofeng Xie Mar 1, 2003 + * Xiaofeng Xie May 11, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + */ +package net.adaptivebox.knowledge; + +import net.adaptivebox.encode.IEncodeEngine; +import net.adaptivebox.global.BasicBound; +import net.adaptivebox.space.BasicPoint; + +public class SearchPoint extends BasicPoint implements IEncodeEngine { + // store the encode information for goodness evaluation + // encodeInfo[0]: the sum of constraints (if it equals to 0, then be a feasible point) + // encodeInfo[1]: the value of objective function + private final double[] encodeInfo = new double[2]; + private double objectiveValue; + + public SearchPoint(int dim) { + super(dim); + for (int i = 0; i < encodeInfo.length; i++) { + encodeInfo[i] = BasicBound.MAXDOUBLE; + } + } + + public double[] getEncodeInfo() { + return encodeInfo; + } + + private void importEncodeInfo(double[] info) { + System.arraycopy(info, 0, encodeInfo, 0, encodeInfo.length); + } + + private void importEncodeInfo(IEncodeEngine point) { + importEncodeInfo(point.getEncodeInfo()); + } + + // Replace self by given point + public void importPoint(SearchPoint point) { + importLocation(point); + importEncodeInfo(point); + setObjectiveValue(point.getObjectiveValue()); + } + + public double getObjectiveValue() { + return objectiveValue; + } + + public void setObjectiveValue(double objectiveValue) { + this.objectiveValue = objectiveValue; + } + + public boolean isFeasible() { + return encodeInfo[0] == 0; // no constraint violations + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/problem/ProblemEncoder.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/problem/ProblemEncoder.java new file mode 100644 index 000000000..674d27542 --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/problem/ProblemEncoder.java @@ -0,0 +1,109 @@ +/** + * Description: Encodes the specified problem into encoded information for + * forming the goodness landscape. + * + * Author Create/Modi Note + * Xiaofeng Xie May 31, 2000 + * Xiaofeng Xie Sep. 19, 2002 + * Xiaofeng Xie Mar. 01, 2003 + * Xiaofeng Xie May 11, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + * + * @version 1.0 + * @Since MAOS1.0 + */ + +package net.adaptivebox.problem; + +import net.adaptivebox.encode.EvalElement; +import net.adaptivebox.encode.EvalStruct; +import net.adaptivebox.global.BasicBound; +import net.adaptivebox.knowledge.SearchPoint; +import net.adaptivebox.space.DesignDim; +import net.adaptivebox.space.DesignSpace; + +public abstract class ProblemEncoder { + // Store the calculated results for the responses + private final double[] tempResponseSet; // temp values + private final double[] tempLocation; // temp values + + // the search space (S) + private final DesignSpace designSpace; + + // For evaluate the response vector into encoded vector double[2] + private final EvalStruct evalStruct; + + protected ProblemEncoder(int paramNum, int targetNum) throws Exception { + designSpace = new DesignSpace(paramNum); + evalStruct = new EvalStruct(targetNum); + tempLocation = new double[paramNum]; + tempResponseSet = new double[targetNum]; + } + + public DesignSpace getDesignSpace() { + return designSpace; + } + + // set the default information for each dimension of search space (S) + protected void setDefaultXAt(int i, double min, double max, double grain) { + DesignDim dd = new DesignDim(); + dd.grain = grain; + dd.paramBound = new BasicBound(min, max); + designSpace.setElemAt(dd, i); + } + + // set the default information for evaluation each response + protected void setDefaultYAt(int i, double min, double max) { + EvalElement ee = new EvalElement(); + ee.targetBound = new BasicBound(min, max); + evalStruct.setElemAt(ee, i); + } + + // get a fresh point + public SearchPoint getFreshSearchPoint() { + return new SearchPoint(designSpace.getDimension()); + } + + // get an encoded point + public SearchPoint getEncodedSearchPoint() { + SearchPoint point = getFreshSearchPoint(); + designSpace.initializeGene(point.getLocation()); + evaluate(point); + return point; + } + + // evaluate the point into encoded information + public void evaluate(SearchPoint point) { + // copy to temp point + System.arraycopy(point.getLocation(), 0, this.tempLocation, 0, tempLocation.length); + + // mapping the temp point to original search space S + designSpace.getMappingPoint(tempLocation); + + // calculate based on the temp point + calcTargets(tempResponseSet, tempLocation); + evalStruct.evaluate(point.getEncodeInfo(), tempResponseSet); + point.setObjectiveValue(tempResponseSet[0]); + } + + // calculate each response, must be implemented + abstract protected double calcTargetAt(int index, double[] VX); + + // calculate all the responses VY[] based on given point VX[] + private void calcTargets(double[] VY, double[] VX) { + for (int i = 0; i < VY.length; i++) { + VY[i] = calcTargetAt(i, VX); + } + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/sco/SCAgent.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/sco/SCAgent.java new file mode 100644 index 000000000..a09d0dcfd --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/sco/SCAgent.java @@ -0,0 +1,143 @@ +package net.adaptivebox.sco; + +/** + * Description: The description of social cognitive agent. + * + * @Information source: a) external library (L); b) the own memory: a point that + * generated in the last learning cycle + * + * @Coefficients: TaoB and TaoW + * + * @ Author Create/Modi Note + * Xiaofeng Xie Mar 11, 2003 + * Xiaofeng Xie May 11, 2004 + * Xiaofeng Xie May 20, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + * + * @version 1.0 + * @Since MAOS1.0 + * + * @References: + * [1] Xie X F, Zhang W J. Solving engineering design problems by social cognitive + * optimization. Genetic and Evolutionary Computation Conference, 2004: 261-262 + */ + +import net.adaptivebox.problem.ProblemEncoder; +import net.adaptivebox.space.DesignSpace; +import net.adaptivebox.space.ILocationEngine; +import net.adaptivebox.global.RandomGenerator; +import net.adaptivebox.goodness.IGoodnessCompareEngine; +import net.adaptivebox.knowledge.Library; +import net.adaptivebox.knowledge.SearchPoint; + +public class SCAgent { + + // Describes the problem to be solved (encode the point into intermediate information) + private ProblemEncoder problemEncoder; + + // Forms the goodness landscape + private IGoodnessCompareEngine specComparator; + + // the coefficients of SCAgent + private static final int TaoB = 2; + + // The early version set TaoW as the size of external library (NL), but 4 is often enough + private static final int TaoW = 4; + + // The referred external library + private Library externalLib; + + // store the point that generated in current learning cycle + private SearchPoint trailPoint; + + // the own memory: store the point that generated in last learning cycle + private SearchPoint pcurrent_t; + + public void setExternalLib(Library lib) { + externalLib = lib; + } + + public void setProblemEncoder(ProblemEncoder encoder) { + problemEncoder = encoder; + trailPoint = problemEncoder.getFreshSearchPoint(); + pcurrent_t = problemEncoder.getEncodedSearchPoint(); + } + + public void setSpecComparator(IGoodnessCompareEngine comparer) { + specComparator = comparer; + } + + public SearchPoint generatePoint() { + // generate a new point + generatePoint(trailPoint); + + // evaluate the generated point + problemEncoder.evaluate(trailPoint); + return trailPoint; + } + + private void generatePoint(ILocationEngine tempPoint) { + SearchPoint Xmodel, Xrefer, libBPoint; + + // choose Selects a better point (libBPoint) from externalLib (L) based + // on tournament selection + int xb = externalLib.tournamentSelection(specComparator, TaoB, true); + libBPoint = externalLib.getSelectedPoint(xb); + + // Compares pcurrent_t with libBPoint + // The better one becomes model point (Xmodel) + // The worse one becomes refer point (Xrefer) + if (specComparator.compare(pcurrent_t.getEncodeInfo(), + libBPoint.getEncodeInfo()) == IGoodnessCompareEngine.LARGER_THAN) { + Xmodel = libBPoint; + Xrefer = pcurrent_t; + } else { + Xmodel = pcurrent_t; + Xrefer = libBPoint; + } + + // observational learning: generates a new point near the model point, which + // the variation range is decided by the difference of Xmodel and Xrefer + inferPoint(tempPoint, Xmodel, Xrefer, problemEncoder.getDesignSpace()); + } + + // 1. Update the current point into the external library + // 2. Replace the current point by the generated point + public void updateInfo() { + // Selects a bad point kw from TaoW points in Library + int xw = externalLib.tournamentSelection(specComparator, TaoW, false); + + // Replaces kw with pcurrent_t + externalLib.getSelectedPoint(xw).importPoint(pcurrent_t); + + // Replaces pcurrent_t (x(t)) with trailPoint (x(t+1)) + pcurrent_t.importPoint(trailPoint); + } + + // 1---model point, 2---refer point + private boolean inferPoint(ILocationEngine newPoint, ILocationEngine point1, ILocationEngine point2, + DesignSpace space) { + double[] newLoc = newPoint.getLocation(); + double[] real1 = point1.getLocation(); + double[] real2 = point2.getLocation(); + + for (int i = 0; i < newLoc.length; i++) { + newLoc[i] = real1[i] * 2 - real2[i]; + // boundary handling + newLoc[i] = space.boundAdjustAt(newLoc[i], i); + newLoc[i] = RandomGenerator.doubleRangeRandom(newLoc[i], real2[i]); + } + return true; + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/BasicPoint.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/BasicPoint.java new file mode 100644 index 000000000..9f6c2ec01 --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/BasicPoint.java @@ -0,0 +1,42 @@ +/** + * Description: provide the location information of a point + * + * Author Create/Modi Note + * Xiaofeng Xie Mar 1, 2003 + * Xiaofeng Xie May 11, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + */ + +package net.adaptivebox.space; + +public class BasicPoint implements ILocationEngine { + // store the location information in the search space (S) + private final double[] location; + + public BasicPoint(int dim) { + location = new double[dim]; + } + + public double[] getLocation() { + return location; + } + + public void importLocation(double[] pointLoc) { + System.arraycopy(pointLoc, 0, location, 0, pointLoc.length); + } + + public void importLocation(ILocationEngine point) { + importLocation(point.getLocation()); + } +}
\ No newline at end of file diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/DesignDim.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/DesignDim.java new file mode 100644 index 000000000..f8f283bf1 --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/DesignDim.java @@ -0,0 +1,45 @@ +/** + * Description: provide the information for goodness evaluation of a target + * + * Author Create/Modi Note + * Xiaofeng Xie Mar 1, 2003 + * Xiaofeng Xie May 3, 2004 Add grain value + * Xiaofeng Xie May 11, 2004 Add crowd distance + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + */ + +package net.adaptivebox.space; + +import net.adaptivebox.global.BasicBound; + +public class DesignDim { + // To discrete space with the given step. For example, for an integer variable, + // The grain value can be set as 1. + public double grain = 0; + public BasicBound paramBound = new BasicBound(); // the range of a parameter + + public boolean isDiscrete() { + return grain != 0; + } + + public double getGrainedValue(double value) { + if (grain == 0) { + return value; + } else if (grain > 0) { + return paramBound.minValue + Math.rint((value - paramBound.minValue) / grain) * grain; + } else { + return paramBound.maxValue - Math.rint((paramBound.maxValue - value) / grain) * grain; + } + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/DesignSpace.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/DesignSpace.java new file mode 100644 index 000000000..7d9307936 --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/DesignSpace.java @@ -0,0 +1,73 @@ +/** + * Description: provide the information for the search space (S) + * + * Author Create/Modi Note + * Xiaofeng Xie Mar 2, 2003 + * Xiaofeng Xie May 11, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + * + * @References: + * [1] Zhang W J, Xie X F, Bi D C. Handling boundary constraints for numerical + * optimization by particle swarm flying in periodic search space. Congress + * on Evolutionary Computation, Oregon, USA, 2004 + * especially for particle swarm agent + */ + +package net.adaptivebox.space; + +public class DesignSpace { + // The information of all the dimension + private DesignDim[] dimProps; + + public DesignSpace(int dim) { + dimProps = new DesignDim[dim]; + } + + public void setElemAt(DesignDim elem, int index) { + dimProps[index] = elem; + } + + public int getDimension() { + if (dimProps == null) { + return -1; + } + return dimProps.length; + } + + public double boundAdjustAt(double val, int dim) { + return dimProps[dim].paramBound.boundAdjust(val); + } + + public void mutationAt(double[] location, int i) { + location[i] = dimProps[i].paramBound.getRandomValue(); + } + + public double getMagnitudeIn(int dimensionIndex) { + return dimProps[dimensionIndex].paramBound.getLength(); + } + + public void initializeGene(double[] tempX) { + for (int i = 0; i < tempX.length; i++) + tempX[i] = dimProps[i].paramBound.getRandomValue(); // Global.RandomGenerator.doubleRangeRandom(9.8, 10); + } + + public void getMappingPoint(double[] point) { + for (int i = 0; i < getDimension(); i++) { + point[i] = dimProps[i].paramBound.annulusAdjust(point[i]); + if (dimProps[i].isDiscrete()) { + point[i] = dimProps[i].getGrainedValue(point[i]); + } + } + } +} diff --git a/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/ILocationEngine.java b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/ILocationEngine.java new file mode 100644 index 000000000..6b839df6e --- /dev/null +++ b/nlpsolver/ThirdParty/EvolutionarySolver/src/net/adaptivebox/space/ILocationEngine.java @@ -0,0 +1,25 @@ +/** + * Description: provide the information for location + * + * Author Create/Modi Note + * Xiaofeng Xie May 3, 2003 + * Xiaofeng Xie May 11, 2004 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Please acknowledge the author(s) if you use this code in any way. + */ + +package net.adaptivebox.space; + +public interface ILocationEngine { + double[] getLocation(); +} diff --git a/nlpsolver/help/en/com.sun.star.comp.Calc.NLPSolver/Options.xhp b/nlpsolver/help/en/com.sun.star.comp.Calc.NLPSolver/Options.xhp new file mode 100644 index 000000000..91e3d68f2 --- /dev/null +++ b/nlpsolver/help/en/com.sun.star.comp.Calc.NLPSolver/Options.xhp @@ -0,0 +1,194 @@ +<?xml version="1.0" encoding="UTF-8"?> +<helpdocument version="1.0"> + +<!-- +*********************************************************************** + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************ + --> + + +<meta> + <topic id="nlpsolveroptions" indexer="include"> + <title xml-lang="en-US" id="tit">Options</title> + <filename>/com.sun.star.comp.Calc.NLPSolver/Options.xhp</filename> + </topic> + </meta> + <body> +<bookmark xml-lang="en-US" branch="index" id="bm_id0503200917110375_scalc"><bookmark_value>Solver for Nonlinear Problems;Options</bookmark_value> +</bookmark> +<paragraph xml-lang="en-US" id="hd_id0503200917103593" role="heading" level="1" l10n="NEW">General Options</paragraph> + <table id=""> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103780" role="tablecontent" l10n="NEW">Size of Swarm</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103723" role="tablecontent" l10n="NEW">… defines the number of individuals to participate in the learning process. Each individual finds its own solutions and contributes to the overall knowledge.</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103771" role="tablecontent" l10n="NEW">Learning Cycles</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103720" role="tablecontent" l10n="NEW">… defines the number of iterations, the algorithm should take. In each iteration, all individuals make a guess on the best solution and share their knowledge.</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103732" role="tablecontent" l10n="NEW">Variable Bounds Guessing</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id050320091710378" role="tablecontent" l10n="NEW">If enabled (default), the algorithm tries to find variable bounds by looking at the starting values.</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103794" role="tablecontent" l10n="NEW">Variable Bounds Threshold</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103710" role="tablecontent" l10n="NEW">When guessing variable bounds, this threshold specifies, how the initial values are shifted to build the bounds. For an example how these values are calculated, please refer to the Manual in the Wiki.</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103740" role="tablecontent" l10n="NEW">Use ACR Comparator</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103766" role="tablecontent" l10n="NEW">If <emph>disabled</emph> (default), the BCH Comparator is used. It compares two individuals by first looking at their constraint violations and only if those are equal, it measures their current solution.</paragraph> + <paragraph xml-lang="en-US" id="par_id0503200917103744" role="tablecontent" l10n="NEW">If <emph>enabled</emph>, the ACR Comparator is used. It compares two individuals dependent on the current iteration and measures their goodness with knowledge about the libraries worst known solutions (in regard to their constraint violations).</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103792" role="tablecontent" l10n="NEW">Use Random Starting Point</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103790" role="tablecontent" l10n="NEW">If <emph>enabled</emph>, the library is simply filled up with randomly chosen points.</paragraph> + <paragraph xml-lang="en-US" id="par_id0503200917103765" role="tablecontent" l10n="NEW">If <emph>disabled</emph>, the currently present values (as given by the user) are inserted in the library as reference point.</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0504200917103794" role="tablecontent" l10n="NEW">Stagnation Limit</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id050320091710377" role="tablecontent" l10n="NEW">If this number of individuals found solutions within a close range, the iteration is stopped and the best of these values is chosen as optimal.</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103762" role="tablecontent" l10n="NEW">Stagnation Tolerance</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103834" role="tablecontent" l10n="NEW">Defines in what range solutions are considered “similar”.</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103891" role="tablecontent" l10n="NEW">Show Enhanced Solver Status</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0503200917103832" role="tablecontent" l10n="NEW">If <emph>enabled</emph>, an additional dialog is shown during the solving process which gives information about the current progress, the level of stagnation, the currently best known solution as well as the possibility, to stop or resume the solver.</paragraph> + </tablecell> + </tablerow> + </table> + + <paragraph xml-lang="en-US" id="hd_id0603200910392151" role="heading" level="2" l10n="NEW">DEPS-specific Options</paragraph> + <table id=""> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0603200910394232" role="tablecontent" l10n="NEW">Agent Switch Rate</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0603200910394248" role="tablecontent" l10n="NEW">Specifies the probability for an individual to choose the Differential Evolution strategy.</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0603200910394277" role="tablecontent" l10n="NEW">DE: Crossover Probability</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0603200910394280" role="tablecontent" l10n="NEW">… defines the probability of the individual being combined with the globally best point. If crossover is not used, the point is assembled from the own memory of the individual.</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0603200910394216" role="tablecontent" l10n="NEW">DE: Scaling Factor</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id060320091039424" role="tablecontent" l10n="NEW">During crossover, the scaling factor decides about the “speed” of movement.</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id060320091039421" role="tablecontent" l10n="NEW">PS: Constriction Coefficient</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0603200910394225" role="tablecontent" l10n="NEW">… defines the speed at which the particles/individuals move towards each other.</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0603200910394222" role="tablecontent" l10n="NEW">PS: Cognitive Constant</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0603200910394212" role="tablecontent" l10n="NEW">… sets the importance of the own memory (in particular the best reached point so far).</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0603200910394292" role="tablecontent" l10n="NEW">PS: Social Constant</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0603200910394284" role="tablecontent" l10n="NEW">… sets the importance of the global best point between all particles/individuals.</paragraph> + </tablecell> + </tablerow> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id060320091039425" role="tablecontent" l10n="NEW">PS: Mutation Probability</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0603200910394272" role="tablecontent" l10n="NEW">… defines the probability, that instead of moving a component of the particle towards the best point, it randomly chooses a new value from the valid range for that variable.</paragraph> + </tablecell> + </tablerow> + </table> + + <paragraph xml-lang="en-US" id="hd_id0603200910401383" role="heading" level="2" l10n="NEW">SCO-specific Options</paragraph> + <table id=""> + <tablerow> + <tablecell> + <paragraph xml-lang="en-US" id="par_id0603200910401382" role="tablecontent" l10n="NEW">Size of Library</paragraph> + </tablecell> + <tablecell> + <paragraph xml-lang="en-US" id="par_id060320091040136" role="tablecontent" l10n="NEW">… defines the amount of information to store in the public library. Each individual stores knowledge there and asks for information.</paragraph> + </tablecell> + </tablerow> + </table> + + </body> +</helpdocument> diff --git a/nlpsolver/help/en/com.sun.star.comp.Calc.NLPSolver/Usage.xhp b/nlpsolver/help/en/com.sun.star.comp.Calc.NLPSolver/Usage.xhp new file mode 100644 index 000000000..d4bf41607 --- /dev/null +++ b/nlpsolver/help/en/com.sun.star.comp.Calc.NLPSolver/Usage.xhp @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<helpdocument version="1.0"> + +<!-- +*********************************************************************** + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************ + --> + + +<meta> + <topic id="nlpsolverusage" indexer="include"> + <title xml-lang="en-US" id="tit">Usage</title> + <filename>/com.sun.star.comp.Calc.NLPSolver/Usage.xhp</filename> + </topic> + </meta> + <body> +<bookmark xml-lang="en-US" branch="index" id="bm_id0603200910434044_scalc"><bookmark_value>Solver for Nonlinear Problems;Usage</bookmark_value> +</bookmark> +<paragraph xml-lang="en-US" id="hd_id0603200910430882" role="heading" level="1" l10n="NEW">Usage</paragraph> + <paragraph xml-lang="en-US" id="par_id0603200910430845" role="paragraph">Regardless whether you use DEPS or SCO, you start by going to <menuitem>Tools - Solver</menuitem> and set the Cell to be optimized, the direction to go (minimization, maximization) and the cells to be modified to reach the goal. Then you go to the Options and specify the solver to be used and if necessary adjust the according <link href="com.sun.star.comp.Calc.NLPSolver/Options.xhp">parameters</link>.</paragraph> + <paragraph xml-lang="en-US" id="par_id0603200910430821" role="paragraph" l10n="NEW">There is also a list of constraints you can use to restrict the possible range of solutions or to penalize certain conditions. However, in case of the evolutionary solvers DEPS and SCO, these constraints are also used to specify bounds on the variables of the problem. Due to the random nature of the algorithms, it is <emph>highly recommended</emph> to do so and give upper (and in case "Assume Non-Negative Variables" is turned off also lower) bounds for all variables. They don't have to be near the actual solution (which is probably unknown) but should give a rough indication of the expected size (0 ≤ var ≤ 1 or maybe -1000000 ≤ var ≤ 1000000).</paragraph> + <paragraph xml-lang="en-US" id="par_id0603200910430873" role="paragraph" l10n="NEW">Bounds are specified by selecting one or more variables (as range) on the left side and entering a numerical value (not a cell or a formula) on the right side. That way you can also choose one or more variables to be <emph>Integer</emph> or <emph>Binary</emph> only.</paragraph> + </body> +</helpdocument>
\ No newline at end of file diff --git a/nlpsolver/help/en/com.sun.star.comp.Calc.NLPSolver/help.tree b/nlpsolver/help/en/com.sun.star.comp.Calc.NLPSolver/help.tree new file mode 100644 index 000000000..7ccf4d6c2 --- /dev/null +++ b/nlpsolver/help/en/com.sun.star.comp.Calc.NLPSolver/help.tree @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * +--> + +<tree_view> +<help_section application="scalc" id="08" title="Solver for Nonlinear Problems"> + <node id="0816" title="Solver for Nonlinear Problems"> + <topic id="help/com.sun.star.comp.Calc.NLPSolver/Usage.xhp">Usage</topic> + <topic id="help/com.sun.star.comp.Calc.NLPSolver/Options.xhp">Options</topic> + </node> +</help_section> +</tree_view> diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/BaseEvolutionarySolver.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/BaseEvolutionarySolver.java new file mode 100644 index 000000000..0c402e87c --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/BaseEvolutionarySolver.java @@ -0,0 +1,392 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver; + +import com.sun.star.comp.Calc.NLPSolver.dialogs.DummyEvolutionarySolverStatusDialog; +import com.sun.star.comp.Calc.NLPSolver.dialogs.EvolutionarySolverStatusUno; +import com.sun.star.comp.Calc.NLPSolver.dialogs.IEvolutionarySolverStatusDialog; +import com.sun.star.sheet.SolverConstraintOperator; +import com.sun.star.uno.XComponentContext; +import java.util.ArrayList; +import net.adaptivebox.global.BasicBound; +import net.adaptivebox.global.RandomGenerator; +import net.adaptivebox.goodness.ACRComparator; +import net.adaptivebox.goodness.BCHComparator; +import net.adaptivebox.goodness.IGoodnessCompareEngine; +import net.adaptivebox.knowledge.Library; +import net.adaptivebox.knowledge.SearchPoint; +import net.adaptivebox.problem.ProblemEncoder; + +public abstract class BaseEvolutionarySolver extends BaseNLPSolver { + + public BaseEvolutionarySolver(XComponentContext xContext, String name) { + super(xContext, name); + + registerProperty(m_swarmSize); + registerProperty(m_learningCycles); + registerProperty(m_guessVariableRange); + registerProperty(m_variableRangeThreshold); + registerProperty(m_useACRComperator); + + registerProperty(m_useRandomStartingPoint); + registerProperty(m_useStrongerPRNG); + + registerProperty(m_required); + registerProperty(m_tolerance); + + registerProperty(m_enhancedSolverStatus); + } + + private static class Variable { + private final CellMap CellMap; + private final int OriginalVariable; + private double MinValue; + private double MaxValue; + private double Granularity; + + private Variable(CellMap cellMap, int originalVariable) { + this.CellMap = cellMap; + this.OriginalVariable = originalVariable; + this.MinValue = BasicBound.MINDOUBLE; + this.MaxValue = BasicBound.MAXDOUBLE; + this.Granularity = 0.0; + } + } + + private class CalcProblemEncoder extends ProblemEncoder { + + private final ArrayList<Variable> m_variables; + private final ArrayList<ExtSolverConstraint> m_constraints; + + private CalcProblemEncoder(ArrayList<Variable> variables, + ArrayList<ExtSolverConstraint> constraints) throws Exception { + //m_variableCount variables to solve, target function + constraints to match + super(variables.size(), 1 + constraints.size()); + + m_variables = variables; + m_constraints = constraints; + + double objective = m_maximize ? BasicBound.MAXDOUBLE : BasicBound.MINDOUBLE; + setDefaultYAt(0, objective, objective); + + for (int i = 0; i < constraints.size(); i++) { + ExtSolverConstraint constraint = constraints.get(i); + + switch (constraint.Operator.getValue()) { + case SolverConstraintOperator.EQUAL_value: + setDefaultYAt(i + 1, constraint.Data, constraint.Data); + break; + case SolverConstraintOperator.GREATER_EQUAL_value: + setDefaultYAt(i + 1, constraint.Data, BasicBound.MAXDOUBLE); + break; + case SolverConstraintOperator.LESS_EQUAL_value: + setDefaultYAt(i + 1, BasicBound.MINDOUBLE, constraint.Data); + break; + case SolverConstraintOperator.INTEGER_value: + setDefaultYAt(i + 1, BasicBound.MINDOUBLE, BasicBound.MAXDOUBLE); + break; + case SolverConstraintOperator.BINARY_value: + setDefaultYAt(i + 1, 0, 1); + break; + } + } + + for (int i = 0; i < m_variables.size(); i++) { + Variable variable = m_variables.get(i); + setDefaultXAt(i, variable.MinValue, variable.MaxValue, variable.Granularity); + } + } + + @Override + protected double calcTargetAt(int index, double[] VX) { + if (index == 0) { + //calcTargetAt is called in a loop over all functions, so it's + //enough to set the variables in the first step only + for (int i = 0; i < m_variables.size(); i++) { + CellMap variableMap = m_variables.get(i).CellMap; + m_variableData[variableMap.Range][variableMap.Row][variableMap.Col] = VX[i]; + } + for (int i = 0; i < m_cellRangeCount; i++) + m_cellRangeData[i].setData(m_variableData[i]); + + //errors are punished + if (m_objectiveCell.getError() != 0) + return m_maximize ? BasicBound.MINDOUBLE : BasicBound.MAXDOUBLE; + + double result = m_objectiveCell.getValue(); + + if (result >= m_toleratedMin && result <= m_toleratedMax && checkConstraints()) + m_toleratedCount++; + + return result; + } else + return m_constraints.get(index - 1).getLeftValue(); + } + + } + + protected CalcProblemEncoder m_problemEncoder; + protected Library m_library; + protected IGoodnessCompareEngine m_envCompareEngine; + protected IGoodnessCompareEngine m_specCompareEngine; + protected SearchPoint m_totalBestPoint; + + protected int m_toleratedCount; + protected double m_toleratedMin; + protected double m_toleratedMax; + + private final ArrayList<Variable> m_variables = new ArrayList<Variable>(); + + //properties + protected PropertyInfo<Integer> m_swarmSize = new PropertyInfo<Integer>("SwarmSize", 70, "Size of Swarm"); + protected PropertyInfo<Integer> m_librarySize = new PropertyInfo<Integer>("LibrarySize", 210, "Size of Library"); + protected PropertyInfo<Integer> m_learningCycles = new PropertyInfo<Integer>("LearningCycles", 2000, "Learning Cycles"); + private final PropertyInfo<Boolean> m_guessVariableRange = new PropertyInfo<Boolean>("GuessVariableRange", true, "Variable Bounds Guessing"); + private final PropertyInfo<Double> m_variableRangeThreshold = new PropertyInfo<Double>("VariableRangeThreshold", 3.0, "Variable Bounds Threshold (when guessing)"); //to approximate the variable bounds + private final PropertyInfo<Boolean> m_useACRComperator = new PropertyInfo<Boolean>("UseACRComparator", false, "Use ACR Comparator (instead of BCH)"); + private final PropertyInfo<Boolean> m_useRandomStartingPoint = new PropertyInfo<Boolean>("UseRandomStartingPoint", false, "Use Random starting point"); + private final PropertyInfo<Boolean> m_useStrongerPRNG = new PropertyInfo<Boolean>("UseStrongerPRNG", false, "Use a stronger random generator (slower)"); + protected PropertyInfo<Integer> m_required = new PropertyInfo<Integer>("StagnationLimit", 70, "Stagnation Limit"); + protected PropertyInfo<Double> m_tolerance = new PropertyInfo<Double>("Tolerance", 1e-6, "Stagnation Tolerance"); + private final PropertyInfo<Boolean> m_enhancedSolverStatus = new PropertyInfo<Boolean>("EnhancedSolverStatus", true, "Show enhanced solver status"); + + protected IEvolutionarySolverStatusDialog m_solverStatusDialog; + + private void prepareVariables(double[][] variableBounds) { + m_variables.clear(); + for (int i = 0; i < m_variableCount; i++) { + Variable var = new Variable(m_variableMap[i], i); + var.MinValue = variableBounds[i][0]; + var.MaxValue = variableBounds[i][1]; + var.Granularity = variableBounds[i][2]; + m_variables.add(var); + } + } + + @Override + protected void initializeSolve() { + super.initializeSolve(); + + if (m_variableCount == 0) + { + return; + } + if (m_enhancedSolverStatus.getValue()) + m_solverStatusDialog = new EvolutionarySolverStatusUno(m_xContext); + else + m_solverStatusDialog = new DummyEvolutionarySolverStatusDialog(); + + //Init: + double[][] variableBounds = new double[m_variableCount][3]; + //approximate variable bounds + for (int i = 0; i < m_variableCount; i++) { + if (m_guessVariableRange.getValue()) { + double value = m_variableCells[i].getValue(); + + //0 is a bad starting point, so just pick some other. + //That is certainly not optimal but the user should specify + //bounds or at least a good starting point anyway. + if (value == 0.0) + value = 1000; + + double b1; + double b2; + + if (m_assumeNonNegative.getValue()) { + b1 = 0; + b2 = value + value * 2 * m_variableRangeThreshold.getValue(); + } else { + b1 = value + value * m_variableRangeThreshold.getValue(); + b2 = value - value * m_variableRangeThreshold.getValue(); + } + + variableBounds[i][0] = Math.min(b1, b2); + variableBounds[i][1] = Math.max(b1, b2); + } else { + //that almost always leads to bad or no solutions at all + if (m_assumeNonNegative.getValue()) + variableBounds[i][0] = 0.0; + else + variableBounds[i][0] = BasicBound.MINDOUBLE; + variableBounds[i][1] = BasicBound.MAXDOUBLE; + } + variableBounds[i][2] = 0.0; + } + + //prepare constraints and parse them for variable bounds + ArrayList<ExtSolverConstraint> constraints = new ArrayList<ExtSolverConstraint>(); + for (int i = 0; i < m_constraintCount; i++) { + Double doubleValue; + + if (m_extConstraints[i].Right != null) + doubleValue = null; + else + doubleValue = m_extConstraints[i].Data; + + boolean isVariableBound = false; + //If it refers to a cell, it has to be treated as constraint, not as + //bound. + if (m_extConstraints[i].Right == null) { + for (int j = 0; j < m_variableCount && !isVariableBound; j++) { + if (m_constraints[i].Left.Sheet == super.m_variables[j].Sheet && + m_constraints[i].Left.Column == super.m_variables[j].Column && + m_constraints[i].Left.Row == super.m_variables[j].Row) { + isVariableBound = true; + + //Therefore we try to use it as bounds for this variable. + + switch (m_extConstraints[i].Operator.getValue()) { + case SolverConstraintOperator.EQUAL_value: + if (doubleValue == null) + continue; + variableBounds[j][0] = doubleValue; + variableBounds[j][1] = doubleValue; + break; + case SolverConstraintOperator.GREATER_EQUAL_value: + if (doubleValue == null) + continue; + variableBounds[j][0] = doubleValue; + break; + case SolverConstraintOperator.LESS_EQUAL_value: + if (doubleValue == null) + continue; + variableBounds[j][1] = doubleValue; + break; + case SolverConstraintOperator.INTEGER_value: + variableBounds[j][2] = 1.0; + break; + case SolverConstraintOperator.BINARY_value: + variableBounds[j][0] = 0.0; + variableBounds[j][1] = 1.0; + variableBounds[j][2] = 1.0; + break; + default: + //If it is neither <=, nor =, nor >=, we treat + //it as normal constraint. + isVariableBound = false; + } + } + } + } + + if (!isVariableBound) { + constraints.add(m_extConstraints[i]); + } + } + + prepareVariables(variableBounds); + + try { + m_problemEncoder = new CalcProblemEncoder(m_variables, constraints); + } catch (Exception e) { + m_problemEncoder = null; + return; + } + + m_library = new Library(m_librarySize.getValue(), m_problemEncoder); + + if (m_useRandomStartingPoint.getValue()) { + m_totalBestPoint = m_problemEncoder.getEncodedSearchPoint(); + } else { + m_totalBestPoint = m_problemEncoder.getFreshSearchPoint(); + double[] currentValues = new double[m_variables.size()]; + for (int i = 0; i < m_variables.size(); i++) + currentValues[i] = m_currentParameters[m_variables.get(i).OriginalVariable]; + m_totalBestPoint.importLocation(currentValues); + m_problemEncoder.evaluate(m_totalBestPoint); + } + //input the chosen point into the library as reference for the individuals + m_library.getSelectedPoint(0).importPoint(m_totalBestPoint); + + m_solverStatusDialog.setBestSolution(m_totalBestPoint.getObjectiveValue(), checkConstraints()); + + m_envCompareEngine = new BCHComparator(); + m_specCompareEngine = m_useACRComperator.getValue() ? new ACRComparator(m_library, m_learningCycles.getValue()) : new BCHComparator(); + + RandomGenerator.useStrongerGenerator( m_useStrongerPRNG.getValue() ); + } + + protected void applySolution() { + double[] location = m_totalBestPoint.getLocation(); + + //make sure, the "Integer" variable type is met + m_problemEncoder.getDesignSpace().getMappingPoint(location); + + //get the function value for our optimal point + for (int i = 0; i < m_variableCount; i++) { + m_variableCells[i].setValue(location[i]); + m_currentParameters[i] = location[i]; + } + m_functionValue = m_objectiveCell.getValue(); + } + + @Override + protected void finalizeSolve() { + applySolution(); + + m_success = (m_objectiveCell.getError() == 0 && checkConstraints()); + + m_solverStatusDialog.setVisible(false); + m_solverStatusDialog.dispose(); + + super.finalizeSolve(); + } + + private boolean checkConstraints() { + boolean result = true; + for (int i = 0; i < m_constraintCount && result; i++) { + if (m_extConstraints[i].Left.getError() == 0) { + double value = m_extConstraints[i].getLeftValue(); + double targetValue = m_extConstraints[i].Data; + + switch (m_extConstraints[i].Operator.getValue()) { + case SolverConstraintOperator.EQUAL_value: + result = value == targetValue; + break; + case SolverConstraintOperator.GREATER_EQUAL_value: + result = value >= targetValue; + break; + case SolverConstraintOperator.LESS_EQUAL_value: + result = value <= targetValue; + break; + case SolverConstraintOperator.INTEGER_value: + result = Math.rint(value) == value; + break; + case SolverConstraintOperator.BINARY_value: + result = (value == 0.0 || value == 1.0); + break; + } + } else { + result = false; + } + } + + return result; + } + +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/BaseNLPSolver.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/BaseNLPSolver.java new file mode 100644 index 000000000..d425e2a4c --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/BaseNLPSolver.java @@ -0,0 +1,551 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver; + +import com.sun.star.awt.XReschedule; +import com.sun.star.beans.Property; +import com.sun.star.beans.PropertyVetoException; +import com.sun.star.beans.UnknownPropertyException; +import com.sun.star.beans.XPropertyChangeListener; +import com.sun.star.beans.XPropertySetInfo; +import com.sun.star.beans.XVetoableChangeListener; +import com.sun.star.chart.XChartDataArray; +import com.sun.star.container.XIndexAccess; +import com.sun.star.document.XEmbeddedObjectSupplier; +import com.sun.star.frame.XModel; +import com.sun.star.lang.IllegalArgumentException; +import com.sun.star.lang.IndexOutOfBoundsException; +import com.sun.star.lang.WrappedTargetException; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.lib.uno.helper.WeakBase; +import com.sun.star.sheet.SolverConstraint; +import com.sun.star.sheet.SolverConstraintOperator; +import com.sun.star.sheet.XSpreadsheet; +import com.sun.star.sheet.XSpreadsheetDocument; +import com.sun.star.sheet.XSpreadsheets; +import com.sun.star.table.CellAddress; +import com.sun.star.table.CellContentType; +import com.sun.star.table.CellRangeAddress; +import com.sun.star.table.XCell; +import com.sun.star.table.XTableChartsSupplier; +import com.sun.star.uno.Exception; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +public abstract class BaseNLPSolver extends WeakBase + implements com.sun.star.lang.XLocalizable, + com.sun.star.sheet.XSolver, + com.sun.star.sheet.XSolverDescription, + com.sun.star.beans.XPropertySet, + com.sun.star.beans.XPropertySetInfo +{ + + protected final XComponentContext m_xContext; + private final String m_name; + + private final ArrayList<PropertyInfo> m_properties = new ArrayList<PropertyInfo>(); + private final HashMap<String, PropertyInfo> m_propertyMap = new HashMap<String, PropertyInfo>(); + + private com.sun.star.lang.Locale m_locale = new com.sun.star.lang.Locale(); + private final ResourceManager resourceManager; + + private CellAddress m_objective; + protected CellAddress[] m_variables; + protected SolverConstraint[] m_constraints; + + public BaseNLPSolver(XComponentContext xContext, String name) { + m_xContext = xContext; + m_name = name; + // init members exposed as XSolver properties through uno bridge + m_objective = new CellAddress(); + m_variables = new CellAddress[0]; + m_constraints = new SolverConstraint[0]; + + XMultiComponentFactory componentFactory = xContext.getServiceManager(); + try { + Object toolkit = componentFactory.createInstanceWithContext("com.sun.star.awt.Toolkit", xContext); + m_xReschedule = UnoRuntime.queryInterface(XReschedule.class, toolkit); + } catch (Exception ex) { + Logger.getLogger(BaseNLPSolver.class.getName()).log(Level.SEVERE, null, ex); + } + + resourceManager = new ResourceManager(xContext, "com.sun.star.comp.Calc.NLPSolver", "/locale", "NLPSolverCommon"); + + registerProperty(m_assumeNonNegative); + } + + protected void registerProperty(PropertyInfo property) { + m_properties.add(property); + m_propertyMap.put(property.getProperty().Name, property); + property.localize(resourceManager); + } + + // com.sun.star.lang.XLocalizable: + public void setLocale(com.sun.star.lang.Locale eLocale) + { + m_locale = eLocale; + } + + public com.sun.star.lang.Locale getLocale() + { + return m_locale; + } + + // com.sun.star.sheet.XSolver: + + private XSpreadsheetDocument m_document; + private XModel m_xModel; + protected XReschedule m_xReschedule; + protected ExtSolverConstraint[] m_extConstraints; + protected boolean m_maximize; + + protected int m_variableCount; + protected int m_constraintCount; + protected int m_cellRangeCount; + protected XCell m_objectiveCell; + protected XCell[] m_variableCells; + protected XChartDataArray[] m_cellRangeData; + protected CellMap[] m_variableMap; + protected double[][][] m_variableData; + + protected double m_functionValue; + protected double[] m_currentParameters; + protected boolean m_success = false; + + public XSpreadsheetDocument getDocument() { + return m_document; + } + + public void setDocument(XSpreadsheetDocument document) { + m_document = document; + m_xModel = UnoRuntime.queryInterface(XModel.class, m_document); + } + + public CellAddress getObjective() { + return m_objective; + } + + public void setObjective(CellAddress objective) { + m_objective = objective; + m_objectiveCell = getCell(objective); + } + + public CellAddress[] getVariables() { + return m_variables; + } + + private static class RowInfo { + private short Sheet; + private int Row; + private int StartCol; + private int EndCol; + + private RowInfo(short sheet, int row) { + Sheet = sheet; + Row = row; + } + + private CellRangeAddress getCellRangeAddress(int lastRow) { + CellRangeAddress result = new CellRangeAddress(); + result.Sheet = Sheet; + result.StartColumn = StartCol; + result.StartRow = Row; + result.EndColumn = EndCol; + result.EndRow = lastRow; + return result; + } + } + + protected static class CellMap { + protected int Range; + protected int Col; + protected int Row; + } + + protected class ExtSolverConstraint { + + public XCell Left; + public SolverConstraintOperator Operator; + public XCell Right; + public double Data; + + private ExtSolverConstraint(XCell left, SolverConstraintOperator operator, Object right) { + this.Left = left; + this.Operator = operator; + this.Right = null; + if (right instanceof Number) { + this.Data = ((Number)right).doubleValue(); + } else if (right instanceof CellAddress) { + XCell cell = getCell((CellAddress)right); + if (cell.getType() == CellContentType.VALUE) { + this.Data = cell.getValue(); + } else { + this.Right = cell; + this.Data = 0.0; + } + } + } + + public double getLeftValue() { + if (this.Right == null) { + return this.Left.getValue(); + } else { + return this.Left.getValue() - this.Right.getValue(); + } + } + + } + + public void setVariables(CellAddress[] variables) { + m_variables = variables; + m_variableCount = variables.length; + + //update cell references + m_variableCells = new XCell[m_variableCount]; + m_currentParameters = new double[m_variableCount]; + for (int i = 0; i < m_variableCount; i++) { + m_variableCells[i] = getCell(variables[i]); + m_currentParameters[i] = m_variableCells[i].getValue(); + } + + //parse for cell ranges (under the assumption, that the cells are ordered + //left to right, top to bottom for each cell range + m_variableMap = new CellMap[m_variableCount]; + m_variableData = new double[m_variableCount][][]; + + ArrayList<RowInfo> rows = new ArrayList<RowInfo>(); + RowInfo currentRow = null; + int lastSheet = -1, lastRow = -1; + for (int i = 0; i < m_variableCount; i++) { + boolean match = lastSheet == m_variables[i].Sheet && + lastRow == m_variables[i].Row; + assert !match || currentRow != null; + if (match && currentRow.EndCol == m_variables[i].Column - 1) + currentRow.EndCol++; + else { + currentRow = new RowInfo(m_variables[i].Sheet, m_variables[i].Row); + currentRow.StartCol = m_variables[i].Column; + currentRow.EndCol = m_variables[i].Column; + rows.add(currentRow); + lastSheet = currentRow.Sheet; + lastRow = currentRow.Row; + } + } + + ArrayList<CellRangeAddress> cellRangeAddresses = new ArrayList<CellRangeAddress>(); + if (rows.size() > 0) { + RowInfo firstRow = rows.get(0); + int offset = 0; + for (int i = 1; i < rows.size(); i++) { + currentRow = rows.get(i); + if (currentRow.Sheet != firstRow.Sheet || + currentRow.Row != firstRow.Row + offset + 1 || + currentRow.StartCol != firstRow.StartCol || + currentRow.EndCol != firstRow.EndCol) { + cellRangeAddresses.add(firstRow.getCellRangeAddress(firstRow.Row + offset)); + firstRow = currentRow; + offset = 0; + } else { + offset++; + } + } + cellRangeAddresses.add(firstRow.getCellRangeAddress(firstRow.Row + offset)); + } + + m_cellRangeCount = cellRangeAddresses.size(); + m_cellRangeData = new XChartDataArray[m_cellRangeCount]; + int varID = 0; + //get cell range data and map the variables to their new location + for (int i = 0; i < m_cellRangeCount; i++) { + for (int y = 0; y <= cellRangeAddresses.get(i).EndRow - cellRangeAddresses.get(i).StartRow; y++) + for (int x = 0; x <= cellRangeAddresses.get(i).EndColumn - cellRangeAddresses.get(i).StartColumn; x++) { + CellMap map = new CellMap(); + m_variableMap[varID++] = map; + map.Range = i; + map.Col = x; + map.Row = y; + } + m_cellRangeData[i] = getChartDataArray(cellRangeAddresses.get(i)); + m_variableData[i] = m_cellRangeData[i].getData(); + } + } + + public SolverConstraint[] getConstraints() { + return m_constraints; + } + + public void setConstraints(SolverConstraint[] constraints) { + m_constraints = constraints; + m_constraintCount = constraints.length; + + //update cell references + m_extConstraints = new ExtSolverConstraint[m_constraintCount]; + for (int i = 0; i < m_constraintCount; i++) { + m_extConstraints[i] = new ExtSolverConstraint( + getCell(constraints[i].Left), + constraints[i].Operator, + constraints[i].Right); + } + } + + public boolean getMaximize() { + return m_maximize; + } + + public void setMaximize(boolean maximize) { + m_maximize = maximize; + } + + public boolean getSuccess() { + return m_success; + } + + public double getResultValue() { + return m_functionValue; + } + + public double[] getSolution() { + return m_currentParameters; + } + + private XCell getCell(CellAddress cellAddress) { + return getCell(cellAddress.Column, cellAddress.Row, cellAddress.Sheet); + } + + private XCell getCell(int col, int row, int sheet) { + try { + XSpreadsheets xSpreadsheets = m_document.getSheets(); + XIndexAccess xSheetIndex = UnoRuntime.queryInterface(XIndexAccess.class, xSpreadsheets); + XSpreadsheet xSpreadsheet = UnoRuntime.queryInterface(XSpreadsheet.class, xSheetIndex.getByIndex(sheet)); + return xSpreadsheet.getCellByPosition(col, row); + } catch (IndexOutOfBoundsException ex) { + Logger.getLogger(BaseNLPSolver.class.getName()).log(Level.SEVERE, null, ex); + } catch (WrappedTargetException ex) { + Logger.getLogger(BaseNLPSolver.class.getName()).log(Level.SEVERE, null, ex); + } + + return null; + } + + + + private XChartDataArray getChartDataArray(CellRangeAddress cellRangeAddress) { + return getChartDataArray(cellRangeAddress.Sheet, cellRangeAddress.StartColumn, + cellRangeAddress.StartRow, cellRangeAddress.EndColumn, cellRangeAddress.EndRow); + } + + private XChartDataArray getChartDataArray(int sheet, int startCol, int startRow, int endCol, int endRow) { + try { + XSpreadsheets xSpreadsheets = m_document.getSheets(); + XIndexAccess xSheetIndex = UnoRuntime.queryInterface(XIndexAccess.class, xSpreadsheets); + XSpreadsheet xSpreadsheet = UnoRuntime.queryInterface(XSpreadsheet.class, xSheetIndex.getByIndex(sheet)); + return UnoRuntime.queryInterface(XChartDataArray.class, xSpreadsheet.getCellRangeByPosition(startCol, startRow, endCol, endRow)); + } catch (IndexOutOfBoundsException ex) { + Logger.getLogger(BaseNLPSolver.class.getName()).log(Level.SEVERE, null, ex); + } catch (WrappedTargetException ex) { + Logger.getLogger(BaseNLPSolver.class.getName()).log(Level.SEVERE, null, ex); + } + + return null; + } + + protected PropertyInfo<Boolean> m_assumeNonNegative = new PropertyInfo<Boolean>("AssumeNonNegative", false, "Assume Non-Negative Variables"); + + protected void initializeSolve() { + lockDocument(); + } + + protected void finalizeSolve() { + unlockDocument(); + } + + public String getComponentDescription() { + return m_name; + } + + public String getStatusDescription() { + return ""; + } + + public String getPropertyDescription(String property) { + PropertyInfo propertyInfo = m_propertyMap.get(property); + if (propertyInfo != null) + return propertyInfo.getDescription(); + else + return ""; + } + + // com.sun.star.beans.XPropertySet: + + public XPropertySetInfo getPropertySetInfo() { + return this; + } + + public void setPropertyValue(String property, Object value) throws UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException { + PropertyInfo propertyInfo = m_propertyMap.get(property); + if (propertyInfo != null) + propertyInfo.setValue(value); + else + throw new UnknownPropertyException(); + } + + public Object getPropertyValue(String property) throws UnknownPropertyException, WrappedTargetException { + PropertyInfo propertyInfo = m_propertyMap.get(property); + if (propertyInfo != null) + return propertyInfo.getValue(); + else + throw new UnknownPropertyException(); + } + + public void addPropertyChangeListener(String property, XPropertyChangeListener listener) throws UnknownPropertyException, WrappedTargetException { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void removePropertyChangeListener(String property, XPropertyChangeListener listener) throws UnknownPropertyException, WrappedTargetException { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void addVetoableChangeListener(String property, XVetoableChangeListener listener) throws UnknownPropertyException, WrappedTargetException { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void removeVetoableChangeListener(String property, XVetoableChangeListener listener) throws UnknownPropertyException, WrappedTargetException { + throw new UnsupportedOperationException("Not supported yet."); + } + + // com.sun.star.beans.XPropertySetInfo: + + public Property[] getProperties() { + int propertyCount = m_properties.size(); + Property[] properties = new Property[propertyCount]; + for (int i = 0; i < propertyCount; i++) + properties[i] = m_properties.get(i).getProperty(); + return properties; + } + + public Property getPropertyByName(String property) throws UnknownPropertyException { + PropertyInfo propertyInfo = m_propertyMap.get(property); + if (propertyInfo != null) + return propertyInfo.getProperty(); + else + throw new UnknownPropertyException(); + } + + public boolean hasPropertyByName(String property) { + return m_propertyMap.containsKey(property); + } + + // Helper functions + private void lockDocument(boolean lock) { + if (lock) + m_xModel.lockControllers(); + else + m_xModel.unlockControllers(); + + try { + XIndexAccess xSpreadsheets = UnoRuntime.queryInterface(XIndexAccess.class, m_document.getSheets()); + int sheets = xSpreadsheets.getCount(); + for (int i = 0; i < sheets; i++) { + Object sheet = xSpreadsheets.getByIndex(i); + XTableChartsSupplier xTableChartsSupplier = UnoRuntime.queryInterface(XTableChartsSupplier.class, sheet); + XIndexAccess xCharts = UnoRuntime.queryInterface(XIndexAccess.class, xTableChartsSupplier.getCharts()); + int charts = xCharts.getCount(); + for (int j = 0; j < charts; j++) { + Object chart = xCharts.getByIndex(j); + XEmbeddedObjectSupplier xChartObjects = UnoRuntime.queryInterface(XEmbeddedObjectSupplier.class, chart); + XModel xChartModel = UnoRuntime.queryInterface(XModel.class, xChartObjects.getEmbeddedObject()); + if (lock) + xChartModel.lockControllers(); + else + xChartModel.unlockControllers(); + } + } + } catch (Exception ex) { + Logger.getLogger(BaseNLPSolver.class.getName()).log(Level.SEVERE, null, ex); + } + } + + protected void lockDocument() { + lockDocument(true); + } + + protected void unlockDocument() { + lockDocument(false); + } + + public static String nanoTimeToString(ResourceManager resourceManager, long nanoseconds) { + if (nanoseconds < 0) return null; // shouldn't happen... but if it does, throw an error! + + if (nanoseconds == 0) return "0"; + + if (nanoseconds < 1000) + return nanoseconds + " " + resourceManager.getLocalizedString("Time.Nanoseconds", "Nanoseconds"); + + double microseconds = (double) nanoseconds / 1000; + if (microseconds < 1000) + return String.format("%.2f %s", microseconds, resourceManager.getLocalizedString("Time.Microseconds", "Microseconds")); + + double milliseconds = microseconds / 1000; + if (milliseconds < 1000) + return String.format("%.2f %s", milliseconds, resourceManager.getLocalizedString("Time.Milliseconds", "Milliseconds")); + + double seconds = milliseconds / 1000; + if (seconds < 90) + return String.format("%.2f %s", seconds, resourceManager.getLocalizedString("Time.Seconds", "Seconds")); + + long minutes = (long) seconds / 60; + seconds -= minutes * 60; + long hours = minutes / 60; + minutes -= hours * 60; + long days = hours / 24; + hours -= days * 24; + + if (days > 0) + return String.format("%d %s, %d %s", + days, resourceManager.getLocalizedString(String.format("Time.Day%s", days == 1 ? "" : "s"), "Days"), + hours, resourceManager.getLocalizedString(String.format("Time.Hour%s", hours == 1 ? "" : "s"), "Hours")); + + if (hours > 0) + return String.format("%d %s, %d %s", + hours, resourceManager.getLocalizedString(String.format("Time.Hour%s", hours == 1 ? "" : "s"), "Hours"), + minutes, resourceManager.getLocalizedString(String.format("Time.Minute%s", minutes == 1 ? "" : "s"), "Minutes")); + + if (minutes > 0) + return String.format("%d %s, %.0f %s", + minutes, resourceManager.getLocalizedString(String.format("Time.Minute%s", minutes == 1 ? "" : "s"), "Minutes"), + Math.floor(seconds), resourceManager.getLocalizedString(String.format("Time.Second%s", Math.floor(seconds) == 1 ? "" : "s"), "Seconds")); + + return String.format("%.2f %s", seconds, resourceManager.getLocalizedString("Time.Seconds", "Seconds")); + } + // </editor-fold> + +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/DEPSSolverImpl.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/DEPSSolverImpl.java new file mode 100644 index 000000000..2b6c1ce36 --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/DEPSSolverImpl.java @@ -0,0 +1,212 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import net.adaptivebox.deps.DEPSAgent; +import net.adaptivebox.deps.behavior.DEGTBehavior; +import net.adaptivebox.deps.behavior.PSGTBehavior; +import net.adaptivebox.global.IUpdateCycleEngine; +import net.adaptivebox.knowledge.Library; +import net.adaptivebox.knowledge.SearchPoint; +import net.adaptivebox.space.BasicPoint; + +import com.sun.star.comp.Calc.NLPSolver.dialogs.IEvolutionarySolverStatusDialog; +import com.sun.star.lang.IllegalArgumentException; +import com.sun.star.lang.XSingleComponentFactory; +import com.sun.star.lib.uno.helper.Factory; +import com.sun.star.registry.XRegistryKey; +import com.sun.star.uno.XComponentContext; + + +public final class DEPSSolverImpl extends BaseEvolutionarySolver + implements com.sun.star.lang.XServiceInfo +{ + private static final String m_implementationName = DEPSSolverImpl.class.getName(); + private static final String[] m_serviceNames = { + "com.sun.star.sheet.Solver", + "com.sun.star.beans.PropertySet" + }; + + public DEPSSolverImpl( XComponentContext context ) + { + super(context, "DEPS Evolutionary Algorithm"); + + registerProperty(m_agentSwitchRate); + registerProperty(m_minFactor); + registerProperty(m_maxFactor); + registerProperty(m_CR); + registerProperty(m_c1); + registerProperty(m_c2); + registerProperty(m_weight); + registerProperty(m_CL); + } + + public static XSingleComponentFactory __getComponentFactory( String sImplementationName ) { + XSingleComponentFactory xFactory = null; + + if ( sImplementationName.equals( m_implementationName ) ) + xFactory = Factory.createComponentFactory(DEPSSolverImpl.class, m_serviceNames); + return xFactory; + } + + public static boolean __writeRegistryServiceInfo( XRegistryKey xRegistryKey ) { + return Factory.writeRegistryServiceInfo(m_implementationName, + m_serviceNames, + xRegistryKey); + } + + // com.sun.star.lang.XServiceInfo: + public String getImplementationName() { + return m_implementationName; + } + + public boolean supportsService( String sService ) { + int len = m_serviceNames.length; + + for( int i=0; i < len; i++) { + if (sService.equals(m_serviceNames[i])) + return true; + } + return false; + } + + public String[] getSupportedServiceNames() { + return m_serviceNames; + } + + private final PropertyInfo<Double> m_agentSwitchRate = new PropertyInfo<Double>("AgentSwitchRate", 0.5, "Agent Switch Rate (DE Probability)"); + // --DE + private final PropertyInfo<Double> m_minFactor = new PropertyInfo<Double>("DEFactorMin", 0.5, "DE: Min Scaling Factor (0-1.2)"); + private final PropertyInfo<Double> m_maxFactor = new PropertyInfo<Double>("DEFactorMax", 0.5, "DE: Max Scaling Factor (0-1.2)"); + private final PropertyInfo<Double> m_CR = new PropertyInfo<Double>("DECR", 0.9, "DE: Crossover Probability (0-1)"); + // --PS + private final PropertyInfo<Double> m_c1 = new PropertyInfo<Double>("PSC1", 1.494, "PS: Cognitive Constant"); + private final PropertyInfo<Double> m_c2 = new PropertyInfo<Double>("PSC2", 1.494, "PS: Social Constant"); + private final PropertyInfo<Double> m_weight = new PropertyInfo<Double>("PSWeight", 0.729, "PS: Constriction Coefficient"); + private final PropertyInfo<Double> m_CL = new PropertyInfo<Double>("PSCL", 0.0, "PS: Mutation Probability (0-0.005)"); + + public void solve() { + try { + m_librarySize.setValue(m_swarmSize.getValue()); //DEPS' library is as large as the swarm + } catch (IllegalArgumentException ex) { + Logger.getLogger(DEPSSolverImpl.class.getName()).log(Level.SEVERE, null, ex); + } + initializeSolve(); + if (m_problemEncoder == null) + { + return; + } + + //Init: + DEPSAgent[] agents = new DEPSAgent[m_swarmSize.getValue()]; + for (int i = 0; i < m_swarmSize.getValue(); i++) { + DEGTBehavior deGTBehavior = new DEGTBehavior(); + deGTBehavior.MIN_FACTOR = Math.min(m_minFactor.getValue(), m_maxFactor.getValue()); + deGTBehavior.MAX_FACTOR = Math.max(m_minFactor.getValue(), m_maxFactor.getValue()); + deGTBehavior.CR = m_CR.getValue(); + deGTBehavior.setLibrary(m_library); + + PSGTBehavior psGTBehavior = new PSGTBehavior(); + psGTBehavior.c1 = m_c1.getValue(); + psGTBehavior.c2 = m_c2.getValue(); + psGTBehavior.CL = m_CL.getValue(); + psGTBehavior.weight = m_weight.getValue(); + psGTBehavior.setLibrary(m_library); + + agents[i] = new DEPSAgent(m_problemEncoder, deGTBehavior, psGTBehavior, + m_agentSwitchRate.getValue(), m_specCompareEngine, + m_library.getSelectedPoint(i)); + } + + //Learn: + m_solverStatusDialog.setVisible(true); + m_solverStatusDialog.setMaxIterations(m_learningCycles.getValue()); + m_solverStatusDialog.setMaxStagnation(m_required.getValue()); + int learningCycle = 1; + long runtime = 0; + do { + long startTime = System.nanoTime(); + + if (learningCycle >= m_learningCycles.getValue()) + learningCycle = 1; + + if (m_solverStatusDialog.getUserState() == IEvolutionarySolverStatusDialog.CONTINUE) + lockDocument(); + + m_toleratedCount = 0; + m_toleratedMin = -1.0 * m_tolerance.getValue(); + m_toleratedMax = m_tolerance.getValue(); + for (; learningCycle <= m_learningCycles.getValue() && + m_toleratedCount < m_required.getValue() && + m_solverStatusDialog.getUserState() != IEvolutionarySolverStatusDialog.CANCEL; learningCycle++) { + m_library.refreshGbest(m_specCompareEngine); + + for (int i = 0; i < m_swarmSize.getValue(); i++) + agents[i].generatePoint(); + + for (int i = 0; i < m_swarmSize.getValue(); i++) + agents[i].learn(); + + for (int i = 0; i < m_swarmSize.getValue(); i++) { + SearchPoint agentPoint = agents[i].getMGState(); + boolean inRange = (agentPoint.getObjectiveValue() >= m_toleratedMin && agentPoint.getObjectiveValue() <= m_toleratedMax); + if (Library.replace(m_envCompareEngine, agentPoint, m_totalBestPoint)) { + m_solverStatusDialog.setBestSolution(m_totalBestPoint.getObjectiveValue(), m_totalBestPoint.isFeasible()); + if (!inRange) { + m_toleratedMin = agentPoint.getObjectiveValue() - m_tolerance.getValue(); + m_toleratedMax = agentPoint.getObjectiveValue() + m_tolerance.getValue(); + m_toleratedCount = 0; + } + } + } + + if (m_specCompareEngine instanceof IUpdateCycleEngine) + ((IUpdateCycleEngine)m_specCompareEngine).updateCycle(learningCycle); + + m_solverStatusDialog.setIteration(learningCycle); + m_solverStatusDialog.setStagnation(m_toleratedCount); + m_solverStatusDialog.setRuntime(runtime + (System.nanoTime() - startTime)); + m_xReschedule.reschedule(); + } + + applySolution(); //show the current solution + unlockDocument(); //allow the solution to be displayed + + runtime += (System.nanoTime() - startTime); + m_solverStatusDialog.setRuntime(runtime); + } while (m_solverStatusDialog.waitForUser() == IEvolutionarySolverStatusDialog.CONTINUE); + + lockDocument(); + + finalizeSolve(); + } + +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/META-INF/manifest.xml b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/META-INF/manifest.xml new file mode 100644 index 000000000..0867cdd96 --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/META-INF/manifest.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<manifest:manifest xmlns:manifest="http://openoffice.org/2001/manifest"> + <manifest:file-entry manifest:media-type="application/vnd.sun.star.uno-components" + manifest:full-path="components.rdb"/> + <manifest:file-entry manifest:media-type="application/vnd.sun.star.help" + manifest:full-path="help"/> + <manifest:file-entry manifest:media-type="application/vnd.sun.star.package-bundle-description" + manifest:full-path="description/extensiondescription.txt"/> +</manifest:manifest>
\ No newline at end of file diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/Manifest.mf b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/Manifest.mf new file mode 100644 index 000000000..d194e6a3b --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/Manifest.mf @@ -0,0 +1 @@ +RegistrationClassName: com.sun.star.comp.Calc.NLPSolver.Registration diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/PropertyInfo.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/PropertyInfo.java new file mode 100644 index 000000000..dc5663213 --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/PropertyInfo.java @@ -0,0 +1,101 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver; + +import com.sun.star.beans.Property; +import com.sun.star.lang.IllegalArgumentException; +import com.sun.star.uno.Type; + +public class PropertyInfo<PropType> { + + private Property m_property; + private PropType m_value; + private String m_description; + + public Property getProperty() { + return m_property; + } + + public PropType getValue() { + return m_value; + } + + public String getDescription() { + return m_description; + } + + @SuppressWarnings("unchecked") + public void setValue(Object value) throws IllegalArgumentException { + if (m_property.Type == Type.LONG) { + if (!(value instanceof Integer)) + throw new IllegalArgumentException(); + m_value = (PropType)value; + } else if (m_property.Type == Type.DOUBLE) { + if (!(value instanceof Double)) + throw new IllegalArgumentException(); + m_value = (PropType)value; + } else if (m_property.Type == Type.BOOLEAN) { + if (!(value instanceof Boolean)) + throw new IllegalArgumentException(); + m_value = (PropType)value; + } + } + + public PropertyInfo(String name, PropType value, String description) { + this(name, value, (short)0, description); + } + + private PropertyInfo(String name, PropType value, short attributes, + String description) { + m_property = new Property(); + m_property.Name = name; + m_property.Attributes = attributes; + m_property.Handle = -1; + + if (value instanceof Integer) + m_property.Type = Type.LONG; + else if (value instanceof Double) + m_property.Type = Type.DOUBLE; + else if (value instanceof Boolean) + m_property.Type = Type.BOOLEAN; + + m_value = value; + m_description = description; + } + + public void localize(ResourceManager resourceManager) { + try { + m_description = resourceManager.getLocalizedString("Properties." + + m_property.Name); + } catch (com.sun.star.resource.MissingResourceException ex) { + System.out.println("Can't localize. Resource missing for property: " + + m_property.Name); + } + } + +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/Registration.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/Registration.java new file mode 100644 index 000000000..157f4963f --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/Registration.java @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package com.sun.star.comp.Calc.NLPSolver; + +import com.sun.star.lib.uno.helper.Factory; +import com.sun.star.lang.XSingleComponentFactory; + +public final class Registration { + + private static final String[] m_serviceNames = { + "com.sun.star.beans.PropertySet", + "com.sun.star.sheet.Solver" + }; + + public static XSingleComponentFactory __getComponentFactory( String sImplementationName ) + { + XSingleComponentFactory xFactory = null; + + if ( sImplementationName.equals( "com.sun.star.comp.Calc.NLPSolver.DEPSSolverImpl" ) ) + xFactory = Factory.createComponentFactory( com.sun.star.comp.Calc.NLPSolver.DEPSSolverImpl.class, + m_serviceNames ); + if ( sImplementationName.equals( "com.sun.star.comp.Calc.NLPSolver.SCOSolverImpl" ) ) + xFactory = Factory.createComponentFactory( com.sun.star.comp.Calc.NLPSolver.SCOSolverImpl.class, + m_serviceNames ); + + return xFactory; + } + private Registration() {} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/ResourceManager.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/ResourceManager.java new file mode 100644 index 000000000..33eebc831 --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/ResourceManager.java @@ -0,0 +1,93 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver; + +import com.sun.star.beans.PropertyState; +import com.sun.star.beans.PropertyValue; +import com.sun.star.beans.XPropertySet; +import com.sun.star.configuration.theDefaultProvider; +import com.sun.star.deployment.PackageInformationProvider; +import com.sun.star.deployment.XPackageInformationProvider; +import com.sun.star.lang.Locale; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.resource.StringResourceWithLocation; +import com.sun.star.resource.XStringResourceWithLocation; +import com.sun.star.uno.AnyConverter; +import com.sun.star.uno.Exception; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; + + +public class ResourceManager { + + private final String m_resourceBasename; + private XStringResourceWithLocation m_xStrResource; + + public ResourceManager(XComponentContext xContext, String oxtId, String relativeResourceBaseUrl, String resourceBasename) { + m_resourceBasename = resourceBasename; + + XPackageInformationProvider xPkgInfo = PackageInformationProvider.get(xContext); + final String oxtRoot = xPkgInfo.getPackageLocation(oxtId); + final String resourceBaseUrl = oxtRoot + relativeResourceBaseUrl; + + try { + XMultiServiceFactory xConfig = theDefaultProvider.get(xContext); + + Object[] args = new Object[1]; + args[0] = new PropertyValue("nodepath", 0, "/org.openoffice.Setup/L10N", PropertyState.DIRECT_VALUE); + XPropertySet xConfigProps = UnoRuntime.queryInterface(XPropertySet.class, + xConfig.createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", args)); + String[] localeProp = AnyConverter.toString(xConfigProps.getPropertyValue("ooLocale")).split("-"); + String lang = localeProp[0]; + String country = (localeProp.length >= 2 ? localeProp[1] : ""); + String variant = (localeProp.length >= 3 ? localeProp[2] : ""); + Locale locale = new Locale(lang, country, variant); + + m_xStrResource = StringResourceWithLocation.create(xContext, resourceBaseUrl, true, locale, m_resourceBasename, "", null); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + /* This implementation is used if the presence of the key will be handled + * "outside" (i.e. by catching the appropriate MissingResourceException). */ + public String getLocalizedString(String key) throws com.sun.star.resource.MissingResourceException { + return m_xStrResource.resolveString(m_resourceBasename + "." + key); + } + + /* This implementation on the other hand handles the exception by itself + * and returns a (predefined) default value if necessary. */ + public String getLocalizedString(String key, String defaultValue) { + try { + return m_xStrResource.resolveString(m_resourceBasename + "." + key); + } catch (com.sun.star.resource.MissingResourceException ex) { + return defaultValue; + } + } + +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/SCOSolverImpl.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/SCOSolverImpl.java new file mode 100644 index 000000000..c1798606d --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/SCOSolverImpl.java @@ -0,0 +1,167 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver; + +import com.sun.star.comp.Calc.NLPSolver.dialogs.IEvolutionarySolverStatusDialog; +import com.sun.star.uno.XComponentContext; +import com.sun.star.lib.uno.helper.Factory; +import com.sun.star.lang.XSingleComponentFactory; +import com.sun.star.registry.XRegistryKey; +import net.adaptivebox.sco.SCAgent; +import net.adaptivebox.global.IUpdateCycleEngine; +import net.adaptivebox.knowledge.Library; +import net.adaptivebox.knowledge.SearchPoint; + + +public final class SCOSolverImpl extends BaseEvolutionarySolver + implements com.sun.star.lang.XServiceInfo +{ + private static final String m_implementationName = SCOSolverImpl.class.getName(); + private static final String[] m_serviceNames = { + "com.sun.star.sheet.Solver", + "com.sun.star.beans.PropertySet" + }; + + public SCOSolverImpl( XComponentContext context ) + { + super(context, "SCO Evolutionary Algorithm"); + + registerProperty(m_librarySize); //SCO allows the user to specify the size of the library + } + + public static XSingleComponentFactory __getComponentFactory( String sImplementationName ) { + XSingleComponentFactory xFactory = null; + + if ( sImplementationName.equals( m_implementationName ) ) + xFactory = Factory.createComponentFactory(SCOSolverImpl.class, m_serviceNames); + return xFactory; + } + + public static boolean __writeRegistryServiceInfo( XRegistryKey xRegistryKey ) { + return Factory.writeRegistryServiceInfo(m_implementationName, + m_serviceNames, + xRegistryKey); + } + + // com.sun.star.lang.XServiceInfo: + public String getImplementationName() { + return m_implementationName; + } + + public boolean supportsService( String sService ) { + int len = m_serviceNames.length; + + for( int i=0; i < len; i++) { + if (sService.equals(m_serviceNames[i])) + return true; + } + return false; + } + + public String[] getSupportedServiceNames() { + return m_serviceNames; + } + + public void solve() { + initializeSolve(); + + if (m_problemEncoder == null) + { + return; + } + + //Init: + int swarmSize = m_swarmSize.getValue(); + SCAgent[] agents = new SCAgent[swarmSize]; + for (int i = 0; i < swarmSize; i++) { + agents[i] = new SCAgent(); + agents[i].setProblemEncoder(m_problemEncoder); + agents[i].setSpecComparator(m_specCompareEngine); + agents[i].setExternalLib(m_library); + } + + //Learn: + m_solverStatusDialog.setVisible(true); + int learningCycles = m_learningCycles.getValue(); + m_solverStatusDialog.setMaxIterations(learningCycles); + m_solverStatusDialog.setMaxStagnation(m_required.getValue()); + int learningCycle = 1; + long runtime = 0; + do { + long startTime = System.nanoTime(); + + if (learningCycle >= m_learningCycles.getValue()) + learningCycle = 1; + + if (m_solverStatusDialog.getUserState() == IEvolutionarySolverStatusDialog.CONTINUE) + lockDocument(); + + m_toleratedCount = 0; + m_toleratedMin = -1.0 * m_tolerance.getValue(); + m_toleratedMax = m_tolerance.getValue(); + for (; learningCycle <= learningCycles && + m_toleratedCount < m_required.getValue() && + m_solverStatusDialog.getUserState() != IEvolutionarySolverStatusDialog.CANCEL; learningCycle++) { + for (int i = 0; i < swarmSize; i++) { + SearchPoint point = agents[i].generatePoint(); + boolean inRange = (point.getObjectiveValue() >= m_toleratedMin && point.getObjectiveValue() <= m_toleratedMax); + if (Library.replace(m_envCompareEngine, point, m_totalBestPoint)) { + m_solverStatusDialog.setBestSolution(m_totalBestPoint.getObjectiveValue(), m_totalBestPoint.isFeasible()); + if (!inRange) { + m_toleratedMin = point.getObjectiveValue() - m_tolerance.getValue(); + m_toleratedMax = point.getObjectiveValue() + m_tolerance.getValue(); + m_toleratedCount = 0; + } + } + } + + for (int i = 0; i < swarmSize; i++) + agents[i].updateInfo(); + + if (m_specCompareEngine instanceof IUpdateCycleEngine) + ((IUpdateCycleEngine)m_specCompareEngine).updateCycle(learningCycle); + + m_solverStatusDialog.setIteration(learningCycle); + m_solverStatusDialog.setStagnation(m_toleratedCount); + m_solverStatusDialog.setRuntime(runtime + (System.nanoTime() - startTime)); + m_xReschedule.reschedule(); + } + + applySolution(); //show the current solution + unlockDocument(); //allow the solution to be displayed + + runtime += (System.nanoTime() - startTime); + m_solverStatusDialog.setRuntime(runtime); + } while (m_solverStatusDialog.waitForUser() == IEvolutionarySolverStatusDialog.CONTINUE); + + lockDocument(); + + finalizeSolve(); + } + +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/components.rdb b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/components.rdb new file mode 100644 index 000000000..151ec5eed --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/components.rdb @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<components xmlns="http://openoffice.org/2010/uno-components"> + <component loader="com.sun.star.loader.Java2" uri="./nlpsolver.jar"> + <implementation name="com.sun.star.comp.Calc.NLPSolver.DEPSSolverImpl"> + <service name="com.sun.star.beans.PropertySet"/> + <service name="com.sun.star.sheet.Solver"/> + </implementation> + <implementation name="com.sun.star.comp.Calc.NLPSolver.SCOSolverImpl"> + <service name="com.sun.star.beans.PropertySet"/> + <service name="com.sun.star.sheet.Solver"/> + </implementation> + </component> +</components> diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/description-en-US.txt b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/description-en-US.txt new file mode 100644 index 000000000..9288dcf75 --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/description-en-US.txt @@ -0,0 +1 @@ +This extension integrates into Calc and offers new Solver engines to use for optimizing nonlinear programming models. diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/description.xml b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/description.xml new file mode 100644 index 000000000..928975682 --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/description.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--Created with OpenOffice.org API plug-in for NetBeans Version 2.0.3--> +<description xmlns="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink"> + <version value="0.9"/> + <identifier value="com.sun.star.comp.Calc.NLPSolver"/> + <display-name> + <name lang="en-US">Solver for Nonlinear Programming</name> + </display-name> + <publisher> + <name lang="en-US" xlink:href="http://www.documentfoundation.org">The Document Foundation</name> + </publisher> + <extension-description> + <src lang="en-US" xlink:href="description-en-US.txt"/> + </extension-description> + <dependencies> + <OpenOffice.org-minimal-version xmlns:d="http://openoffice.org/extensions/description/2006" d:name="OpenOffice.org 3.0" value="3.0"/> + </dependencies> +</description> diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/BaseDialog.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/BaseDialog.java new file mode 100644 index 000000000..d10ad3493 --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/BaseDialog.java @@ -0,0 +1,151 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver.dialogs; + +import com.sun.star.awt.InvalidateStyle; +import com.sun.star.awt.PosSize; +import com.sun.star.awt.Rectangle; +import com.sun.star.comp.Calc.NLPSolver.dialogs.controls.BaseControl; +import com.sun.star.awt.XControl; +import com.sun.star.awt.XControlModel; +import com.sun.star.awt.XDialog; +import com.sun.star.awt.XToolkit; +import com.sun.star.awt.XWindow; +import com.sun.star.awt.XWindowPeer; +import com.sun.star.frame.XController; +import com.sun.star.frame.XDesktop; +import com.sun.star.frame.XFrame; +import com.sun.star.frame.XModel; +import com.sun.star.lang.XComponent; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.uno.Exception; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * The BaseDialog represents the base for all dialogs used within the addon. + * It automatically loads the necessary interfaces to access OpenOffice.org dialogs. + */ +public abstract class BaseDialog extends BaseControl { + + private XMultiComponentFactory xMCF; + private XMultiServiceFactory xMSF; + protected XWindow xWindow; + protected XDialog xDialog; + private XWindowPeer xWindowPeer; + + @Override + public String getName() { + return null; + } + + public XMultiServiceFactory getMultiServiceFactory() { + return xMSF; + } + + private XFrame getCurrentFrame() throws Exception { + Object oDesktop = xMCF.createInstanceWithContext("com.sun.star.frame.Desktop", context); + XDesktop xDesktop = UnoRuntime.queryInterface(XDesktop.class, oDesktop); + XComponent xComponent = xDesktop.getCurrentComponent(); + XModel xModel = UnoRuntime.queryInterface(XModel.class, xComponent); + XController xController = xModel.getCurrentController(); + return xController.getFrame(); + } + + private Rectangle getWorkspaceDimensions() throws Exception { + return getCurrentFrame().getComponentWindow().getPosSize(); + } + + public BaseDialog(XComponentContext context, String title, int x, int y, int width, int height) { + super(context); + try { + xMCF = context.getServiceManager(); + setUnoModel(xMCF.createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", context)); + xMSF = UnoRuntime.queryInterface(XMultiServiceFactory.class, getUnoModel()); + + setProperty("Title", title); + setPosition(x, y); + setSize(width, height); + + unoControl = xMCF.createInstanceWithContext("com.sun.star.awt.UnoControlDialog", context); + XControl xControl = UnoRuntime.queryInterface(XControl.class, unoControl); + XControlModel xControlModel = UnoRuntime.queryInterface(XControlModel.class, getUnoModel()); + xControl.setModel(xControlModel); + + Object toolkit = xMCF.createInstanceWithContext("com.sun.star.awt.Toolkit", context); + XToolkit xToolkit = UnoRuntime.queryInterface(XToolkit.class, toolkit); + xWindow = UnoRuntime.queryInterface(XWindow.class, unoControl); + xWindow.setVisible(false); + XWindowPeer xParentWindowPeer = UnoRuntime.queryInterface(XWindowPeer.class, getCurrentFrame().getComponentWindow()); + xControl.createPeer(xToolkit, xParentWindowPeer); + xWindowPeer = xControl.getPeer(); + + xDialog = UnoRuntime.queryInterface(XDialog.class, unoControl); + + //center if necessary + if (x < 0 || y < 0) { + Rectangle workspacePosSize = getWorkspaceDimensions(); + Rectangle dialogPosSize = xWindow.getPosSize(); + if (x < 0) + dialogPosSize.X = workspacePosSize.X + (workspacePosSize.Width / 2) - (dialogPosSize.Width / 2); + if (y < 0) + dialogPosSize.Y = workspacePosSize.Y + (workspacePosSize.Height / 2) - (dialogPosSize.Height / 2); + + xWindow.setPosSize(dialogPosSize.X, dialogPosSize.Y, + dialogPosSize.Width, dialogPosSize.Height, PosSize.POS); + } + + } catch (Exception ex) { + Logger.getLogger(BaseDialog.class.getName()).log(Level.SEVERE, null, ex); + } + } + + @Override + protected void finalize() throws Throwable { + XComponent xComponent = UnoRuntime.queryInterface(XComponent.class, unoControl); + xComponent.dispose(); + super.finalize(); + } + + + + + + public void setCloseable(boolean closeable) { + setProperty("Closeable", Boolean.valueOf(closeable)); + } + + public void repaint() { + xWindowPeer.invalidate((short)(InvalidateStyle.CHILDREN /*| InvalidateStyle.NOERASE*/ | + InvalidateStyle.UPDATE | InvalidateStyle.TRANSPARENT)); + } + +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/DummyEvolutionarySolverStatusDialog.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/DummyEvolutionarySolverStatusDialog.java new file mode 100644 index 000000000..92f45b9a8 --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/DummyEvolutionarySolverStatusDialog.java @@ -0,0 +1,73 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver.dialogs; + +public class DummyEvolutionarySolverStatusDialog + implements IEvolutionarySolverStatusDialog { + + public int getUserState() { + return OK; + } + + public void setBestSolution(double solution, boolean feasible) { + + } + + public void setMaxIterations(int maxIterations) { + + } + + public void setMaxStagnation(int maxStagnation) { + + } + + public void setIteration(int iteration) { + + } + + public void setStagnation(int stagnation) { + + } + + public void setRuntime(long runtime) { + + } + + public int waitForUser() { + return OK; + } + + public void setVisible(boolean visible) { + + } + + public void dispose() { + + } + +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/EvolutionarySolverStatusUno.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/EvolutionarySolverStatusUno.java new file mode 100644 index 000000000..e3695a0c7 --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/EvolutionarySolverStatusUno.java @@ -0,0 +1,292 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver.dialogs; + +import com.sun.star.comp.Calc.NLPSolver.BaseNLPSolver; +import com.sun.star.awt.ActionEvent; +import com.sun.star.awt.XActionListener; +import com.sun.star.comp.Calc.NLPSolver.ResourceManager; +import com.sun.star.lang.EventObject; +import com.sun.star.lang.XComponent; +import com.sun.star.style.VerticalAlignment; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import com.sun.star.comp.Calc.NLPSolver.dialogs.controls.Button; +import com.sun.star.comp.Calc.NLPSolver.dialogs.controls.Label; +import com.sun.star.comp.Calc.NLPSolver.dialogs.controls.ProgressBar; + +public class EvolutionarySolverStatusUno extends BaseDialog + implements IEvolutionarySolverStatusDialog, + XActionListener { + + private int userState; + private final Label lblSolutionValue; + private final Label lblIteration; + private final ProgressBar pbIteration; + private final Label lblIterationValue; + private final Label lblStagnation; + private final ProgressBar pbStagnation; + private final Label lblStagnationValue; + private final Label lblRuntimeValue; + private final Button btnStop; + private final Button btnOK; + private final Button btnContinue; + private final int defaultTextColor; + private int maxIterations; + private int maxStagnation; + + private final ResourceManager resourceManager; + + private static final int COLOR_RED = 0xFF0000; + + public EvolutionarySolverStatusUno(XComponentContext xContext) { + super(xContext, "Solver Status", -1, -1, 170, 95); //center the dialog on the parent + + setCloseable(false); + userState = IEvolutionarySolverStatusDialog.OK; + + resourceManager = new ResourceManager(xContext, "com.sun.star.comp.Calc.NLPSolver", "/locale", "NLPSolverStatusDialog"); + + try { + setProperty("Title", resourceManager.getLocalizedString("Dialog.Caption")); + } catch (com.sun.star.resource.MissingResourceException ex) {} //leave the title as it is + + int y = 5; + Label lblSolution = new Label(this, "lblSolution"); + lblSolution.setPosition(5, y); + lblSolution.setSize(60, 10); + lblSolution.setLabel(resourceManager.getLocalizedString("Controls.lblSolution", "Current Solution:")); + lblSolution.setParentControl(this); + + lblSolutionValue = new Label(this, "lblSolutionValue"); + lblSolutionValue.setPosition(65, y); + lblSolutionValue.setSize(100, 10); + lblSolutionValue.setParentControl(this); + defaultTextColor = lblSolutionValue.getTextColor(); + y += 15; + + lblIteration = new Label(this, "lblIteration"); + lblIteration.setPosition(5, y); + lblIteration.setSize(60, 15); + lblIteration.setLabel(resourceManager.getLocalizedString("Controls.lblIteration", "Iteration:")); + lblIteration.setVerticalAlign(VerticalAlignment.MIDDLE); + lblIteration.setParentControl(this); + + pbIteration = new ProgressBar(this, "pbIteration"); + pbIteration.setPosition(65, y); + pbIteration.setSize(100, 15); + pbIteration.setParentControl(this); + + lblIterationValue = new Label(this, "lblIterationValue"); + lblIterationValue.setPosition(65, y); + lblIterationValue.setSize(100, 20); + lblIterationValue.setVerticalAlign(VerticalAlignment.MIDDLE); + lblIterationValue.setMultiLine(true); + lblIterationValue.setParentControl(this); + lblIterationValue.setVisible(false); + y += 20; + + lblStagnation = new Label(this, "lblStagnation"); + lblStagnation.setPosition(5, y); + lblStagnation.setSize(60, 15); + lblStagnation.setLabel(resourceManager.getLocalizedString("Controls.lblStagnation", "Stagnation:")); + lblStagnation.setVerticalAlign(VerticalAlignment.MIDDLE); + lblStagnation.setParentControl(this); + + pbStagnation = new ProgressBar(this, "pbStagnation"); + pbStagnation.setPosition(65, y); + pbStagnation.setSize(100, 15); + pbStagnation.setParentControl(this); + + lblStagnationValue = new Label(this, "lblStagnationValue"); + lblStagnationValue.setPosition(65, y); + lblStagnationValue.setSize(100, 20); + lblStagnationValue.setVerticalAlign(VerticalAlignment.MIDDLE); + lblStagnationValue.setMultiLine(true); + lblStagnationValue.setParentControl(this); + lblStagnationValue.setVisible(false); + y+= 20; + + Label lblRuntime = new Label(this, "lblRuntime"); + lblRuntime.setPosition(5, y); + lblRuntime.setSize(60, 10); + lblRuntime.setLabel(resourceManager.getLocalizedString("Controls.lblRuntime", "Runtime:")); + lblRuntime.setParentControl(this); + + lblRuntimeValue = new Label(this, "lblRuntimeValue"); + lblRuntimeValue.setPosition(65, y); + lblRuntimeValue.setSize(100, 10); + lblRuntimeValue.setParentControl(this); + y += 15; + + btnStop = new Button(this, "btnStop"); + btnStop.setPosition(5, y); + btnStop.setSize(45, 15); + btnStop.setLabel(resourceManager.getLocalizedString("Controls.btnStop", "Stop")); + btnStop.setParentControl(this); + btnStop.addActionListener(this); + btnStop.setActionCommand("btnStopClick"); + + btnOK = new Button(this, "btnOK"); + btnOK.setPosition(65, y); + btnOK.setSize(40, 15); + btnOK.setLabel(resourceManager.getLocalizedString("Controls.btnOK", "OK")); + btnOK.setParentControl(this); + btnOK.addActionListener(this); + btnOK.setActionCommand("btnOKClick"); + btnOK.setEnabled(false); + + btnContinue = new Button(this, "btnContinue"); + btnContinue.setPosition(110, y); + btnContinue.setSize(55, 15); + btnContinue.setLabel(resourceManager.getLocalizedString("Controls.btnContinue", "Continue")); + btnContinue.setParentControl(this); + btnContinue.addActionListener(this); + btnContinue.setActionCommand("btnContinueClick"); + btnContinue.setEnabled(false); + y += 15; + } + + public int getUserState() { + return userState; + } + + public void setBestSolution(double solution, boolean feasible) { + lblSolutionValue.setLabel(String.format("%g", solution)); + if (feasible) + lblSolutionValue.setTextColor(defaultTextColor); + else + lblSolutionValue.setTextColor(COLOR_RED); //red + } + + public void setMaxIterations(int maxIterations) { + pbIteration.setRange(0, maxIterations); + this.maxIterations = maxIterations; + } + + public void setMaxStagnation(int maxStagnation) { + pbStagnation.setRange(0, maxStagnation); + this.maxStagnation = maxStagnation; + } + + public void setIteration(int iteration) { + pbIteration.setValue(iteration); + } + + public void setStagnation(int stagnation) { + pbStagnation.setValue(stagnation); + } + + public void setRuntime(long runtime) { + lblRuntimeValue.setLabel(BaseNLPSolver.nanoTimeToString(resourceManager, runtime)); + } + + public int waitForUser() { + btnStop.setEnabled(false); + btnOK.setEnabled(true); + btnContinue.setEnabled(true); + + if (pbIteration.getValue() >= maxIterations) { + lblIteration.setTextColor(COLOR_RED); + if (userState != IEvolutionarySolverStatusDialog.CANCEL) + lblStagnationValue.setLabel( + resourceManager.getLocalizedString("Message.StopIteration", + "Maximum iterations reached.")); + } + + if (pbStagnation.getValue() >= maxStagnation) { + lblStagnation.setTextColor(COLOR_RED); + if (userState != IEvolutionarySolverStatusDialog.CANCEL) + lblStagnationValue.setLabel( + resourceManager.getLocalizedString("Message.StopStagnation", + "Process stopped due to stagnation.")); + } + + lblIterationValue.setLabel(String.format( + resourceManager.getLocalizedString("Message.CurrentIteration", + "Process stopped at iteration %d of %d."), + pbIteration.getValue(), maxIterations)); + if (userState == IEvolutionarySolverStatusDialog.CANCEL) + lblStagnationValue.setLabel( + resourceManager.getLocalizedString("Message.StopUser", + "Process stopped due to user interruption.")); + + pbIteration.setVisible(false); + pbStagnation.setVisible(false); + lblIterationValue.setVisible(true); + lblStagnationValue.setVisible(true); + + repaint(); + + userState = IEvolutionarySolverStatusDialog.WAITING; + xDialog.execute(); + + lblIteration.setTextColor(defaultTextColor); + lblStagnation.setTextColor(defaultTextColor); + + lblIterationValue.setVisible(false); + lblStagnationValue.setVisible(false); + pbIteration.setVisible(true); + pbStagnation.setVisible(true); + + btnStop.setEnabled(true); + btnOK.setEnabled(false); + btnContinue.setEnabled(false); + + return userState; + } + + @Override + public void setVisible(boolean visible) { + xWindow.setVisible(visible); + } + + public void dispose() { + XComponent component = UnoRuntime.queryInterface(XComponent.class, xDialog); + component.dispose(); + } + + public void actionPerformed(ActionEvent actionEvent) { + if (userState == IEvolutionarySolverStatusDialog.WAITING) { + xDialog.endExecute(); + setVisible(true); + } + + if (actionEvent.ActionCommand.equals("btnStopClick")) + userState = IEvolutionarySolverStatusDialog.CANCEL; + else if (actionEvent.ActionCommand.equals("btnOKClick")) + userState = IEvolutionarySolverStatusDialog.OK; + else if (actionEvent.ActionCommand.equals("btnContinueClick")) + userState = IEvolutionarySolverStatusDialog.CONTINUE; + } + + public void disposing(EventObject eventObject) { + + } + +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/IEvolutionarySolverStatusDialog.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/IEvolutionarySolverStatusDialog.java new file mode 100644 index 000000000..9ef12e09e --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/IEvolutionarySolverStatusDialog.java @@ -0,0 +1,48 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver.dialogs; + +public interface IEvolutionarySolverStatusDialog { + int WAITING = 0; + int OK = 1; + int CONTINUE = 2; + int CANCEL = 3; + + int getUserState(); + + void setBestSolution(double solution, boolean feasible); + void setMaxIterations(int maxIterations); + void setMaxStagnation(int maxStagnation); + void setIteration(int iteration); + void setStagnation(int stagnation); + void setRuntime(long runtime); + int waitForUser(); + + void setVisible(boolean visible); + void dispose(); +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/BaseControl.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/BaseControl.java new file mode 100644 index 000000000..7de59c4b0 --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/BaseControl.java @@ -0,0 +1,141 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver.dialogs.controls; + +import com.sun.star.awt.XControlContainer; +import com.sun.star.awt.XWindow; +import com.sun.star.beans.PropertyVetoException; +import com.sun.star.beans.UnknownPropertyException; +import com.sun.star.beans.XPropertySet; +import com.sun.star.container.ElementExistException; +import com.sun.star.container.XNameContainer; +import com.sun.star.lang.IllegalArgumentException; +import com.sun.star.lang.WrappedTargetException; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import java.util.logging.Level; +import java.util.logging.Logger; + +public abstract class BaseControl { + + protected XComponentContext context; + private Object unoModel; + protected Object unoControl; + private XPropertySet properties; + + + public abstract String getName(); + + public Object getUnoModel() { + return unoModel; + } + + /** + * This is used <b>internally</b> to update the UnoModel and refresh the + * associated PropertySet. + * @param unoModel The new UnoModel for this control. + */ + protected void setUnoModel(Object unoModel) { + this.unoModel = unoModel; + properties = UnoRuntime.queryInterface(XPropertySet.class, unoModel); + } + + public void setParentControl(BaseControl parentControl) { + //TODO : remove from existing parentControl + try { + String name = getName(); + XNameContainer nameContainer = UnoRuntime.queryInterface(XNameContainer.class, parentControl.unoModel); + nameContainer.insertByName(name, unoModel); + + XControlContainer controlContainer = UnoRuntime.queryInterface(XControlContainer.class, parentControl.unoControl); + unoControl = controlContainer.getControl(name); + + } catch (IllegalArgumentException ex) { + Logger.getLogger(BaseControl.class.getName()).log(Level.SEVERE, null, ex); + } catch (ElementExistException ex) { + Logger.getLogger(BaseControl.class.getName()).log(Level.SEVERE, null, ex); + } catch (WrappedTargetException ex) { + Logger.getLogger(BaseControl.class.getName()).log(Level.SEVERE, null, ex); + } + } + + public BaseControl(XComponentContext context) { + this.context = context; + unoModel = null; + unoControl = null; + } + + protected void setProperty(String name, Object value) { + try { + properties.setPropertyValue(name, value); + } catch (UnknownPropertyException ex) { + Logger.getLogger(BaseControl.class.getName()).log(Level.SEVERE, null, ex); + } catch (PropertyVetoException ex) { + Logger.getLogger(BaseControl.class.getName()).log(Level.SEVERE, null, ex); + } catch (IllegalArgumentException ex) { + Logger.getLogger(BaseControl.class.getName()).log(Level.SEVERE, null, ex); + } catch (WrappedTargetException ex) { + Logger.getLogger(BaseControl.class.getName()).log(Level.SEVERE, null, ex); + } + } + + protected Object getProperty(String name) { + try { + return properties.getPropertyValue(name); + } catch (UnknownPropertyException ex) { + Logger.getLogger(BaseControl.class.getName()).log(Level.SEVERE, null, ex); + } catch (WrappedTargetException ex) { + Logger.getLogger(BaseControl.class.getName()).log(Level.SEVERE, null, ex); + } + return null; + } + + // <editor-fold defaultstate="collapsed" desc="Uno Properties"> + + public void setPosition(int x, int y) { + setProperty("PositionX", Integer.valueOf(x)); + setProperty("PositionY", Integer.valueOf(y)); + } + + public void setSize(int width, int height) { + setProperty("Width", Integer.valueOf(width)); + setProperty("Height", Integer.valueOf(height)); + } + + public void setEnabled(boolean enabled) { + setProperty("Enabled", Boolean.valueOf(enabled)); + } + + public void setVisible(boolean visible) { + XWindow xWindow = UnoRuntime.queryInterface(XWindow.class, unoControl); + xWindow.setVisible(visible); + } + + // </editor-fold> + +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/Button.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/Button.java new file mode 100644 index 000000000..61ae47c19 --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/Button.java @@ -0,0 +1,73 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver.dialogs.controls; + +import com.sun.star.awt.XActionListener; +import com.sun.star.awt.XButton; +import com.sun.star.uno.Exception; +import com.sun.star.uno.UnoRuntime; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.sun.star.comp.Calc.NLPSolver.dialogs.BaseDialog; + +public class Button extends LabeledControl { + + private String name; + private XButton xButton; + + public Button(BaseDialog owner, String name) { + super(owner.context); + try { + setUnoModel(owner.getMultiServiceFactory().createInstance("com.sun.star.awt.UnoControlButtonModel")); + this.name = name; + setProperty("Name", name); + } catch (Exception ex) { + Logger.getLogger(Button.class.getName()).log(Level.SEVERE, null, ex); + } + } + + @Override + public String getName() { + return name; + } + + @Override + public void setParentControl(BaseControl parentControl) { + super.setParentControl(parentControl); + xButton = UnoRuntime.queryInterface(XButton.class, unoControl); + } + + public void addActionListener(XActionListener actionListener) { + xButton.addActionListener(actionListener); + } + + public void setActionCommand(String actionCommand) { + xButton.setActionCommand(actionCommand); + } + +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/Label.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/Label.java new file mode 100644 index 000000000..689350ce2 --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/Label.java @@ -0,0 +1,78 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver.dialogs.controls; + +import com.sun.star.lang.IllegalArgumentException; +import com.sun.star.style.VerticalAlignment; +import com.sun.star.uno.AnyConverter; +import com.sun.star.uno.Type; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.sun.star.comp.Calc.NLPSolver.dialogs.BaseDialog; + +public class Label extends LabeledControl { + + private String name; + + public Label(BaseDialog owner, String name) { + super(owner.context); + try { + setUnoModel(owner.getMultiServiceFactory().createInstance("com.sun.star.awt.UnoControlFixedTextModel")); + this.name = name; + setProperty("Name", name); + } catch (Exception ex) { + Logger.getLogger(Button.class.getName()).log(Level.SEVERE, null, ex); + } + } + + @Override + public String getName() { + return name; + } + + public void setVerticalAlign(VerticalAlignment align) { + setProperty("VerticalAlign", align); + } + + + public void setTextColor(int RGB) { + setProperty("TextColor", Integer.valueOf(RGB)); + } + + public int getTextColor() { + try { + Object prop = getProperty("TextColor"); + if (AnyConverter.getType(prop) == Type.LONG) + return AnyConverter.toInt(prop); + } catch (IllegalArgumentException ex) { + Logger.getLogger(LabeledControl.class.getName()).log(Level.SEVERE, null, ex); + } + return 0; + } + +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/LabeledControl.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/LabeledControl.java new file mode 100644 index 000000000..a1c8c7674 --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/LabeledControl.java @@ -0,0 +1,46 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver.dialogs.controls; + +import com.sun.star.uno.XComponentContext; + +public abstract class LabeledControl extends BaseControl { + + public LabeledControl(XComponentContext context) { + super(context); + } + + public void setLabel(String label) { + setProperty("Label", label); + } + + public void setMultiLine(boolean multiLine) { + setProperty("MultiLine", Boolean.valueOf(multiLine)); + } + +} diff --git a/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/ProgressBar.java b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/ProgressBar.java new file mode 100644 index 000000000..a62ea7d9f --- /dev/null +++ b/nlpsolver/src/com/sun/star/comp/Calc/NLPSolver/dialogs/controls/ProgressBar.java @@ -0,0 +1,74 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.Calc.NLPSolver.dialogs.controls; + +import com.sun.star.awt.XProgressBar; +import com.sun.star.uno.UnoRuntime; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.sun.star.comp.Calc.NLPSolver.dialogs.BaseDialog; + +public class ProgressBar extends BaseControl { + + private String m_name; + private XProgressBar m_progressBar; + + public ProgressBar(BaseDialog owner, String name) { + super(owner.context); + try { + setUnoModel(owner.getMultiServiceFactory().createInstance("com.sun.star.awt.UnoControlProgressBarModel")); + m_name = name; + setProperty("Name", name); + } catch (Exception ex) { + Logger.getLogger(Button.class.getName()).log(Level.SEVERE, null, ex); + } + } + + @Override + public String getName() { + return m_name; + } + + @Override + public void setParentControl(BaseControl parentControl) { + super.setParentControl(parentControl); + m_progressBar = UnoRuntime.queryInterface(XProgressBar.class, unoControl); + } + + public void setRange(int min, int max) { + m_progressBar.setRange(min, max); + } + + public void setValue(int value) { + m_progressBar.setValue(value); + } + + public int getValue() { + return m_progressBar.getValue(); + } +} diff --git a/nlpsolver/src/locale/NLPSolverCommon_en_US.default b/nlpsolver/src/locale/NLPSolverCommon_en_US.default new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/nlpsolver/src/locale/NLPSolverCommon_en_US.default diff --git a/nlpsolver/src/locale/NLPSolverCommon_en_US.properties b/nlpsolver/src/locale/NLPSolverCommon_en_US.properties new file mode 100644 index 000000000..5ab304d69 --- /dev/null +++ b/nlpsolver/src/locale/NLPSolverCommon_en_US.properties @@ -0,0 +1,25 @@ +#BaseNLPSolver +NLPSolverCommon.Properties.AssumeNonNegative=Assume Non-Negative Variables + +#BaseEvolutionarySolver +NLPSolverCommon.Properties.SwarmSize=Size of Swarm +NLPSolverCommon.Properties.LibrarySize=Size of Library +NLPSolverCommon.Properties.LearningCycles=Learning Cycles +NLPSolverCommon.Properties.GuessVariableRange=Variable Bounds Guessing +NLPSolverCommon.Properties.VariableRangeThreshold=Variable Bounds Threshold (when guessing) +NLPSolverCommon.Properties.UseACRComparator=Use ACR Comparator (instead of BCH) +NLPSolverCommon.Properties.UseRandomStartingPoint=Use Random starting point +NLPSolverCommon.Properties.UseStrongerPRNG=Use a stronger random generator (slower) +NLPSolverCommon.Properties.StagnationLimit=Stagnation Limit +NLPSolverCommon.Properties.Tolerance=Stagnation Tolerance +NLPSolverCommon.Properties.EnhancedSolverStatus=Show enhanced solver status + +#DEPS +NLPSolverCommon.Properties.AgentSwitchRate=Agent Switch Rate (DE Probability) +NLPSolverCommon.Properties.DEFactorMin=DE: Min Scaling Factor (0-1.2) +NLPSolverCommon.Properties.DEFactorMax=DE: Max Scaling Factor (0-1.2) +NLPSolverCommon.Properties.DECR=DE: Crossover Probability (0-1) +NLPSolverCommon.Properties.PSC1=PS: Cognitive Constant +NLPSolverCommon.Properties.PSC2=PS: Social Constant +NLPSolverCommon.Properties.PSWeight=PS: Constriction Coefficient +NLPSolverCommon.Properties.PSCL=PS: Mutation Probability (0-0.005) diff --git a/nlpsolver/src/locale/NLPSolverStatusDialog_en_US.default b/nlpsolver/src/locale/NLPSolverStatusDialog_en_US.default new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/nlpsolver/src/locale/NLPSolverStatusDialog_en_US.default diff --git a/nlpsolver/src/locale/NLPSolverStatusDialog_en_US.properties b/nlpsolver/src/locale/NLPSolverStatusDialog_en_US.properties new file mode 100644 index 000000000..241259257 --- /dev/null +++ b/nlpsolver/src/locale/NLPSolverStatusDialog_en_US.properties @@ -0,0 +1,30 @@ +#Dialog +NLPSolverStatusDialog.Dialog.Caption=Solver Status + +#Controls +NLPSolverStatusDialog.Controls.lblSolution=Current Solution: +NLPSolverStatusDialog.Controls.lblIteration=Iteration: +NLPSolverStatusDialog.Controls.lblStagnation=Stagnation: +NLPSolverStatusDialog.Controls.lblRuntime=Runtime: +NLPSolverStatusDialog.Controls.btnStop=Stop +NLPSolverStatusDialog.Controls.btnOK=OK +NLPSolverStatusDialog.Controls.btnContinue=Continue + +#Messages +NLPSolverStatusDialog.Message.StopIteration=Maximum iterations reached. +NLPSolverStatusDialog.Message.StopStagnation=Process stopped due to stagnation. +NLPSolverStatusDialog.Message.StopUser=Process stopped due to user interruption. +NLPSolverStatusDialog.Message.CurrentIteration=Process stopped at iteration %d of %d. + +#Time formatting +NLPSolverStatusDialog.Time.Nanoseconds=Nanoseconds +NLPSolverStatusDialog.Time.Microseconds=Microseconds +NLPSolverStatusDialog.Time.Milliseconds=Milliseconds +NLPSolverStatusDialog.Time.Second=Second +NLPSolverStatusDialog.Time.Seconds=Seconds +NLPSolverStatusDialog.Time.Minute=Minute +NLPSolverStatusDialog.Time.Minutes=Minutes +NLPSolverStatusDialog.Time.Hour=Hour +NLPSolverStatusDialog.Time.Hours=Hours +NLPSolverStatusDialog.Time.Day=Day +NLPSolverStatusDialog.Time.Days=Days |