You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(2) |
Sep
(7) |
Oct
(1) |
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(13) |
Feb
(17) |
Mar
(5) |
Apr
(10) |
May
(10) |
Jun
(42) |
Jul
(23) |
Aug
(38) |
Sep
(12) |
Oct
(9) |
Nov
(6) |
Dec
|
2005 |
Jan
(3) |
Feb
(17) |
Mar
(6) |
Apr
|
May
(1) |
Jun
(10) |
Jul
|
Aug
(10) |
Sep
|
Oct
(8) |
Nov
(2) |
Dec
(2) |
2006 |
Jan
(2) |
Feb
(11) |
Mar
(44) |
Apr
(84) |
May
(120) |
Jun
(18) |
Jul
|
Aug
(12) |
Sep
(19) |
Oct
(22) |
Nov
(7) |
Dec
(11) |
2007 |
Jan
(6) |
Feb
(10) |
Mar
(24) |
Apr
(13) |
May
(46) |
Jun
(25) |
Jul
(46) |
Aug
(47) |
Sep
(60) |
Oct
(61) |
Nov
(138) |
Dec
(47) |
2008 |
Jan
(6) |
Feb
(23) |
Mar
(58) |
Apr
(78) |
May
(82) |
Jun
(34) |
Jul
(56) |
Aug
(59) |
Sep
(54) |
Oct
(127) |
Nov
(47) |
Dec
(33) |
2009 |
Jan
(16) |
Feb
(18) |
Mar
(37) |
Apr
(162) |
May
(49) |
Jun
(58) |
Jul
(59) |
Aug
(17) |
Sep
(10) |
Oct
|
Nov
|
Dec
|
From: Gary P. <gpa...@gm...> - 2009-06-11 06:30:53
|
Hi all, This is a small status update from myself regarding CIlib and the current topics being worked on. I should be pushing small notices like this out more regularly so you all can get a feeling of where we are going / what's going on. Currently, various developments are being done and I'm currently merging a few improvements that will stabalise a lot of the questions you all have. The following is currently active: -- Gary Pampara (2): - New DomainParser implementation using a Parser generator - Core changes to improve generic inter-operation (investigating a Dependency Injection strategy) Theuns Cloete (1): - Various Clustering changes Andrich van Wyk (1): - Kernel methods (SVM) - Data access framework Stefan van der Stockt (1): - Neural Network changes Prof. Andries Engelbrecht (1): - Mathematical function updates and various measurements. I have a few patches that are waiting to go in. I've not had that much time to investigate the impact of them yet - but will do do asap. Recent problems with a broken patch in the GA were higher priority. Outstanding: -- Julian Duhein (1): - Dynamic environments. Let us know if anything else is required :D I plan to include a few more updates before we release 0.7.1. Regards, Gary |
From: Theuns C. <the...@gm...> - 2009-06-11 06:28:18
|
Hey Gary, Would it make sense to split the parser into a separate maven module? This way the parser code only has to be generated once, and the JAR file can just be included in the classpath. Regards -- Theuns On Wed, Jun 10, 2009 at 12:51 PM, Gary Pampara<gpa...@gm...> wrote: > The need to have a decent parser for the domain strings is something > that has been on the cards for a very long time. The main problem with > the current implementation is that it is very non-expressive. > > Illegal domains such as: > - R(8, 9)^-1 > - R^0 > - Any other strange combination > > were allowed in the previous parser. > > These patches propose a new generated parser based on a provided grammar > file. > > JJTree and JavaCC were used to achieve the parser. > > Gary Pampara (3): > Semi-complete parser definition. > Deprecation of parser for generated parser. > Prevent invalid values / options in domain strings. |
From: Theuns C. <the...@gm...> - 2009-06-11 06:20:37
|
Yes, the multi-threaded split cooperative algorithm can be used as benchmark to test the new "Algorithm stack" implementation. A pattern's weight is used to indicate how "important" a pattern is. The main idea behind it is to improve performance. Taken clustering as an example, if you have a data set where patterns repeat, you only need to keep one reference to that pattern and increment its weight for each other pattern that is equal. The weight is then used in distance calculations or mean calculations and therefore improves performance. There are also cases where Neural Networks weigh the patterns to indicate significance. It should be clear that there can be different strategies for weighing patterns. In my clustering example, a weight is usually discrete (an integer) whereas in the NN example, a weight is usually a real value between 0 and 1. I agree that we can make use of Types to indicate a pattern's classification, but then it should only be primitive types, i.e. Int, Bit, Real or StringType. I don't think a container type will make sense as a classification. -- Theuns On Wed, Jun 10, 2009 at 12:51 PM, Andrich van Wyk<avw...@gm...> wrote: > I don't think there will be gains unless you keep the samples down to 1, as > is CIlib already uses 100% CPU because our samples are concurrent. This is > the same argument as for threading fitness evaluations, it depends on the > problem and hardware setup etc. But I agree that the algorithm stack might > need a look at and this can make a good experiment to test these things. > > Another question I have is regarding your new Pattern class. I am rewriting > the data stuff as we have discussed a few meetings ago and I have written a > similar class and want to try accommodate your new changes as well. > > What do the weight and index fields do? I didn't apply the patch, so I can't > follow method calls, and there is no documentation. > > Also, in the meeting we discussed the type of a pattern's classification, > shouldn't the classification field rather be Type instead of String? There > is StringType so there is no loss of functionality (if a user indeed wants > Strings for the classification). > > On Wed, Jun 10, 2009 at 11:09 AM, Theuns Cloete <the...@gm...> > wrote: >> >> Hey Andrich, >> >> Firstly, don't think that the multi-threaded class should be committed >> to the master branch. I only sent it out so that other people can have >> a look and comment like you are doing now. That is why I marked it >> experimental. >> >> Secondly, not exactly, the number of threads can be set with the >> .setNumberOfThreads(int) method, which means that even if there are 10 >> sub-populations, but you only have 4 cores (and configure it to use 4 >> threads), then 4 sub-populations will run concurrently. Obviously >> there is a performance hit for managing more threads, but the gains >> can be greater if you have enough cores. I haven't tried multiple >> concurrent samples though. >> >> If an algorithm or problem uses Algorithm.get(), there will be a lot >> of exceptions due to concurrency issues. This whole experiment is >> dependant on the fact that we need to relook the Algorithm stack and I >> hope that we can find a solution using Guice. So, start thinking about >> solutions ;-) >> >> Regards >> -- >> Theuns >> >> On Wed, Jun 10, 2009 at 10:30 AM, Andrich van Wyk<avw...@gm...> >> wrote: >> > Hey Theuns >> > >> > Two things regarding this: If I understand this correctly, each sub >> > algorithm now executes in it own thread. So for instance, if you have >> > three >> > sub algorithms, that will be 3 threads, but you still have to run 30 >> > samples >> > minimum, which then entails 90 total threads running. Is this the case? >> > Also, what is the performance cost of having the 90 running instead of >> > just >> > the 30? >> > >> > Another thing you mention in your summary mail is that this only works >> > if >> > the problem you are optimizing doesn't call Algorithm.get(). If we >> > commit >> > this, how do we convey to the user that he is not allowed to use a >> > problem >> > using Algorithm.get(), also how is the user suppose to know if a problem >> > will call Algorithm.get() ? >> > >> > Regards >> > >> > On Wed, Jun 10, 2009 at 8:40 AM, Theuns Cloete <the...@gm...> >> > wrote: >> >> >> >> An ExecutorService and CoundDownLatch is used to concurrently execute >> >> the >> >> performInitialisation() and performIteration() methods of each >> >> sub-population (sub-algorithm). >> >> >> >> Thus far it works with simplistic problems such as minimizing some >> >> continuous function, but it breaks with more complex problems such as >> >> clustering with the help of the ClusteringUtils class. Following >> >> commits >> >> will address these issues. >> >> --- >> >> .../cooperative/SplitCooperativeAlgorithm.java | 160 >> >> ++++++++++++++------ >> >> 1 files changed, 117 insertions(+), 43 deletions(-) |
From: Gary P. <gpa...@gm...> - 2009-06-10 11:04:35
|
This has been resolved. On Friday 05 June 2009 07:38:19 Gary Pampara wrote: > Hi all, > > There seems to have been a bug introduced with the latest chages with the > GA. Minimisation seems to be failing. I'm not sure of the cause but will > have a look at it. > > Regards, > Gary > > --------------------------------------------------------------------------- >--- OpenSolaris 2009.06 is a cutting edge operating system for enterprises > looking to deploy the next generation of Solaris that includes the latest > innovations from Sun and the OpenSource community. Download a copy and > enjoy capabilities such as Networking, Storage and Virtualization. Go to: > http://p.sf.net/sfu/opensolaris-get > _______________________________________________ > cilib-devel mailing list > cil...@li... > https://lists.sourceforge.net/lists/listinfo/cilib-devel |
From: Gary P. <gpa...@gm...> - 2009-06-10 10:52:22
|
Sometimes the domain string may be specified with an invalid value. Some examples of this are: - R(8.0, 9.0)^0 (Zero exponent) - R(9.0, 9.0)^-1 (Negative exponent) - R(9.0, 8.0) (Lower bound is greater than upper bound) To correct this, the parser grammar was corrected. Tests have been added to verify the behaviour of the parser. Streamlined the domain registry by removing a member that is no longer used. Signed-off-by: Gary Pampara <gpa...@gm...> --- pom.xml | 3 +- .../cilib/type/StringBasedDomainRegistry.java | 36 +---- .../cilib/type/parser/DomainParserVisitorImpl.java | 85 ++++++++++- src/main/jjtree/parser.jjt | 10 +- .../sourceforge/cilib/type/DomainParserTest.java | 160 +++----------------- .../cilib/type/StringBasedDomainRegistryTest.java | 32 ++-- .../cilib/type/parser/DomainParserTest.java | 46 ++++++- 7 files changed, 177 insertions(+), 195 deletions(-) diff --git a/pom.xml b/pom.xml index d94420c..46704b7 100644 --- a/pom.xml +++ b/pom.xml @@ -165,8 +165,7 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>javacc-maven-plugin</artifactId> - <!--<version>2.5</version>--> - <version>2.4.1</version> + <version>2.5</version> <executions> <execution> <id>jjtree-javacc</id> diff --git a/src/main/java/net/sourceforge/cilib/type/StringBasedDomainRegistry.java b/src/main/java/net/sourceforge/cilib/type/StringBasedDomainRegistry.java index 4309009..4fc5c17 100644 --- a/src/main/java/net/sourceforge/cilib/type/StringBasedDomainRegistry.java +++ b/src/main/java/net/sourceforge/cilib/type/StringBasedDomainRegistry.java @@ -25,23 +25,16 @@ import java.util.logging.Level; import java.util.logging.Logger; import net.sourceforge.cilib.type.parser.ParseException; import net.sourceforge.cilib.type.types.container.StructuredType; -import net.sourceforge.cilib.type.types.container.Vector; /** * Class to perform the needed mappings between a top level domain string * and the built representation. * * @author Gary Pampara - * */ public class StringBasedDomainRegistry implements DomainRegistry { - - /** - * Generated <u>Serial Version UID</u> for the serialization. - */ private static final long serialVersionUID = 3821361290684036030L; private String domainString; -// private String expandedRepresentation; private StructuredType builtRepresenation; @@ -58,13 +51,13 @@ public class StringBasedDomainRegistry implements DomainRegistry { */ public StringBasedDomainRegistry(StringBasedDomainRegistry copy) { this.domainString = copy.domainString; -// this.expandedRepresentation = copy.expandedRepresentation; this.builtRepresenation = copy.builtRepresenation.getClone(); } /** * {@inheritDoc} */ + @Override public StringBasedDomainRegistry getClone() { return new StringBasedDomainRegistry(this); } @@ -72,6 +65,7 @@ public class StringBasedDomainRegistry implements DomainRegistry { /** * {@inheritDoc} */ + @Override public String getDomainString() { return domainString; } @@ -80,14 +74,11 @@ public class StringBasedDomainRegistry implements DomainRegistry { * Set the value of the string representing the domain. * @param domainString The domainString to set. */ + @Override public void setDomainString(String domainString) { this.domainString = domainString; try { -// DomainParser parser = new DomainParser(); -// parser.parse(domainString); -// setExpandedRepresentation(parser.expandDomainString(domainString)); -// setBuiltRepresenation(parser.getBuiltRepresentation()); - setBuiltRepresenation(net.sourceforge.cilib.type.parser.DomainParser.parse(domainString)); + this.builtRepresenation = net.sourceforge.cilib.type.parser.DomainParser.parse(domainString); } catch (ParseException ex) { Logger.getLogger(StringBasedDomainRegistry.class.getName()).log(Level.SEVERE, null, ex); } @@ -96,21 +87,7 @@ public class StringBasedDomainRegistry implements DomainRegistry { /** * {@inheritDoc} */ -// public String getExpandedRepresentation() { -// return expandedRepresentation; -// } - - /** - * Set the value of the expaded domain string. - * @param expandedRepresentation The expandedRepresentation to set. - */ -// public void setExpandedRepresentation(String expandedRepresentation) { -// this.expandedRepresentation = expandedRepresentation; -// } - - /** - * {@inheritDoc} - */ + @Override public StructuredType getBuiltRepresenation() { return this.builtRepresenation; } @@ -128,8 +105,9 @@ public class StringBasedDomainRegistry implements DomainRegistry { /** * {@inheritDoc} */ + @Override public int getDimension() { - return ((Vector) this.builtRepresenation).getDimension(); + return this.builtRepresenation.size(); } } diff --git a/src/main/java/net/sourceforge/cilib/type/parser/DomainParserVisitorImpl.java b/src/main/java/net/sourceforge/cilib/type/parser/DomainParserVisitorImpl.java index 66de851..c0079ee 100644 --- a/src/main/java/net/sourceforge/cilib/type/parser/DomainParserVisitorImpl.java +++ b/src/main/java/net/sourceforge/cilib/type/parser/DomainParserVisitorImpl.java @@ -35,17 +35,37 @@ import net.sourceforge.cilib.type.types.container.TypeList; */ public class DomainParserVisitorImpl implements DomainParserVisitor { + /** + * Top level visit operation - no actions are performed. + * @param node The abstract syntax tree node to visit. + * @param data The passed in data object. + * @return The result of the visit opertion. + */ @Override public Object visit(SimpleNode node, Object data) { return null; } + /** + * The root starting point of the grammar. No actions are performed apart from + * deferring to other production rules. + * @param node The abstract syntax tree node to visit. + * @param data The passed in data object. + * @return The result of the visit opertion. + */ @Override public Object visit(ASTrootElement node, Object data) { ASTelement element = (ASTelement) node.jjtGetChild(0); return element.jjtAccept(this, data); } + /** + * Obtain the results of the visitation of the {@code domainElement} + * and any possible {@code repeat}s. + * @param node The abstract syntax tree node to visit. + * @param data The passed in data object. + * @return The result of the visit opertion. + */ @Override public Object visit(ASTelement node, Object data) { ASTdomainElement domainElement = (ASTdomainElement) node.jjtGetChild(0); @@ -59,6 +79,13 @@ public class DomainParserVisitorImpl implements DomainParserVisitor { return null; } + /** + * Obtain the data from the domainElement. Actual types are constructed based + * on the determined type, bounds and exponent values. + * @param node The abstract syntax tree node to visit. + * @param data The passed in data object. + * @return The result of the visit opertion. + */ @Override public Object visit(ASTdomainElement node, Object data) { int children = node.jjtGetNumChildren(); @@ -85,14 +112,18 @@ public class DomainParserVisitorImpl implements DomainParserVisitor { if (dimensionOrExponent instanceof ASTexponent) { exponent = getExponent(node, data, 1); } - } expandDomain(creator, bounds, exponent, data); - return null; } + /** + * Obtain the type defined in the portion of the domain string. + * @param node The abstract syntax tree node to visit. + * @param data The passed in data object. + * @return The result of the visit opertion. + */ @Override public Object visit(ASTtype node, Object data) { DomainNode domainNode = (DomainNode) node.jjtGetChild(0); @@ -103,31 +134,51 @@ public class DomainParserVisitorImpl implements DomainParserVisitor { Class<?> creatorClass = Class.forName("net.sourceforge.cilib.type.creator." + domainNode.getValue()); instance = (TypeCreator) creatorClass.newInstance(); } catch (ClassNotFoundException ex) { + ex.printStackTrace(); } catch (InstantiationException ex) { + ex.printStackTrace(); } catch (IllegalAccessException ex) { + ex.printStackTrace(); } return instance; } + /** + * Extract the exponent value for the portion of the domain string. + * @param node The abstract syntax tree node to visit. + * @param data The passed in data object. + * @return The result of the visit opertion. + */ @Override public Object visit(ASTexponent node, Object data) { DomainNode domainNode = (DomainNode) node.jjtGetChild(0); return domainNode.getValue(); } + /** + * Determine the dimension elements of the potion of the domain string. + * @param node The abstract syntax tree node to visit. + * @param data The passed in data object. + * @return The result of the visit opertion. + */ @Override public Object visit(ASTdimension node, Object data) { ASTlowerDim lowerDim = (ASTlowerDim) node.jjtGetChild(0); return lowerDim.jjtAccept(this, data); } + /** + * Extract the lower bounds information from the portion of the domain string. + * @param node The abstract syntax tree node to visit. + * @param data The passed in data object. + * @return The result of the visit opertion. + */ @Override public Object visit(ASTlowerDim node, Object data) { List<Double> bounds = new ArrayList<Double>(); ASTnumber number1 = (ASTnumber) node.jjtGetChild(0); - Double value1 = Double.valueOf((String) number1.jjtAccept(this, data)); bounds.add(value1); @@ -136,6 +187,10 @@ public class DomainParserVisitorImpl implements DomainParserVisitor { ASTupperDim upper = (ASTupperDim) remainder; Double value2 = Double.valueOf((String) upper.jjtAccept(this, data)); bounds.add(value2); + + if (value1.compareTo(value2) > 0) + throw new UnsupportedOperationException("Parsed bound values are not in order." + + "Upper bound is less than lower bound."); } if (remainder instanceof ASTvalue) { @@ -146,24 +201,48 @@ public class DomainParserVisitorImpl implements DomainParserVisitor { return bounds; } + /** + * Obtain the value for the upper bound and return it. + * @param node The abstract syntax tree node to visit. + * @param data The passed in data object. + * @return The result of the visit opertion. + */ @Override public Object visit(ASTupperDim node, Object data) { ASTnumber number = (ASTnumber) node.jjtGetChild(0); return number.jjtAccept(this, data); } + /** + * Perfrom no actions. This is a terminal node for bounds. + * @param node The abstract syntax tree node to visit. + * @param data The passed in data object. + * @return {@code null} - no action is performed. + */ @Override public Object visit(ASTvalue node, Object data) { // Nothing to be done as this is a terminal node that simply ends a statement. return null; } + /** + * Apply the repeat action as defined in the grammar. + * @param node The abstract syntax tree node to visit. + * @param data The passed in data object. + * @return The result of the visit opertion. + */ @Override public Object visit(ASTrepeat node, Object data) { ASTelement element = (ASTelement) node.jjtGetChild(0); return element.jjtAccept(this, data); } + /** + * Extract the number that is defined in the domain string. + * @param node The abstract syntax tree node to visit. + * @param data The passed in data object. + * @return The result of the visit opertion. + */ @Override public Object visit(ASTnumber node, Object data) { DomainNode domainNode = (DomainNode) node.jjtGetChild(0); diff --git a/src/main/jjtree/parser.jjt b/src/main/jjtree/parser.jjt index aeb3423..00da3ba 100644 --- a/src/main/jjtree/parser.jjt +++ b/src/main/jjtree/parser.jjt @@ -62,21 +62,21 @@ ASTrootElement rootElement() : {} { element() <EOF> { return jjtThis; }} void element() : {} { domainElement() (repeat())? } void domainElement() : {} { type() (dimension() (exponent())? | exponent())? } void type() : { Token t = null; } { t=<TYPE> {jjtThis.jjtAddChild(new DomainNode(t.image), 0);}} -void exponent() : { Token t = null; } { <EXPONENT> t=<INTEGER> {jjtThis.jjtAddChild(new DomainNode(t.image), 0);}} +void exponent() : { Token t = null; } { <EXPONENT> t=<POSITIVE_INTEGER> {jjtThis.jjtAddChild(new DomainNode(t.image), 0);}} void dimension() : {} { lowerDim() } void lowerDim() : {} { "(" number() ( upperDim() | value() ) } void upperDim() : {} { "," number() ")" } void value() : {} { ")" } void repeat() : {} { "," element() } void number() : { Token t = null; } { - (t=<NUMBER> | t=<INTEGER>) { jjtThis.jjtAddChild(new DomainNode(t.image), 0);} -| <MINUS> (t=<NUMBER> | t=<INTEGER>) {jjtThis.jjtAddChild(new DomainNode("-"+t.image), 0);} + (t=<POSITIVE_INTEGER> | t=<NUMBER>) { jjtThis.jjtAddChild(new DomainNode(t.image), 0);} +| <MINUS> (t=<POSITIVE_INTEGER> | t=<NUMBER>) {jjtThis.jjtAddChild(new DomainNode("-"+t.image), 0);} } SKIP : { " " | "\t" | "\n" | "\r" } TOKEN : { - < INTEGER : (<DIGIT>)+ > -| < NUMBER : <INTEGER> ( "." <INTEGER> )? > + < POSITIVE_INTEGER : (["1"-"9"]) (<DIGIT>)* > +| < NUMBER : (<DIGIT>)+ ( "." (<DIGIT>)+ )? > | < DIGIT : ["0"-"9"] > | < TYPE : ( "R" | "B" | "Z" | "T" ) > | < MINUS : "-" > diff --git a/src/test/java/net/sourceforge/cilib/type/DomainParserTest.java b/src/test/java/net/sourceforge/cilib/type/DomainParserTest.java index 0e8894d..d2a1362 100644 --- a/src/test/java/net/sourceforge/cilib/type/DomainParserTest.java +++ b/src/test/java/net/sourceforge/cilib/type/DomainParserTest.java @@ -23,7 +23,8 @@ package net.sourceforge.cilib.type; import net.sourceforge.cilib.type.parser.ParseException; -import static org.junit.Assert.fail; +import net.sourceforge.cilib.type.types.container.Vector; +import org.junit.Assert; import org.junit.Test; @@ -35,162 +36,43 @@ public class DomainParserTest { @Test public void testParseReal() throws ParseException { -// DomainParser parser = new DomainParser(); -// try { -// parser.parse("R(0,INF)"); -// parser.parse("R"); -// assertEquals("R", parser.expandDomainString("R")); -// parser.parse("R^6"); -// assertEquals("R,R,R,R,R,R", parser.expandDomainString("R^6")); -// parser.parse("R(-9,9)"); -// assertEquals("R(-9.0,9.0)", parser.expandDomainString("R(-9,9)")); -// parser.parse("R(-30.0,30.0)^6"); -// assertEquals("R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0)", parser.expandDomainString("R(-30.0,30.0)^6")); - net.sourceforge.cilib.type.parser.DomainParser.parse("R(0.0,9.0)"); - net.sourceforge.cilib.type.parser.DomainParser.parse("R"); -// assertEquals("R", parser.expandDomainString("R")); - net.sourceforge.cilib.type.parser.DomainParser.parse("R^6"); -// assertEquals("R,R,R,R,R,R", parser.expandDomainString("R^6")); - net.sourceforge.cilib.type.parser.DomainParser.parse("R(-9.0,9.0)"); -// assertEquals("R(-9.0,9.0)", parser.expandDomainString("R(-9,9)")); - net.sourceforge.cilib.type.parser.DomainParser.parse("R(-30.0,30.0)^6"); -// assertEquals("R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0)", parser.expandDomainString("R(-30.0,30.0)^6")); -// } -// catch (Exception e) { -// fail("Parser cannot handle parsing of R! " + e.getMessage()); -// } + net.sourceforge.cilib.type.parser.DomainParser.parse("R(0.0,9.0)"); + net.sourceforge.cilib.type.parser.DomainParser.parse("R"); + net.sourceforge.cilib.type.parser.DomainParser.parse("R^6"); + net.sourceforge.cilib.type.parser.DomainParser.parse("R(-9.0,9.0)"); + net.sourceforge.cilib.type.parser.DomainParser.parse("R(-30.0,30.0)^6"); } @Test public void testParseBit() throws ParseException { -// DomainParser parser = new DomainParser(); - net.sourceforge.cilib.type.parser.DomainParser.parse("B"); - net.sourceforge.cilib.type.parser.DomainParser.parse("B^6"); - -// parser.parse("B"); -// assertEquals("B", parser.expandDomainString("B")); -// parser.parse("B^6"); -// assertEquals("B,B,B,B,B,B", parser.expandDomainString("B^6")); + net.sourceforge.cilib.type.parser.DomainParser.parse("B"); + net.sourceforge.cilib.type.parser.DomainParser.parse("B^6"); } @Test public void testParseInteger() throws ParseException { -// DomainParser parser = new DomainParser(); - net.sourceforge.cilib.type.parser.DomainParser.parse("Z"); -// parser.parse("Z"); -// assertEquals("Z", parser.expandDomainString("Z")); - net.sourceforge.cilib.type.parser.DomainParser.parse("Z(-1,0)"); -// assertEquals("Z(-1.0,0.0)", parser.expandDomainString("Z(-1,0)")); - net.sourceforge.cilib.type.parser.DomainParser.parse("Z(0,1)"); -// assertEquals("Z(0.0,1.0)", parser.expandDomainString("Z(0,1)")); - net.sourceforge.cilib.type.parser.DomainParser.parse("Z(-999,999)"); -// assertEquals("Z(-999.0,999.0)", parser.expandDomainString("Z(-999,999)")); - net.sourceforge.cilib.type.parser.DomainParser.parse("Z^8"); -// assertEquals("Z,Z,Z,Z,Z,Z,Z,Z", parser.expandDomainString("Z^8")); - net.sourceforge.cilib.type.parser.DomainParser.parse("Z(0,1)^10"); -// assertEquals("Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0)", parser.expandDomainString("Z(0,1)^10")); + net.sourceforge.cilib.type.parser.DomainParser.parse("Z"); + net.sourceforge.cilib.type.parser.DomainParser.parse("Z(-1,0)"); + net.sourceforge.cilib.type.parser.DomainParser.parse("Z(0,1)"); + net.sourceforge.cilib.type.parser.DomainParser.parse("Z(-999,999)"); + net.sourceforge.cilib.type.parser.DomainParser.parse("Z^8"); + net.sourceforge.cilib.type.parser.DomainParser.parse("Z(0,1)^10"); } @Test - public void testParseString() { -// DomainParser parser = new DomainParser(); - try { - net.sourceforge.cilib.type.parser.DomainParser.parse("T^5"); -// assertEquals("T,T,T,T,T", parser.expandDomainString("T^5")); - } - catch (Exception e) { - fail("Parser cannot handle parsing of T! " + e.getMessage()); - } + public void testParseString() throws ParseException { + net.sourceforge.cilib.type.parser.DomainParser.parse("T^5"); } @Test - public void testParseComplexDomain() { -// DomainParser parser = new DomainParser(); - try { - net.sourceforge.cilib.type.parser.DomainParser.parse("R(-30.0,30.0)^30,B,Z^6"); -// assertEquals("R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),B,Z,Z,Z,Z,Z,Z", -// parser.expandDomainString("R(-30.0,30.0)^30,B,Z^6")); - } - catch (Exception e) { - fail("Parser cannot handle parsing of a complex domain! " + e.getMessage()); - } - } - - - /** - * This test determines if the parser can successfully parse and build - * domains that can be represented as a matrix (also regarded as second order - * domains). - */ -// @Test -// public void testParseMatrixDomain() { -// DomainParser parser = new DomainParser(); -// try { -// parser.parse("[R(-30.0,30.0)^4]^5,B,B,Z(2,5)"); -// assertEquals("[R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0)],[R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0)],[R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0)],[R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0)],[R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0)],B,B,Z(2.0,5.0)", -// parser.expandDomainString("[R(-30.0,30.0)^4]^5,B,B,Z(2,5)")); -// } -// catch (Exception e) { -// fail("Parser cannot handle martix representation domains! " + e.getMessage()); -// } -// } + public void testParseComplexDomain() throws ParseException { + Vector vector = (Vector) net.sourceforge.cilib.type.parser.DomainParser.parse("R(-30.0,30.0)^30,B,Z^6"); - -// @Test -// public void testBuildMatrixDomain() { -// DomainParser parser = new DomainParser(); -// try { -// parser.parse("[R(-30.0,30.0)^4]^5"); -// -// TypeList matrix = (TypeList) parser.getBuiltRepresentation(); -// -// // Test the dimensionality -// assertEquals(5, matrix.size()); -// -// for (int i = 0; i < matrix.size(); i++) { -// assertEquals(4, ((TypeList)matrix.get(i)).size()); -// } -// -// // Test object equality -// Vector v1 = (Vector) matrix.get(0); -// Vector v2 = (Vector) matrix.get(1); -// Vector v3 = (Vector) matrix.get(2); -// Vector v4 = (Vector) matrix.get(3); -// Vector v5 = (Vector) matrix.get(4); -// -// assertTrue(assertObjectNotSame(v1, v2)); -// assertTrue(assertObjectNotSame(v1, v3)); -// assertTrue(assertObjectNotSame(v1, v4)); -// assertTrue(assertObjectNotSame(v1, v5)); -// assertTrue(assertObjectNotSame(v2, v3)); -// assertTrue(assertObjectNotSame(v2, v4)); -// assertTrue(assertObjectNotSame(v2, v5)); -// assertTrue(assertObjectNotSame(v3, v4)); -// assertTrue(assertObjectNotSame(v3, v4)); -// assertTrue(assertObjectNotSame(v4, v5)); -// } catch (Exception e) { -// -// } -// } - - /** - * - * @param v1 - * @param v2 - * @return - */ -// private boolean assertObjectNotSame(Vector v1, Vector v2) { - -// for (int i = 0; i < v1.getDimension(); i++) { -// if (v1.get(i).equals(v2.get(i))) -// return false; -// } -// -// return true; -// } + Assert.assertEquals(37, vector.size()); + } } diff --git a/src/test/java/net/sourceforge/cilib/type/StringBasedDomainRegistryTest.java b/src/test/java/net/sourceforge/cilib/type/StringBasedDomainRegistryTest.java index 56104da..34c52e7 100644 --- a/src/test/java/net/sourceforge/cilib/type/StringBasedDomainRegistryTest.java +++ b/src/test/java/net/sourceforge/cilib/type/StringBasedDomainRegistryTest.java @@ -4,17 +4,17 @@ * Department of Computer Science * University of Pretoria * South Africa - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program 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 General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -22,23 +22,25 @@ package net.sourceforge.cilib.type; -import org.junit.Ignore; +import net.sourceforge.cilib.type.types.TypeUtil; +import net.sourceforge.cilib.type.types.container.StructuredType; +import org.junit.Assert; +import org.junit.Test; /** * * @author gpampara */ -@Ignore public class StringBasedDomainRegistryTest { -// @Test -// public void matrixCreation() { -// DomainRegistry registry = new StringBasedDomainRegistry(); -// registry.setDomainString("[R(-5.0, 5.0)^10]^10"); -// -// TypeList matrix = (TypeList) registry.getBuiltRepresenation(); -// Assert.assertEquals(10, matrix.size()); -// Assert.assertEquals(10, ((TypeList) matrix.get(0)).size()); -// Assert.assertTrue(TypeUtil.isInsideBounds(matrix)); -// } + @Test + public void structureExists() { + DomainRegistry registry = new StringBasedDomainRegistry(); + registry.setDomainString("R(-30.0, 30)^30"); + + StructuredType<?> structure = registry.getBuiltRepresenation(); + Assert.assertEquals(30, structure.size()); + Assert.assertTrue(TypeUtil.isInsideBounds(structure)); + } + } diff --git a/src/test/java/net/sourceforge/cilib/type/parser/DomainParserTest.java b/src/test/java/net/sourceforge/cilib/type/parser/DomainParserTest.java index 3dd25e5..e71a7bf 100644 --- a/src/test/java/net/sourceforge/cilib/type/parser/DomainParserTest.java +++ b/src/test/java/net/sourceforge/cilib/type/parser/DomainParserTest.java @@ -27,11 +27,15 @@ import org.junit.Assert; import org.junit.Test; /** - * + * Tests related to the parsing of domain strings. * @author gpampara */ public class DomainParserTest { + /** + * Creation of {@code StringType}. + * @throws ParseException if an exception occurs during parsing. + */ @Test public void stringType() throws ParseException { StructuredType vector = DomainParser.parse("T"); @@ -39,8 +43,12 @@ public class DomainParserTest { Assert.assertEquals(1, vector.size()); } + /** + * The default kind of domain string that would be quite common. + * @throws ParseException + */ @Test - public void test() throws ParseException { + public void dimensionRange() throws ParseException { Vector vector = (Vector) DomainParser.parse("R(-9.0, 9.0)^6"); Assert.assertEquals(6, vector.size()); @@ -83,4 +91,38 @@ public class DomainParserTest { Assert.assertEquals(10, vector.size()); } + + @Test(expected=TokenMgrError.class) + public void invalidDomain() throws ParseException { + DomainParser.parse("Y"); + } + + @Test(expected=ParseException.class) + public void parseNotValid() throws ParseException { + DomainParser.parse("R(-5, -4, -5)^-7"); + } + + @Test(expected=ParseException.class) + public void negativeExponent() throws ParseException { + DomainParser.parse("R^-9"); + } + + @Test(expected=ParseException.class) + public void zeroExponent() throws ParseException { + DomainParser.parse("R^0"); + } + + @Test + public void integerBounds() throws ParseException { + DomainParser.parse("R(1,3)"); + DomainParser.parse("R(-1,3)"); + DomainParser.parse("R(-3,-1)"); + DomainParser.parse("R(-3,-1)^9"); + } + + @Test(expected=UnsupportedOperationException.class) + public void incorrectBoundsOrder() throws ParseException { + DomainParser.parse("R(3, 2)"); // Lower bound > Upper bound = WRONG! + } + } -- 1.6.2.3 |
From: Gary P. <gpa...@gm...> - 2009-06-10 10:52:21
|
Defining the Domain parser within a grammar file and letting the parser be generated is infinitely more useful than the old manner in which we defined the parser. The JavaCC grammar may be might not be the best, but it's a step in the right direction. Signed-off-by: Gary Pampara <gpa...@gm...> --- pom.xml | 14 ++ .../bioinf/sequencealignment/BinaryMSAProblem.java | 12 +- .../cilib/bioinf/sequencealignment/MSAProblem.java | 5 +- .../controlparameter/BoundedControlParameter.java | 12 +- .../functions/discrete/KnightCoverageProblem.java | 1 - .../cilib/problem/ClusteringProblem.java | 5 +- .../CooperativeOptimisationProblemAdapter.java | 21 ++- .../net/sourceforge/cilib/type/DomainBuilder.java | 2 + .../net/sourceforge/cilib/type/DomainParser.java | 2 + .../net/sourceforge/cilib/type/DomainRegistry.java | 2 +- .../sourceforge/cilib/type/DomainValidator.java | 1 + .../cilib/type/StringBasedDomainRegistry.java | 34 ++-- .../java/net/sourceforge/cilib/type/creator/B.java | 16 +- .../java/net/sourceforge/cilib/type/creator/R.java | 8 + .../java/net/sourceforge/cilib/type/creator/T.java | 7 + .../cilib/type/creator/TypeCreator.java | 7 + .../java/net/sourceforge/cilib/type/creator/Z.java | 9 + .../cilib/type/parser/DomainParserVisitorImpl.java | 193 ++++++++++++++++ src/main/jjtree/parser.jjt | 89 ++++++-- .../cilib/measurement/generic/IterationsTest.java | 10 +- .../generic/PercentageCompleteTest.java | 10 +- .../cilib/measurement/generic/RestartsTest.java | 10 +- .../cilib/measurement/generic/TimeTest.java | 10 +- .../measurement/multiple/MultipleFitnessTest.java | 10 +- .../multiple/MultipleSolutionsTest.java | 10 +- .../single/BestParticlePositionTest.java | 14 +- .../cilib/measurement/single/DiameterTest.java | 10 +- .../measurement/single/FitnessEvaluationsTest.java | 10 +- .../cilib/measurement/single/FitnessTest.java | 10 +- .../single/FunctionOptimisationErrorTest.java | 12 +- .../measurement/single/ParticlePositionsTest.java | 10 +- .../cilib/measurement/single/SolutionTest.java | 12 +- .../sourceforge/cilib/type/DomainParserTest.java | 233 ++++++++++---------- .../cilib/type/StringBasedDomainRegistryTest.java | 26 +-- .../cilib/type/parser/DomainParserTest.java | 86 +++++++ 35 files changed, 644 insertions(+), 279 deletions(-) create mode 100644 src/main/java/net/sourceforge/cilib/type/parser/DomainParserVisitorImpl.java create mode 100644 src/test/java/net/sourceforge/cilib/type/parser/DomainParserTest.java diff --git a/pom.xml b/pom.xml index ead9cc4..d94420c 100644 --- a/pom.xml +++ b/pom.xml @@ -163,6 +163,20 @@ <version>2.4.2</version> </plugin> <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>javacc-maven-plugin</artifactId> + <!--<version>2.5</version>--> + <version>2.4.1</version> + <executions> + <execution> + <id>jjtree-javacc</id> + <goals> + <goal>jjtree-javacc</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptors> diff --git a/src/main/java/net/sourceforge/cilib/bioinf/sequencealignment/BinaryMSAProblem.java b/src/main/java/net/sourceforge/cilib/bioinf/sequencealignment/BinaryMSAProblem.java index 58148af..b1b1671 100644 --- a/src/main/java/net/sourceforge/cilib/bioinf/sequencealignment/BinaryMSAProblem.java +++ b/src/main/java/net/sourceforge/cilib/bioinf/sequencealignment/BinaryMSAProblem.java @@ -26,9 +26,10 @@ import java.util.Collection; import net.sourceforge.cilib.problem.Fitness; import net.sourceforge.cilib.problem.MaximisationFitness; import net.sourceforge.cilib.problem.OptimisationProblemAdapter; -import net.sourceforge.cilib.type.DomainParser; import net.sourceforge.cilib.type.DomainRegistry; import net.sourceforge.cilib.type.StringBasedDomainRegistry; +import net.sourceforge.cilib.type.parser.DomainParser; +import net.sourceforge.cilib.type.parser.ParseException; import net.sourceforge.cilib.type.types.Type; import net.sourceforge.cilib.type.types.container.Vector; @@ -163,7 +164,7 @@ public class BinaryMSAProblem extends OptimisationProblemAdapter { */ public DomainRegistry getDomain() { //computes the domain according to the input sequences and amount of gaps to insert if (this.domainRegistry.getDomainString() == null) { - DomainParser parser = new DomainParser(); +// DomainParser parser = new DomainParser(); //reads in the input data sets. FASTADataSetBuilder stringBuilder = (FASTADataSetBuilder) this.getDataSetBuilder(); @@ -207,7 +208,12 @@ public class BinaryMSAProblem extends OptimisationProblemAdapter { System.out.println("Domain: "+rep); //extra for debug, can be commented out - parser.parse(rep); + try { + //extra for debug, can be commented out +// parser.parse(rep); + DomainParser.parse(rep); + } catch (ParseException ex) { + } domainRegistry.setDomainString(rep); } diff --git a/src/main/java/net/sourceforge/cilib/bioinf/sequencealignment/MSAProblem.java b/src/main/java/net/sourceforge/cilib/bioinf/sequencealignment/MSAProblem.java index 1e9f690..ed2d2d2 100644 --- a/src/main/java/net/sourceforge/cilib/bioinf/sequencealignment/MSAProblem.java +++ b/src/main/java/net/sourceforge/cilib/bioinf/sequencealignment/MSAProblem.java @@ -26,7 +26,6 @@ import java.util.Collection; import net.sourceforge.cilib.problem.Fitness; import net.sourceforge.cilib.problem.MaximisationFitness; import net.sourceforge.cilib.problem.OptimisationProblemAdapter; -import net.sourceforge.cilib.type.DomainParser; import net.sourceforge.cilib.type.DomainRegistry; import net.sourceforge.cilib.type.StringBasedDomainRegistry; import net.sourceforge.cilib.type.types.Type; @@ -118,7 +117,7 @@ public class MSAProblem extends OptimisationProblemAdapter { public DomainRegistry getDomain() { //computes the domain according to the input sequences and amount of gaps to insert if (this.domainRegistry.getDomainString() == null) { - DomainParser parser = new DomainParser(); +// DomainParser parser = new DomainParser(); //reads in the input data sets. FASTADataSetBuilder stringBuilder = (FASTADataSetBuilder) this.getDataSetBuilder(); @@ -163,7 +162,7 @@ public class MSAProblem extends OptimisationProblemAdapter { System.out.println("Domain: "+rep); //extra for debug, can be commented out - parser.parse(rep); +// parser.parse(rep); domainRegistry.setDomainString(rep); } diff --git a/src/main/java/net/sourceforge/cilib/controlparameter/BoundedControlParameter.java b/src/main/java/net/sourceforge/cilib/controlparameter/BoundedControlParameter.java index b10557e..f864cb3 100644 --- a/src/main/java/net/sourceforge/cilib/controlparameter/BoundedControlParameter.java +++ b/src/main/java/net/sourceforge/cilib/controlparameter/BoundedControlParameter.java @@ -21,9 +21,9 @@ */ package net.sourceforge.cilib.controlparameter; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; +import net.sourceforge.cilib.type.parser.ParseException; import net.sourceforge.cilib.type.types.Bounds; -import net.sourceforge.cilib.type.types.BoundsFactory; import net.sourceforge.cilib.type.types.Real; import net.sourceforge.cilib.type.types.container.Vector; @@ -167,11 +167,11 @@ public abstract class BoundedControlParameter implements ControlParameter { * Set the range of the parameter. * @param range The domain string representing the range. */ - public void setRange(String range) { + public void setRange(String range) throws ParseException { this.range = range; - DomainParser parser = new DomainParser(); - parser.parse(this.range); - Vector v = (Vector) parser.getBuiltRepresentation(); + Vector v = (Vector) DomainParser.parse(this.range); +// parser.parse(this.range); +// Vector v = (Vector) parser.getBuiltRepresentation(); if (v.getDimension() != 1) throw new RuntimeException("Range incorrect in BoundedUpdateStrategy! Please correct"); diff --git a/src/main/java/net/sourceforge/cilib/functions/discrete/KnightCoverageProblem.java b/src/main/java/net/sourceforge/cilib/functions/discrete/KnightCoverageProblem.java index d34fc3e..3aaf649 100644 --- a/src/main/java/net/sourceforge/cilib/functions/discrete/KnightCoverageProblem.java +++ b/src/main/java/net/sourceforge/cilib/functions/discrete/KnightCoverageProblem.java @@ -24,7 +24,6 @@ package net.sourceforge.cilib.functions.discrete; import net.sourceforge.cilib.problem.Fitness; import net.sourceforge.cilib.problem.MinimisationFitness; import net.sourceforge.cilib.problem.OptimisationProblemAdapter; -import net.sourceforge.cilib.type.DomainParser; import net.sourceforge.cilib.type.DomainRegistry; import net.sourceforge.cilib.type.types.Type; import net.sourceforge.cilib.type.types.container.Vector; diff --git a/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java b/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java index 75b2a11..df99a21 100644 --- a/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java +++ b/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java @@ -25,7 +25,6 @@ import net.sourceforge.cilib.problem.dataset.AssociatedPairDataSetBuilder; import net.sourceforge.cilib.problem.dataset.ClusterableDataSet; import net.sourceforge.cilib.problem.dataset.DataSetBuilder; import net.sourceforge.cilib.problem.dataset.DataSetManager; -import net.sourceforge.cilib.type.DomainParser; import net.sourceforge.cilib.type.DomainRegistry; import net.sourceforge.cilib.type.StringBasedDomainRegistry; import net.sourceforge.cilib.type.types.Type; @@ -227,8 +226,8 @@ public class ClusteringProblem extends OptimisationProblemAdapter { * clustered */ public void setDomain(String representation) { - DomainParser parser = new DomainParser();//DomainParser.getInstance(); - parser.parse(representation); +// DomainParser parser = new DomainParser();//DomainParser.getInstance(); +// parser.parse(representation); domainRegistry.setDomainString(representation); regenerateDomain(); diff --git a/src/main/java/net/sourceforge/cilib/problem/CooperativeOptimisationProblemAdapter.java b/src/main/java/net/sourceforge/cilib/problem/CooperativeOptimisationProblemAdapter.java index 8d45549..37fee26 100644 --- a/src/main/java/net/sourceforge/cilib/problem/CooperativeOptimisationProblemAdapter.java +++ b/src/main/java/net/sourceforge/cilib/problem/CooperativeOptimisationProblemAdapter.java @@ -21,11 +21,13 @@ */ package net.sourceforge.cilib.problem; -import net.sourceforge.cilib.algorithm.InitialisationException; +import java.util.logging.Level; +import java.util.logging.Logger; import net.sourceforge.cilib.cooperative.CooperativeEntity; -import net.sourceforge.cilib.type.DomainParser; import net.sourceforge.cilib.type.DomainRegistry; import net.sourceforge.cilib.type.StringBasedDomainRegistry; +import net.sourceforge.cilib.type.parser.DomainParser; +import net.sourceforge.cilib.type.parser.ParseException; import net.sourceforge.cilib.type.types.Type; import net.sourceforge.cilib.type.types.TypeUtil; import net.sourceforge.cilib.type.types.container.Vector; @@ -65,12 +67,17 @@ public class CooperativeOptimisationProblemAdapter extends OptimisationProblemAd if (i < offset + dimension - 1) expandedDomain += ","; } - DomainParser dp = new DomainParser(); - if (dp.parse(expandedDomain)) { - domainRegistry.setDomainString(expandedDomain); + try { +// DomainParser dp = new DomainParser(); +// if (dp.parse(expandedDomain)) { +// domainRegistry.setDomainString(expandedDomain); +// } +// else +// throw new InitialisationException("The expanded domain string \"" + expandedDomain + "\" could not be parsed."); + DomainParser.parse(expandedDomain); + } catch (ParseException ex) { + Logger.getLogger(CooperativeOptimisationProblemAdapter.class.getName()).log(Level.SEVERE, null, ex); } - else - throw new InitialisationException("The expanded domain string \"" + expandedDomain + "\" could not be parsed."); } public CooperativeOptimisationProblemAdapter(CooperativeOptimisationProblemAdapter copy) { diff --git a/src/main/java/net/sourceforge/cilib/type/DomainBuilder.java b/src/main/java/net/sourceforge/cilib/type/DomainBuilder.java index f6a4637..4c44d67 100644 --- a/src/main/java/net/sourceforge/cilib/type/DomainBuilder.java +++ b/src/main/java/net/sourceforge/cilib/type/DomainBuilder.java @@ -52,7 +52,9 @@ import net.sourceforge.cilib.type.types.container.Vector; * </ul> * * @author Gary Pampara + * @deprecated in favor of the JavaCC generated parser. */ +@Deprecated public class DomainBuilder { private TypeList representation; diff --git a/src/main/java/net/sourceforge/cilib/type/DomainParser.java b/src/main/java/net/sourceforge/cilib/type/DomainParser.java index b3c918e..abfb06a 100644 --- a/src/main/java/net/sourceforge/cilib/type/DomainParser.java +++ b/src/main/java/net/sourceforge/cilib/type/DomainParser.java @@ -29,7 +29,9 @@ import net.sourceforge.cilib.type.types.container.StructuredType; * represenation. * * @author Gary Pampara + * @deprecated in favor of the JavaCC generated parser. */ +@Deprecated public final class DomainParser { private DomainBuilder builder; diff --git a/src/main/java/net/sourceforge/cilib/type/DomainRegistry.java b/src/main/java/net/sourceforge/cilib/type/DomainRegistry.java index 6f512ff..d5f765b 100644 --- a/src/main/java/net/sourceforge/cilib/type/DomainRegistry.java +++ b/src/main/java/net/sourceforge/cilib/type/DomainRegistry.java @@ -56,7 +56,7 @@ public interface DomainRegistry extends Cloneable, Serializable { * a dimensional string with a descriptve component for each dimension. * @return Returns the expandedRepresentation. */ - public String getExpandedRepresentation(); +// public String getExpandedRepresentation(); /** * Get the instance of the built representation for this domain string. diff --git a/src/main/java/net/sourceforge/cilib/type/DomainValidator.java b/src/main/java/net/sourceforge/cilib/type/DomainValidator.java index 4cc662f..bfed51d 100644 --- a/src/main/java/net/sourceforge/cilib/type/DomainValidator.java +++ b/src/main/java/net/sourceforge/cilib/type/DomainValidator.java @@ -52,6 +52,7 @@ import java.util.ArrayList; * where <tt>[]</tt> represents an empty string. * * @author Gary Pampara + * @deprecated in favor of the JavaCC generated parser. */ public class DomainValidator { diff --git a/src/main/java/net/sourceforge/cilib/type/StringBasedDomainRegistry.java b/src/main/java/net/sourceforge/cilib/type/StringBasedDomainRegistry.java index a19605c..4309009 100644 --- a/src/main/java/net/sourceforge/cilib/type/StringBasedDomainRegistry.java +++ b/src/main/java/net/sourceforge/cilib/type/StringBasedDomainRegistry.java @@ -21,6 +21,9 @@ */ package net.sourceforge.cilib.type; +import java.util.logging.Level; +import java.util.logging.Logger; +import net.sourceforge.cilib.type.parser.ParseException; import net.sourceforge.cilib.type.types.container.StructuredType; import net.sourceforge.cilib.type.types.container.Vector; @@ -38,7 +41,7 @@ public class StringBasedDomainRegistry implements DomainRegistry { */ private static final long serialVersionUID = 3821361290684036030L; private String domainString; - private String expandedRepresentation; +// private String expandedRepresentation; private StructuredType builtRepresenation; @@ -55,7 +58,7 @@ public class StringBasedDomainRegistry implements DomainRegistry { */ public StringBasedDomainRegistry(StringBasedDomainRegistry copy) { this.domainString = copy.domainString; - this.expandedRepresentation = copy.expandedRepresentation; +// this.expandedRepresentation = copy.expandedRepresentation; this.builtRepresenation = copy.builtRepresenation.getClone(); } @@ -79,28 +82,31 @@ public class StringBasedDomainRegistry implements DomainRegistry { */ public void setDomainString(String domainString) { this.domainString = domainString; - - DomainParser parser = new DomainParser(); - parser.parse(domainString); - - setExpandedRepresentation(parser.expandDomainString(domainString)); - setBuiltRepresenation(parser.getBuiltRepresentation()); + try { +// DomainParser parser = new DomainParser(); +// parser.parse(domainString); +// setExpandedRepresentation(parser.expandDomainString(domainString)); +// setBuiltRepresenation(parser.getBuiltRepresentation()); + setBuiltRepresenation(net.sourceforge.cilib.type.parser.DomainParser.parse(domainString)); + } catch (ParseException ex) { + Logger.getLogger(StringBasedDomainRegistry.class.getName()).log(Level.SEVERE, null, ex); + } } /** * {@inheritDoc} */ - public String getExpandedRepresentation() { - return expandedRepresentation; - } +// public String getExpandedRepresentation() { +// return expandedRepresentation; +// } /** * Set the value of the expaded domain string. * @param expandedRepresentation The expandedRepresentation to set. */ - public void setExpandedRepresentation(String expandedRepresentation) { - this.expandedRepresentation = expandedRepresentation; - } +// public void setExpandedRepresentation(String expandedRepresentation) { +// this.expandedRepresentation = expandedRepresentation; +// } /** * {@inheritDoc} diff --git a/src/main/java/net/sourceforge/cilib/type/creator/B.java b/src/main/java/net/sourceforge/cilib/type/creator/B.java index 525ebb7..b4a0f39 100644 --- a/src/main/java/net/sourceforge/cilib/type/creator/B.java +++ b/src/main/java/net/sourceforge/cilib/type/creator/B.java @@ -30,15 +30,12 @@ import net.sourceforge.cilib.type.types.Type; * */ public final class B implements TypeCreator { - - /** - * - */ private static final long serialVersionUID = 7124782787032789332L; /** * {@inheritDoc} */ + @Override public Type create() { return new Bit(); } @@ -46,6 +43,17 @@ public final class B implements TypeCreator { /** * {@inheritDoc} */ + @Override + public Type create(double value) { + Bit b = new Bit(); + b.setReal(value); + return b; + } + + /** + * {@inheritDoc} + */ + @Override public Type create(final double lower, final double upper) { throw new UnsupportedOperationException("Bit types cannot be constructed with bounds"); } diff --git a/src/main/java/net/sourceforge/cilib/type/creator/R.java b/src/main/java/net/sourceforge/cilib/type/creator/R.java index 68c7e38..01d8ac8 100644 --- a/src/main/java/net/sourceforge/cilib/type/creator/R.java +++ b/src/main/java/net/sourceforge/cilib/type/creator/R.java @@ -41,6 +41,14 @@ public final class R implements TypeCreator { /** * {@inheritDoc} */ + @Override + public Type create(double value) { + return new Real(value); + } + + /** + * {@inheritDoc} + */ public Type create(final double lower, final double upper) { return new Real(lower, upper); } diff --git a/src/main/java/net/sourceforge/cilib/type/creator/T.java b/src/main/java/net/sourceforge/cilib/type/creator/T.java index 65b71d6..d12e7a1 100644 --- a/src/main/java/net/sourceforge/cilib/type/creator/T.java +++ b/src/main/java/net/sourceforge/cilib/type/creator/T.java @@ -46,6 +46,13 @@ public final class T implements TypeCreator { /** * {@inheritDoc} */ + public Type create(double value) { + throw new UnsupportedOperationException("StringTypes with single values do not exist"); + } + + /** + * {@inheritDoc} + */ public Type create(final double lower, final double upper) { throw new UnsupportedOperationException("StringTypes with bounds do not exist"); } diff --git a/src/main/java/net/sourceforge/cilib/type/creator/TypeCreator.java b/src/main/java/net/sourceforge/cilib/type/creator/TypeCreator.java index 9816e75..2096c3b 100644 --- a/src/main/java/net/sourceforge/cilib/type/creator/TypeCreator.java +++ b/src/main/java/net/sourceforge/cilib/type/creator/TypeCreator.java @@ -42,6 +42,13 @@ public interface TypeCreator { */ public Type create(); + /** + * Create the type with the specified value. + * @param value The value for the {@code Type}. + * @return The created {@code Type} with the provided value. + */ + public Type create(double value); + /** * Create the type using the bounds <tt>lower</tt> and <tt>upper</tt>. diff --git a/src/main/java/net/sourceforge/cilib/type/creator/Z.java b/src/main/java/net/sourceforge/cilib/type/creator/Z.java index 8fa4feb..c8d6609 100644 --- a/src/main/java/net/sourceforge/cilib/type/creator/Z.java +++ b/src/main/java/net/sourceforge/cilib/type/creator/Z.java @@ -46,6 +46,15 @@ public final class Z implements TypeCreator { /** * {@inheritDoc} */ + public Type create(double value) { + Int i = new Int(); + i.setReal(value); + return i; + } + + /** + * {@inheritDoc} + */ public Type create(final double lower, final double upper) { return new Int(Double.valueOf(lower).intValue(), Double.valueOf(upper).intValue()); } diff --git a/src/main/java/net/sourceforge/cilib/type/parser/DomainParserVisitorImpl.java b/src/main/java/net/sourceforge/cilib/type/parser/DomainParserVisitorImpl.java new file mode 100644 index 0000000..66de851 --- /dev/null +++ b/src/main/java/net/sourceforge/cilib/type/parser/DomainParserVisitorImpl.java @@ -0,0 +1,193 @@ +/** + * Copyright (C) 2003 - 2008 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package net.sourceforge.cilib.type.parser; + +import java.util.ArrayList; +import java.util.List; +import net.sourceforge.cilib.type.creator.TypeCreator; +import net.sourceforge.cilib.type.parser.DomainParser.DomainNode; +import net.sourceforge.cilib.type.types.Type; +import net.sourceforge.cilib.type.types.container.TypeList; + +/** + * + * @author gpampara + */ +public class DomainParserVisitorImpl implements DomainParserVisitor { + + @Override + public Object visit(SimpleNode node, Object data) { + return null; + } + + @Override + public Object visit(ASTrootElement node, Object data) { + ASTelement element = (ASTelement) node.jjtGetChild(0); + return element.jjtAccept(this, data); + } + + @Override + public Object visit(ASTelement node, Object data) { + ASTdomainElement domainElement = (ASTdomainElement) node.jjtGetChild(0); + domainElement.jjtAccept(this, data); + + if (node.jjtGetNumChildren() > 1) { + ASTrepeat repeat = (ASTrepeat) node.jjtGetChild(1); + repeat.jjtAccept(this, data); + } + + return null; + } + + @Override + public Object visit(ASTdomainElement node, Object data) { + int children = node.jjtGetNumChildren(); + TypeCreator creator = null; + List<Double> bounds = null; + int exponent = 1; + + // type() + ASTtype type = (ASTtype) node.jjtGetChild(0); + creator = (TypeCreator) type.jjtAccept(this, data); + + if (children > 1) { + SimpleNode dimensionOrExponent = (SimpleNode) node.jjtGetChild(1); + + if (dimensionOrExponent instanceof ASTdimension) { + ASTdimension dimension = (ASTdimension) dimensionOrExponent; + bounds = (List<Double>) dimension.jjtAccept(this, data); + + if (children > 2) { // We have an exponent as well + exponent = getExponent(node, data, 2); + } + } + + if (dimensionOrExponent instanceof ASTexponent) { + exponent = getExponent(node, data, 1); + } + + } + + expandDomain(creator, bounds, exponent, data); + + return null; + } + + @Override + public Object visit(ASTtype node, Object data) { + DomainNode domainNode = (DomainNode) node.jjtGetChild(0); + TypeCreator instance = null; + + try { + // create an instance of the TypeCreator + Class<?> creatorClass = Class.forName("net.sourceforge.cilib.type.creator." + domainNode.getValue()); + instance = (TypeCreator) creatorClass.newInstance(); + } catch (ClassNotFoundException ex) { + } catch (InstantiationException ex) { + } catch (IllegalAccessException ex) { + } + + return instance; + } + + @Override + public Object visit(ASTexponent node, Object data) { + DomainNode domainNode = (DomainNode) node.jjtGetChild(0); + return domainNode.getValue(); + } + + @Override + public Object visit(ASTdimension node, Object data) { + ASTlowerDim lowerDim = (ASTlowerDim) node.jjtGetChild(0); + return lowerDim.jjtAccept(this, data); + } + + @Override + public Object visit(ASTlowerDim node, Object data) { + List<Double> bounds = new ArrayList<Double>(); + + ASTnumber number1 = (ASTnumber) node.jjtGetChild(0); + + Double value1 = Double.valueOf((String) number1.jjtAccept(this, data)); + bounds.add(value1); + + SimpleNode remainder = (SimpleNode) node.jjtGetChild(1); + if (remainder instanceof ASTupperDim) { + ASTupperDim upper = (ASTupperDim) remainder; + Double value2 = Double.valueOf((String) upper.jjtAccept(this, data)); + bounds.add(value2); + } + + if (remainder instanceof ASTvalue) { + ASTvalue value = (ASTvalue) remainder; + value.jjtAccept(this, data); + } + + return bounds; + } + + @Override + public Object visit(ASTupperDim node, Object data) { + ASTnumber number = (ASTnumber) node.jjtGetChild(0); + return number.jjtAccept(this, data); + } + + @Override + public Object visit(ASTvalue node, Object data) { + // Nothing to be done as this is a terminal node that simply ends a statement. + return null; + } + + @Override + public Object visit(ASTrepeat node, Object data) { + ASTelement element = (ASTelement) node.jjtGetChild(0); + return element.jjtAccept(this, data); + } + + @Override + public Object visit(ASTnumber node, Object data) { + DomainNode domainNode = (DomainNode) node.jjtGetChild(0); + return domainNode.getValue(); + } + + private int getExponent(ASTdomainElement node, Object data, int index) throws NumberFormatException { + ASTexponent astexponent = (ASTexponent) node.jjtGetChild(index); + return Integer.valueOf((String) astexponent.jjtAccept(this, data)).intValue(); + } + + private void expandDomain(TypeCreator creator, List<Double> bounds, int exponent, Object data) { + TypeList list = (TypeList) data; + + for (int i = 0; i < exponent; i++) { + Type type = null; + if (bounds == null || bounds.size() == 0) + type = creator.create(); + else if (bounds.size() == 1) + type = creator.create(bounds.get(0)); + else // 2 bound values provided + type = creator.create(bounds.get(0), bounds.get(1)); + + list.add(type); + } + } +} diff --git a/src/main/jjtree/parser.jjt b/src/main/jjtree/parser.jjt index f070b64..aeb3423 100644 --- a/src/main/jjtree/parser.jjt +++ b/src/main/jjtree/parser.jjt @@ -5,31 +5,72 @@ options { } PARSER_BEGIN( DomainParser ) -package net.sourceforge.cilib.parser; -public class DomainParser {} - -class DomainNode extends SimpleNode { - String value; - public DomainNode() { super(0); } - public DomainNode(String value) { super(0); this.value = value; } - public String getValue() { return value; } - public String toString() { return value; } +package net.sourceforge.cilib.type.parser; + +import java.io.StringReader; +import net.sourceforge.cilib.type.types.Numeric; +import net.sourceforge.cilib.type.types.Type; +import net.sourceforge.cilib.type.types.container.AbstractList; +import net.sourceforge.cilib.type.types.container.StructuredType; +import net.sourceforge.cilib.type.types.container.TypeList; +import net.sourceforge.cilib.type.types.container.Vector; + +public class DomainParser { + public static class DomainNode extends SimpleNode { + private String value; + public DomainNode() { super(0); } + public DomainNode(String value) { super(0); this.value = value; } + public String getValue() { return value; } + @Override public String toString() { return value; } + } + + public static StructuredType parse(String domainString) throws ParseException { + TypeList list = new TypeList(); + + DomainParser parser = new DomainParser(new StringReader(domainString)); + ASTrootElement root = parser.rootElement(); + + DomainParserVisitor visitor = new DomainParserVisitorImpl(); + root.jjtAccept(visitor, list); + + if (isVector(list)) + return toVector(list); + + return list; + } + + private static boolean isVector(TypeList representation) { + for (Type type : representation) + if (!(type instanceof Numeric)) + return false; + + return true; + } + + private static AbstractList toVector(TypeList representation) { + Vector vector = new Vector(representation.size()); + + for (Type type : representation) + vector.add((Numeric) type); + + return vector; + } } PARSER_END( DomainParser ) -ASTrootElement rootElement() : {} { element() <EOF> { return jjtThis; }} -void element() : {} { domainElement() (repeat())? } -void domainElement() : {} { type() (dimension())? } -void type() : { Token t = null; } { t=<TYPE> {jjtThis.jjtAddChild(new DomainNode(t.image), 0);}} -void exponent() : { Token t = null; } { <EXPONENT> t=<INTEGER> {jjtThis.jjtAddChild(new DomainNode(t.image), 0);}} -void dimension() : {} { (lowerDim() | exponent() ) } -void lowerDim() : {} { "(" number() ( upperDim() | value() ) } -void upperDim() : {} { "," number() ")" (exponent())? } -void value() : {} { ")" (exponent())? } -void repeat() : {} { "," element() } -void number() : { Token t = null; } { - t=<NUMBER> { jjtThis.jjtAddChild(new DomainNode(t.image), 0);} -| <MINUS> t=<NUMBER> {jjtThis.jjtAddChild(new DomainNode("-"+t.image), 0);} +ASTrootElement rootElement() : {} { element() <EOF> { return jjtThis; }} +void element() : {} { domainElement() (repeat())? } +void domainElement() : {} { type() (dimension() (exponent())? | exponent())? } +void type() : { Token t = null; } { t=<TYPE> {jjtThis.jjtAddChild(new DomainNode(t.image), 0);}} +void exponent() : { Token t = null; } { <EXPONENT> t=<INTEGER> {jjtThis.jjtAddChild(new DomainNode(t.image), 0);}} +void dimension() : {} { lowerDim() } +void lowerDim() : {} { "(" number() ( upperDim() | value() ) } +void upperDim() : {} { "," number() ")" } +void value() : {} { ")" } +void repeat() : {} { "," element() } +void number() : { Token t = null; } { + (t=<NUMBER> | t=<INTEGER>) { jjtThis.jjtAddChild(new DomainNode(t.image), 0);} +| <MINUS> (t=<NUMBER> | t=<INTEGER>) {jjtThis.jjtAddChild(new DomainNode("-"+t.image), 0);} } SKIP : { " " | "\t" | "\n" | "\r" } @@ -37,7 +78,7 @@ TOKEN : { < INTEGER : (<DIGIT>)+ > | < NUMBER : <INTEGER> ( "." <INTEGER> )? > | < DIGIT : ["0"-"9"] > -| < TYPE : ( "R" | "B" | "Z" ) > +| < TYPE : ( "R" | "B" | "Z" | "T" ) > | < MINUS : "-" > | < EXPONENT : "^" > -} \ No newline at end of file +} diff --git a/src/test/java/net/sourceforge/cilib/measurement/generic/IterationsTest.java b/src/test/java/net/sourceforge/cilib/measurement/generic/IterationsTest.java index 71ea802..6c7a246 100644 --- a/src/test/java/net/sourceforge/cilib/measurement/generic/IterationsTest.java +++ b/src/test/java/net/sourceforge/cilib/measurement/generic/IterationsTest.java @@ -22,10 +22,11 @@ package net.sourceforge.cilib.measurement.generic; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; import net.sourceforge.cilib.type.types.Int; import net.sourceforge.cilib.type.types.container.Vector; @@ -38,13 +39,10 @@ import org.junit.Test; public class IterationsTest { @Test - public void testIterationsDomain() { + public void testIterationsDomain() throws ParseException { Measurement m = new Iterations(); - DomainParser parser = new DomainParser(); - parser.parse(m.getDomain()); - - Vector vector = (Vector) parser.getBuiltRepresentation(); + Vector vector = (Vector) DomainParser.parse(m.getDomain()); assertEquals(1, vector.getDimension()); assertTrue(vector.get(0) instanceof Int); diff --git a/src/test/java/net/sourceforge/cilib/measurement/generic/PercentageCompleteTest.java b/src/test/java/net/sourceforge/cilib/measurement/generic/PercentageCompleteTest.java index 094c2c9..5a67958 100644 --- a/src/test/java/net/sourceforge/cilib/measurement/generic/PercentageCompleteTest.java +++ b/src/test/java/net/sourceforge/cilib/measurement/generic/PercentageCompleteTest.java @@ -22,10 +22,11 @@ package net.sourceforge.cilib.measurement.generic; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; import net.sourceforge.cilib.type.types.Real; import net.sourceforge.cilib.type.types.container.Vector; @@ -38,13 +39,10 @@ import org.junit.Test; public class PercentageCompleteTest { @Test - public void testPercentageCompleteDomain() { + public void testPercentageCompleteDomain() throws ParseException { Measurement m = new PercentageComplete(); - DomainParser parser = new DomainParser(); - parser.parse(m.getDomain()); - - Vector vector = (Vector) parser.getBuiltRepresentation(); + Vector vector = (Vector) DomainParser.parse(m.getDomain()); assertEquals(1, vector.getDimension()); assertTrue(vector.get(0) instanceof Real); diff --git a/src/test/java/net/sourceforge/cilib/measurement/generic/RestartsTest.java b/src/test/java/net/sourceforge/cilib/measurement/generic/RestartsTest.java index ea0a665..ad0b796 100644 --- a/src/test/java/net/sourceforge/cilib/measurement/generic/RestartsTest.java +++ b/src/test/java/net/sourceforge/cilib/measurement/generic/RestartsTest.java @@ -22,10 +22,11 @@ package net.sourceforge.cilib.measurement.generic; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; import net.sourceforge.cilib.type.types.Int; import net.sourceforge.cilib.type.types.container.Vector; @@ -38,13 +39,10 @@ import org.junit.Test; public class RestartsTest { @Test - public void testRestartsDomain() { + public void testRestartsDomain() throws ParseException { Measurement m = new Restarts(); - DomainParser parser = new DomainParser(); - parser.parse(m.getDomain()); - - Vector vector = (Vector) parser.getBuiltRepresentation(); + Vector vector = (Vector) DomainParser.parse(m.getDomain()); assertEquals(1, vector.getDimension()); assertTrue(vector.get(0) instanceof Int); diff --git a/src/test/java/net/sourceforge/cilib/measurement/generic/TimeTest.java b/src/test/java/net/sourceforge/cilib/measurement/generic/TimeTest.java index afa987a..ea53d08 100644 --- a/src/test/java/net/sourceforge/cilib/measurement/generic/TimeTest.java +++ b/src/test/java/net/sourceforge/cilib/measurement/generic/TimeTest.java @@ -22,10 +22,11 @@ package net.sourceforge.cilib.measurement.generic; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; import net.sourceforge.cilib.type.types.Int; import net.sourceforge.cilib.type.types.container.Vector; @@ -34,13 +35,10 @@ import org.junit.Test; public class TimeTest { @Test - public void testTimeDomain() { + public void testTimeDomain() throws ParseException { Measurement m = new Time(); - DomainParser parser = new DomainParser(); - parser.parse(m.getDomain()); - - Vector vector = (Vector) parser.getBuiltRepresentation(); + Vector vector = (Vector) DomainParser.parse(m.getDomain()); assertEquals(1, vector.getDimension()); assertTrue(vector.get(0) instanceof Int); diff --git a/src/test/java/net/sourceforge/cilib/measurement/multiple/MultipleFitnessTest.java b/src/test/java/net/sourceforge/cilib/measurement/multiple/MultipleFitnessTest.java index 0301b81..a019dca 100644 --- a/src/test/java/net/sourceforge/cilib/measurement/multiple/MultipleFitnessTest.java +++ b/src/test/java/net/sourceforge/cilib/measurement/multiple/MultipleFitnessTest.java @@ -22,10 +22,11 @@ package net.sourceforge.cilib.measurement.multiple; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; import net.sourceforge.cilib.type.types.StringType; import net.sourceforge.cilib.type.types.container.TypeList; @@ -38,13 +39,10 @@ import org.junit.Test; public class MultipleFitnessTest { @Test - public void testMultipleFitnessDomain() { + public void testMultipleFitnessDomain() throws ParseException { Measurement m = new MultipleFitness(); - DomainParser parser = new DomainParser(); - parser.parse(m.getDomain()); - - TypeList vector = (TypeList) parser.getBuiltRepresentation(); + TypeList vector = (TypeList) DomainParser.parse(m.getDomain()); assertEquals(1, vector.size()); assertTrue(vector.get(0) instanceof StringType); diff --git a/src/test/java/net/sourceforge/cilib/measurement/multiple/MultipleSolutionsTest.java b/src/test/java/net/sourceforge/cilib/measurement/multiple/MultipleSolutionsTest.java index e477da9..ff48734 100644 --- a/src/test/java/net/sourceforge/cilib/measurement/multiple/MultipleSolutionsTest.java +++ b/src/test/java/net/sourceforge/cilib/measurement/multiple/MultipleSolutionsTest.java @@ -22,10 +22,11 @@ package net.sourceforge.cilib.measurement.multiple; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; import net.sourceforge.cilib.type.types.StringType; import net.sourceforge.cilib.type.types.container.TypeList; @@ -38,13 +39,10 @@ import org.junit.Test; public class MultipleSolutionsTest { @Test - public void testMultipleSolutionsDomain() { + public void testMultipleSolutionsDomain() throws ParseException { Measurement m = new MultipleSolutions(); - DomainParser parser = new DomainParser(); - parser.parse(m.getDomain()); - - TypeList vector = (TypeList) parser.getBuiltRepresentation(); + TypeList vector = (TypeList) DomainParser.parse(m.getDomain()); assertEquals(1, vector.size()); assertTrue(vector.get(0) instanceof StringType); diff --git a/src/test/java/net/sourceforge/cilib/measurement/single/BestParticlePositionTest.java b/src/test/java/net/sourceforge/cilib/measurement/single/BestParticlePositionTest.java index 4d4bdb9..f86e09e 100644 --- a/src/test/java/net/sourceforge/cilib/measurement/single/BestParticlePositionTest.java +++ b/src/test/java/net/sourceforge/cilib/measurement/single/BestParticlePositionTest.java @@ -22,13 +22,14 @@ package net.sourceforge.cilib.measurement.single; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertEquals; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; import net.sourceforge.cilib.type.types.StringType; -import net.sourceforge.cilib.type.types.container.TypeList; +import net.sourceforge.cilib.type.types.container.TypeList; import org.junit.Test; /** @@ -38,13 +39,10 @@ import org.junit.Test; public class BestParticlePositionTest { @Test - public void testBestParticlePositionDomain() { + public void testBestParticlePositionDomain() throws ParseException { Measurement m = new BestParticlePosition(); - - DomainParser parser = new DomainParser(); - parser.parse(m.getDomain()); - - TypeList t = (TypeList) parser.getBuiltRepresentation(); + + TypeList t = (TypeList) DomainParser.parse(m.getDomain()); assertTrue(t.get(0) instanceof StringType); assertEquals(1, t.size()); diff --git a/src/test/java/net/sourceforge/cilib/measurement/single/DiameterTest.java b/src/test/java/net/sourceforge/cilib/measurement/single/DiameterTest.java index e7c5071..bd59215 100644 --- a/src/test/java/net/sourceforge/cilib/measurement/single/DiameterTest.java +++ b/src/test/java/net/sourceforge/cilib/measurement/single/DiameterTest.java @@ -22,10 +22,11 @@ package net.sourceforge.cilib.measurement.single; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; import net.sourceforge.cilib.type.types.Real; import net.sourceforge.cilib.type.types.container.Vector; @@ -38,13 +39,10 @@ import org.junit.Test; public class DiameterTest { @Test - public void testDiameterTestDomain() { + public void testDiameterTestDomain() throws ParseException { Measurement m = new Diameter(); - DomainParser parser = new DomainParser(); - parser.parse(m.getDomain()); - - Vector vector = (Vector) parser.getBuiltRepresentation(); + Vector vector = (Vector) DomainParser.parse(m.getDomain()); assertEquals(1, vector.getDimension()); assertTrue(vector.get(0) instanceof Real); diff --git a/src/test/java/net/sourceforge/cilib/measurement/single/FitnessEvaluationsTest.java b/src/test/java/net/sourceforge/cilib/measurement/single/FitnessEvaluationsTest.java index ec16816..eb64e2a 100644 --- a/src/test/java/net/sourceforge/cilib/measurement/single/FitnessEvaluationsTest.java +++ b/src/test/java/net/sourceforge/cilib/measurement/single/FitnessEvaluationsTest.java @@ -22,10 +22,11 @@ package net.sourceforge.cilib.measurement.single; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; import net.sourceforge.cilib.type.types.Int; import net.sourceforge.cilib.type.types.container.Vector; @@ -38,13 +39,10 @@ import org.junit.Test; public class FitnessEvaluationsTest { @Test - public void testFitnessEvaluationsDomain() { + public void testFitnessEvaluationsDomain() throws ParseException { Measurement m = new FitnessEvaluations(); - DomainParser parser = new DomainParser(); - parser.parse(m.getDomain()); - - Vector vector = (Vector) parser.getBuiltRepresentation(); + Vector vector = (Vector) DomainParser.parse(m.getDomain()); assertEquals(1, vector.getDimension()); assertTrue(vector.get(0) instanceof Int); diff --git a/src/test/java/net/sourceforge/cilib/measurement/single/FitnessTest.java b/src/test/java/net/sourceforge/cilib/measurement/single/FitnessTest.java index 13f8684..f299cc5 100644 --- a/src/test/java/net/sourceforge/cilib/measurement/single/FitnessTest.java +++ b/src/test/java/net/sourceforge/cilib/measurement/single/FitnessTest.java @@ -22,10 +22,11 @@ package net.sourceforge.cilib.measurement.single; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; import net.sourceforge.cilib.type.types.Real; import net.sourceforge.cilib.type.types.container.Vector; @@ -38,13 +39,10 @@ import org.junit.Test; public class FitnessTest { @Test - public void testFitnessDomain() { + public void testFitnessDomain() throws ParseException { Measurement m = new Fitness(); - DomainParser p = new DomainParser(); - p.parse(m.getDomain()); - - Vector t = (Vector) p.getBuiltRepresentation(); + Vector t = (Vector) DomainParser.parse(m.getDomain()); assertEquals(1, t.getDimension()); assertTrue(t.get(0) instanceof Real); diff --git a/src/test/java/net/sourceforge/cilib/measurement/single/FunctionOptimisationErrorTest.java b/src/test/java/net/sourceforge/cilib/measurement/single/FunctionOptimisationErrorTest.java index b42e4dc..2ab1afc 100644 --- a/src/test/java/net/sourceforge/cilib/measurement/single/FunctionOptimisationErrorTest.java +++ b/src/test/java/net/sourceforge/cilib/measurement/single/FunctionOptimisationErrorTest.java @@ -22,13 +22,14 @@ package net.sourceforge.cilib.measurement.single; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; import net.sourceforge.cilib.type.types.Real; -import net.sourceforge.cilib.type.types.container.Vector; +import net.sourceforge.cilib.type.types.container.Vector; import org.junit.Test; /** @@ -38,13 +39,10 @@ import org.junit.Test; public class FunctionOptimisationErrorTest { @Test - public void testFunctionOptimisationErrorDomain() { + public void testFunctionOptimisationErrorDomain() throws ParseException { Measurement m = new FunctionOptimisationError(); - DomainParser parser = new DomainParser(); - parser.parse(m.getDomain()); - - Vector vector = (Vector) parser.getBuiltRepresentation(); + Vector vector = (Vector) DomainParser.parse(m.getDomain()); assertEquals(1, vector.getDimension()); assertTrue(vector.get(0) instanceof Real); diff --git a/src/test/java/net/sourceforge/cilib/measurement/single/ParticlePositionsTest.java b/src/test/java/net/sourceforge/cilib/measurement/single/ParticlePositionsTest.java index 1e1800d..fee12f7 100644 --- a/src/test/java/net/sourceforge/cilib/measurement/single/ParticlePositionsTest.java +++ b/src/test/java/net/sourceforge/cilib/measurement/single/ParticlePositionsTest.java @@ -22,10 +22,11 @@ package net.sourceforge.cilib.measurement.single; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; import net.sourceforge.cilib.type.types.StringType; import net.sourceforge.cilib.type.types.container.TypeList; @@ -38,13 +39,10 @@ import org.junit.Test; public class ParticlePositionsTest { @Test - public void testParticlePositionsDomain() { + public void testParticlePositionsDomain() throws ParseException { Measurement m = new ParticlePositions(); - DomainParser parser = new DomainParser(); - parser.parse(m.getDomain()); - - TypeList vector = (TypeList) parser.getBuiltRepresentation(); + TypeList vector = (TypeList) DomainParser.parse(m.getDomain()); assertEquals(1, vector.size()); assertTrue(vector.get(0) instanceof StringType); diff --git a/src/test/java/net/sourceforge/cilib/measurement/single/SolutionTest.java b/src/test/java/net/sourceforge/cilib/measurement/single/SolutionTest.java index a00da70..6325456 100644 --- a/src/test/java/net/sourceforge/cilib/measurement/single/SolutionTest.java +++ b/src/test/java/net/sourceforge/cilib/measurement/single/SolutionTest.java @@ -22,10 +22,11 @@ package net.sourceforge.cilib.measurement.single; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.type.DomainParser; +import net.sourceforge.cilib.type.parser.DomainParser; import net.sourceforge.cilib.type.types.StringType; import net.sourceforge.cilib.type.types.container.TypeList; @@ -38,13 +39,10 @@ import org.junit.Test; public class SolutionTest { @Test - public void testSolutionDomain() { + public void testSolutionDomain() throws ParseException { Measurement m = new Solution(); - - DomainParser parser = new DomainParser(); - parser.parse(m.getDomain()); - - TypeList vector = (TypeList) parser.getBuiltRepresentation(); + + TypeList vector = (TypeList) DomainParser.parse(m.getDomain()); assertEquals(1, vector.size()); assertTrue(vector.get(0) instanceof StringType); diff --git a/src/test/java/net/sourceforge/cilib/type/DomainParserTest.java b/src/test/java/net/sourceforge/cilib/type/DomainParserTest.java index a6e1872..0e8894d 100644 --- a/src/test/java/net/sourceforge/cilib/type/DomainParserTest.java +++ b/src/test/java/net/sourceforge/cilib/type/DomainParserTest.java @@ -22,13 +22,9 @@ package net.sourceforge.cilib.type; -import net.sourceforge.cilib.type.types.container.TypeList; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import net.sourceforge.cilib.type.parser.ParseException; import static org.junit.Assert.fail; -import net.sourceforge.cilib.type.types.container.Vector; - import org.junit.Test; /** @@ -38,69 +34,72 @@ import org.junit.Test; public class DomainParserTest { @Test - public void testParseReal() { - DomainParser parser = new DomainParser(); - try { - parser.parse("R(0,INF)"); - parser.parse("R"); - assertEquals("R", parser.expandDomainString("R")); - parser.parse("R^6"); - assertEquals("R,R,R,R,R,R", parser.expandDomainString("R^6")); - parser.parse("R(-9,9)"); - assertEquals("R(-9.0,9.0)", parser.expandDomainString("R(-9,9)")); - parser.parse("R(-30.0,30.0)^6"); - assertEquals("R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0)", parser.expandDomainString("R(-30.0,30.0)^6")); - } - catch (Exception e) { - fail("Parser cannot handle parsing of R! " + e.getMessage()); - } + public void testParseReal() throws ParseException { +// DomainParser parser = new DomainParser(); +// try { +// parser.parse("R(0,INF)"); +// parser.parse("R"); +// assertEquals("R", parser.expandDomainString("R")); +// parser.parse("R^6"); +// assertEquals("R,R,R,R,R,R", parser.expandDomainString("R^6")); +// parser.parse("R(-9,9)"); +// assertEquals("R(-9.0,9.0)", parser.expandDomainString("R(-9,9)")); +// parser.parse("R(-30.0,30.0)^6"); +// assertEquals("R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0)", parser.expandDomainString("R(-30.0,30.0)^6")); + net.sourceforge.cilib.type.parser.DomainParser.parse("R(0.0,9.0)"); + net.sourceforge.cilib.type.parser.DomainParser.parse("R"); +// assertEquals("R", parser.expandDomainString("R")); + net.sourceforge.cilib.type.parser.DomainParser.parse("R^6"); +// assertEquals("R,R,R,R,R,R", parser.expandDomainString("R^6")); + net.sourceforge.cilib.type.parser.DomainParser.parse("R(-9.0,9.0)"); +// assertEquals("R(-9.0,9.0)", parser.expandDomainString("R(-9,9)")); + net.sourceforge.cilib.type.parser.DomainParser.parse("R(-30.0,30.0)^6"); +// assertEquals("R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0)", parser.expandDomainString("R(-30.0,30.0)^6")); +// } +// catch (Exception e) { +// fail("Parser cannot handle parsing of R! " + e.getMessage()); +// } } @Test - public void testParseBit() { - DomainParser parser = new DomainParser(); - try { - parser.parse("B"); - assertEquals("B", parser.expandDomainString("B")); - parser.parse("B^6"); - assertEquals("B,B,B,B,B,B", parser.expandDomainString("B^6")); - } - catch (Exception e) { - fail("Parser cannot handle parsing of B! " + e.getMessage()); - } + public void testParseBit() throws ParseException { +// DomainParser parser = new DomainParser(); + net.sourceforge.cilib.type.parser.DomainParser.parse("B"); + net.sourceforge.cilib.type.parser.DomainParser.parse("B^6"); + +// parser.parse("B"); +// assertEquals("B", parser.expandDomainString("B")); +// parser.parse("B^6"); +// assertEquals("B,B,B,B,B,B", parser.expandDomainString("B^6")); } @Test - public void testParseInteger() { - DomainParser parser = new DomainParser(); - try { - parser.parse("Z"); - assertEquals("Z", parser.expandDomainString("Z")); - parser.parse("Z(-1,0)"); - assertEquals("Z(-1.0,0.0)", parser.expandDomainString("Z(-1,0)")); - parser.parse("Z(0,1)"); - assertEquals("Z(0.0,1.0)", parser.expandDomainString("Z(0,1)")); - parser.parse("Z(-999,999)"); - assertEquals("Z(-999.0,999.0)", parser.expandDomainString("Z(-999,999)")); - parser.parse("Z^8"); - assertEquals("Z,Z,Z,Z,Z,Z,Z,Z", parser.expandDomainString("Z^8")); - parser.parse("Z(0,1)^10"); - assertEquals("Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0)", parser.expandDomainString("Z(0,1)^10")); - } - catch (Exception e) { - fail("Parser cannot handle parsing of Z! " + e.getMessage()); - } + public void testParseInteger() throws ParseException { +// DomainParser parser = new DomainParser(); + net.sourceforge.cilib.type.parser.DomainParser.parse("Z"); +// parser.parse("Z"); +// assertEquals("Z", parser.expandDomainString("Z")); + net.sourceforge.cilib.type.parser.DomainParser.parse("Z(-1,0)"); +// assertEquals("Z(-1.0,0.0)", parser.expandDomainString("Z(-1,0)")); + net.sourceforge.cilib.type.parser.DomainParser.parse("Z(0,1)"); +// assertEquals("Z(0.0,1.0)", parser.expandDomainString("Z(0,1)")); + net.sourceforge.cilib.type.parser.DomainParser.parse("Z(-999,999)"); +// assertEquals("Z(-999.0,999.0)", parser.expandDomainString("Z(-999,999)")); + net.sourceforge.cilib.type.parser.DomainParser.parse("Z^8"); +// assertEquals("Z,Z,Z,Z,Z,Z,Z,Z", parser.expandDomainString("Z^8")); + net.sourceforge.cilib.type.parser.DomainParser.parse("Z(0,1)^10"); +// assertEquals("Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0),Z(0.0,1.0)", parser.expandDomainString("Z(0,1)^10")); } @Test public void testParseString() { - DomainParser parser = new DomainParser(); +// DomainParser parser = new DomainParser(); try { - parser.parse("T^5"); - assertEquals("T,T,T,T,T", parser.expandDomainString("T^5")); + net.sourceforge.cilib.type.parser.DomainParser.parse("T^5"); +// assertEquals("T,T,T,T,T", parser.expandDomainString("T^5")); } catch (Exception e) { fail("Parser cannot handle parsing of T! " + e.getMessage()); @@ -110,11 +109,11 @@ public class DomainParserTest { @Test public void testParseComplexDomain() { - DomainParser parser = new DomainParser(); +// DomainParser parser = new DomainParser(); try { - parser.parse("R(-30.0,30.0)^30,B,Z^6"); - assertEquals("R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-30.0,30.0),R(-3... [truncated message content] |
From: Gary P. <gpa...@gm...> - 2009-06-10 10:52:17
|
--- src/main/jjtree/parser.jjt | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-) create mode 100644 src/main/jjtree/parser.jjt diff --git a/src/main/jjtree/parser.jjt b/src/main/jjtree/parser.jjt new file mode 100644 index 0000000..f070b64 --- /dev/null +++ b/src/main/jjtree/parser.jjt @@ -0,0 +1,43 @@ +options { + STATIC=false; + MULTI=true; + VISITOR=true; +} + +PARSER_BEGIN( DomainParser ) +package net.sourceforge.cilib.parser; +public class DomainParser {} + +class DomainNode extends SimpleNode { + String value; + public DomainNode() { super(0); } + public DomainNode(String value) { super(0); this.value = value; } + public String getValue() { return value; } + public String toString() { return value; } +} +PARSER_END( DomainParser ) + +ASTrootElement rootElement() : {} { element() <EOF> { return jjtThis; }} +void element() : {} { domainElement() (repeat())? } +void domainElement() : {} { type() (dimension())? } +void type() : { Token t = null; } { t=<TYPE> {jjtThis.jjtAddChild(new DomainNode(t.image), 0);}} +void exponent() : { Token t = null; } { <EXPONENT> t=<INTEGER> {jjtThis.jjtAddChild(new DomainNode(t.image), 0);}} +void dimension() : {} { (lowerDim() | exponent() ) } +void lowerDim() : {} { "(" number() ( upperDim() | value() ) } +void upperDim() : {} { "," number() ")" (exponent())? } +void value() : {} { ")" (exponent())? } +void repeat() : {} { "," element() } +void number() : { Token t = null; } { + t=<NUMBER> { jjtThis.jjtAddChild(new DomainNode(t.image), 0);} +| <MINUS> t=<NUMBER> {jjtThis.jjtAddChild(new DomainNode("-"+t.image), 0);} +} + +SKIP : { " " | "\t" | "\n" | "\r" } +TOKEN : { + < INTEGER : (<DIGIT>)+ > +| < NUMBER : <INTEGER> ( "." <INTEGER> )? > +| < DIGIT : ["0"-"9"] > +| < TYPE : ( "R" | "B" | "Z" ) > +| < MINUS : "-" > +| < EXPONENT : "^" > +} \ No newline at end of file -- 1.6.2.3 |
From: Gary P. <gpa...@gm...> - 2009-06-10 10:52:10
|
The need to have a decent parser for the domain strings is something that has been on the cards for a very long time. The main problem with the current implementation is that it is very non-expressive. Illegal domains such as: - R(8, 9)^-1 - R^0 - Any other strange combination were allowed in the previous parser. These patches propose a new generated parser based on a provided grammar file. JJTree and JavaCC were used to achieve the parser. Gary Pampara (3): Semi-complete parser definition. Deprecation of parser for generated parser. Prevent invalid values / options in domain strings. pom.xml | 13 + .../bioinf/sequencealignment/BinaryMSAProblem.java | 12 +- .../cilib/bioinf/sequencealignment/MSAProblem.java | 5 +- .../controlparameter/BoundedControlParameter.java | 12 +- .../functions/discrete/KnightCoverageProblem.java | 1 - .../cilib/problem/ClusteringProblem.java | 5 +- .../CooperativeOptimisationProblemAdapter.java | 21 +- .../net/sourceforge/cilib/type/DomainBuilder.java | 2 + .../net/sourceforge/cilib/type/DomainParser.java | 2 + .../net/sourceforge/cilib/type/DomainRegistry.java | 2 +- .../sourceforge/cilib/type/DomainValidator.java | 1 + .../cilib/type/StringBasedDomainRegistry.java | 44 +--- .../java/net/sourceforge/cilib/type/creator/B.java | 16 +- .../java/net/sourceforge/cilib/type/creator/R.java | 8 + .../java/net/sourceforge/cilib/type/creator/T.java | 7 + .../cilib/type/creator/TypeCreator.java | 7 + .../java/net/sourceforge/cilib/type/creator/Z.java | 9 + .../cilib/type/parser/DomainParserVisitorImpl.java | 272 ++++++++++++++++++++ src/main/jjtree/parser.jjt | 84 ++++++ .../cilib/measurement/generic/IterationsTest.java | 10 +- .../generic/PercentageCompleteTest.java | 10 +- .../cilib/measurement/generic/RestartsTest.java | 10 +- .../cilib/measurement/generic/TimeTest.java | 10 +- .../measurement/multiple/MultipleFitnessTest.java | 10 +- .../multiple/MultipleSolutionsTest.java | 10 +- .../single/BestParticlePositionTest.java | 14 +- .../cilib/measurement/single/DiameterTest.java | 10 +- .../measurement/single/FitnessEvaluationsTest.java | 10 +- .../cilib/measurement/single/FitnessTest.java | 10 +- .../single/FunctionOptimisationErrorTest.java | 12 +- .../measurement/single/ParticlePositionsTest.java | 10 +- .../cilib/measurement/single/SolutionTest.java | 12 +- .../sourceforge/cilib/type/DomainParserTest.java | 165 ++---------- .../cilib/type/StringBasedDomainRegistryTest.java | 20 +- .../cilib/type/parser/DomainParserTest.java | 128 +++++++++ 35 files changed, 682 insertions(+), 292 deletions(-) create mode 100644 src/main/java/net/sourceforge/cilib/type/parser/DomainParserVisitorImpl.java create mode 100644 src/main/jjtree/parser.jjt create mode 100644 src/test/java/net/sourceforge/cilib/type/parser/DomainParserTest.java |
From: Theuns C. <the...@gm...> - 2009-06-10 09:10:21
|
Hey Andrich, Firstly, don't think that the multi-threaded class should be committed to the master branch. I only sent it out so that other people can have a look and comment like you are doing now. That is why I marked it experimental. Secondly, not exactly, the number of threads can be set with the .setNumberOfThreads(int) method, which means that even if there are 10 sub-populations, but you only have 4 cores (and configure it to use 4 threads), then 4 sub-populations will run concurrently. Obviously there is a performance hit for managing more threads, but the gains can be greater if you have enough cores. I haven't tried multiple concurrent samples though. If an algorithm or problem uses Algorithm.get(), there will be a lot of exceptions due to concurrency issues. This whole experiment is dependant on the fact that we need to relook the Algorithm stack and I hope that we can find a solution using Guice. So, start thinking about solutions ;-) Regards -- Theuns On Wed, Jun 10, 2009 at 10:30 AM, Andrich van Wyk<avw...@gm...> wrote: > Hey Theuns > > Two things regarding this: If I understand this correctly, each sub > algorithm now executes in it own thread. So for instance, if you have three > sub algorithms, that will be 3 threads, but you still have to run 30 samples > minimum, which then entails 90 total threads running. Is this the case? > Also, what is the performance cost of having the 90 running instead of just > the 30? > > Another thing you mention in your summary mail is that this only works if > the problem you are optimizing doesn't call Algorithm.get(). If we commit > this, how do we convey to the user that he is not allowed to use a problem > using Algorithm.get(), also how is the user suppose to know if a problem > will call Algorithm.get() ? > > Regards > > On Wed, Jun 10, 2009 at 8:40 AM, Theuns Cloete <the...@gm...> > wrote: >> >> An ExecutorService and CoundDownLatch is used to concurrently execute the >> performInitialisation() and performIteration() methods of each >> sub-population (sub-algorithm). >> >> Thus far it works with simplistic problems such as minimizing some >> continuous function, but it breaks with more complex problems such as >> clustering with the help of the ClusteringUtils class. Following commits >> will address these issues. >> --- >> .../cooperative/SplitCooperativeAlgorithm.java | 160 >> ++++++++++++++------ >> 1 files changed, 117 insertions(+), 43 deletions(-) |
From: Andries E. <en...@cs...> - 2009-06-10 06:47:56
|
Thanks Theuns. We need to discuss the patch at the next CIlib meeting, unless Gary feels that all is fine, and can immediately apply. Theuns Cloete wrote: > Hi all, > > This is the fourth iteration of my set of patches after a rebase from the > latest 'master'. You can therefore safely ignore the previous set of patches > that I sent to the mailing list. I would appreciate it if we could apply these > patches as soon as possible, because each time there is some change to master, > I have to rebase and sort out a lot of conflicts which takes a considerable > amount of time. During every rebase it is becoming more difficult to remember > all the changes that have already been merged and those that still needs to be > merged. Feel free to comment and send patches. I think it is time that I put > it out there, so that other people can have a look and suggest or make > improvements. That's why we switched to Git, right? To make this type of > collaboration quicker and easier. > > The patches include the following: > > --- begin clustering branch --- > > 1. This patch includes all the changes I had in my Subversion > repository. It includes various updates that range from clustering > (mostly) to dynamic environments (less). It also included the dynamic > environments stuff that Leo sent through, but it was again merged in > a later patch. Git incorporated this into patch 7. This patch also > includes the ChargedSwarmInitialisationStrategy which deprecates the > ChargedParticleInitialisationStrategy. > > 2. Renamed a detection strategy. > > 3. Small cleanup like removing a super() etc. > > 4. Renamed a method and updated some JavaDoc. > > 5. Added trivial centroid diversification feature for KMeans. > > 6. Rebased from the "tabs to spaces" patch. I also fixed my own white space > issues. This patch also includes some dynamic environment changes. > > 7. Added centroid reinitialisation feature for KMeans, as part of > centroid initialisation strategy. > > 8. Update the kmeans.xml file to show examples of using centroid > initialisation and diversification. > > 9. Implemented methods in StatUtils to calculate a variance vector and > standard deviation vector. Made use of these methods in clustering > measurements. > > 10. Fixed merge mistakes regarding the pso.dynamic package that were made in > previous patches. > > UPDATE: After another rebase these mistakes were handled correctly in previous > patches. This patch can probably be squashed into the next patch. This patch > now only contains renames and minor changes regarding the pso.dynamic package. > > 11. Fixed some mistakes regarding the VonNeumannTopology and > CompetitiveCoevolutionParticleReevaluationResponseStrategy that crept in due > to the rebase. > > UPDATE: After another rebase, these mistakes were handled correctly in > previous patches. This patch can probably be squashed into the next patch. > > 12. Various changes that I had to commit in order to rebase. > > --- end clustering branch --- > > --- begin multi-threaded-split-coop-alg branch --- > > NOTE: Patch 13 is still experimental. I would appreciate some feedback. > > 13. Trying something new: Multi-threaded SplitCooperativeAlgorithm. The idea > is to execute each sub-algorithm in its own thread, thereby improving the > performance of the SplitCooperateAlgorithm, especially on computers with more > than one core. This works very nicely, as long as the algorithm you are using > and the problem you are optimising never uses Algorithm.get(), because the > algorithm stack is not thread safe. We need some elegant and simple way of > getting hold of either the main algorithm or the currently executing > sub-algorithm in a thread safe manner. I hope we can find a way by making use > of Guice. So try it out and let me know what you think. > > NOTE: Patch 14 still needs some work. I would appreciate some feedback. > > 14. Big changes regarding clustering as a result of patch 13. > 14.a. The Pattern class was moved to the type.types.container package as > Pattern<S extends Vector> and it is now a ForwardingStructuredType<S>. > 14.b. The Cluster<Vector> class was introduced which is a Set<Pattern<Vector>>, > i.e. also a Type. > 14.c. The multi-threaded behaviour of patch 13 caused the entire > ClusteringUtils class to break, because it was not thread safe, because it > contained state. The ClusteringUtils class was therefore trimmed down and does > not contain state anymore. It also makes use of the changes mentioned in 14.a > to 14.b. > 14.d. Everything else that depend on the clustering code was updated. > > --- end multi-threaded-split-coop-alg branch --- > > Look at the commit messages and content of each patch to get a better idea of > what each patch contains. > > ------------------------------------------------------------------------------ > Crystal Reports - New Free Runtime and 30 Day Trial > Check out the new simplified licensing option that enables unlimited > royalty-free distribution of the report engine for externally facing > server and web deployment. > http://p.sf.net/sfu/businessobjects > _______________________________________________ > cilib-devel mailing list > cil...@li... > https://lists.sourceforge.net/lists/listinfo/cilib-devel > -- ========================================================== Prof Andries P Engelbrecht South African Research Chair in Artificial Intelligence Fundamentals of Computational Swarm Intelligence, John Wiley & Sons, December 2005. Computational Intelligence, An Introduction John Wiley & Sons, Second edition to be published soon Computational Intelligence Research Group: http://cirg.cs.up.ac.za Department of Computer Science School of Information Technology University of Pretoria Pretoria 0002, South Africa Tel: +27 12 420 3578 Fax: +27 12 362 5188 http://www.cs.up.ac.za/~engel ================================================ This message and attachments are subject to a disclaimer. Please refer to www.it.up.ac.za/documentation/governance/disclaimer/ for full details. / Hierdie boodskap en aanhangsels is aan 'n vrywaringsklousule onderhewig. Volledige besonderhede is by www.it.up.ac.za/documentation/governance/disclaimer/ beskikbaar. |
From: Theuns C. <the...@gm...> - 2009-06-10 06:43:22
|
An ExecutorService and CoundDownLatch is used to concurrently execute the performInitialisation() and performIteration() methods of each sub-population (sub-algorithm). Thus far it works with simplistic problems such as minimizing some continuous function, but it breaks with more complex problems such as clustering with the help of the ClusteringUtils class. Following commits will address these issues. --- .../cooperative/SplitCooperativeAlgorithm.java | 160 ++++++++++++++------ 1 files changed, 117 insertions(+), 43 deletions(-) diff --git a/src/main/java/net/sourceforge/cilib/cooperative/SplitCooperativeAlgorithm.java b/src/main/java/net/sourceforge/cilib/cooperative/SplitCooperativeAlgorithm.java index 659e45a..e9b640b 100644 --- a/src/main/java/net/sourceforge/cilib/cooperative/SplitCooperativeAlgorithm.java +++ b/src/main/java/net/sourceforge/cilib/cooperative/SplitCooperativeAlgorithm.java @@ -24,6 +24,10 @@ package net.sourceforge.cilib.cooperative; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + import net.sourceforge.cilib.algorithm.Algorithm; import net.sourceforge.cilib.algorithm.population.MultiPopulationBasedAlgorithm; import net.sourceforge.cilib.algorithm.population.PopulationBasedAlgorithm; @@ -37,6 +41,8 @@ import net.sourceforge.cilib.entity.Entity; import net.sourceforge.cilib.problem.CooperativeOptimisationProblemAdapter; import net.sourceforge.cilib.problem.Fitness; import net.sourceforge.cilib.problem.OptimisationSolution; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * TODO test this class This class forms that basis for any co-operative optimisation @@ -49,30 +55,32 @@ import net.sourceforge.cilib.problem.OptimisationSolution; */ public class SplitCooperativeAlgorithm extends MultiPopulationBasedAlgorithm implements ParticipatingAlgorithm { private static final long serialVersionUID = 2287798336228462889L; + private static Logger logger = LoggerFactory.getLogger(SplitCooperativeAlgorithm.class); - protected CooperativeEntity context = null; - protected SplitStrategy splitStrategy = null; - // protected PopulationIterator populationIterator = null; - protected FitnessUpdateStrategy fitnessUpdateStrategy = null; - protected ContributionUpdateStrategy contributionUpdateStrategy = null; + protected CooperativeEntity context; + protected SplitStrategy splitStrategy; + protected FitnessUpdateStrategy fitnessUpdateStrategy; + protected ContributionUpdateStrategy contributionUpdateStrategy; + private int numberOfThreads; /** * Creates a new instance of a SplitCooperativeAglorithm. */ public SplitCooperativeAlgorithm() { - super(); - context = new CooperativeEntity(); - splitStrategy = new PerfectSplitStrategy(); - fitnessUpdateStrategy = new StandardFitnessUpdateStrategy(); - contributionUpdateStrategy = new StandardContributionUpdateStrategy(); + this.context = new CooperativeEntity(); + this.splitStrategy = new PerfectSplitStrategy(); + this.fitnessUpdateStrategy = new StandardFitnessUpdateStrategy(); + this.contributionUpdateStrategy = new StandardContributionUpdateStrategy(); + this.numberOfThreads = 2; } public SplitCooperativeAlgorithm(SplitCooperativeAlgorithm copy) { super(copy); - context = copy.context.getClone(); - splitStrategy = copy.splitStrategy; - fitnessUpdateStrategy = copy.fitnessUpdateStrategy; - contributionUpdateStrategy = copy.contributionUpdateStrategy; + this.context = copy.context.getClone(); + this.splitStrategy = copy.splitStrategy; + this.fitnessUpdateStrategy = copy.fitnessUpdateStrategy; + this.contributionUpdateStrategy = copy.contributionUpdateStrategy; + this.numberOfThreads = copy.numberOfThreads; } @Override @@ -83,12 +91,12 @@ public class SplitCooperativeAlgorithm extends MultiPopulationBasedAlgorithm imp @Override public void reset() { super.reset(); - context.reset(); + this.context.reset(); } @Override public OptimisationSolution getBestSolution() { - return new OptimisationSolution(context.getCandidateSolution().getClone(), context.getFitness()); + return new OptimisationSolution(this.context.getCandidateSolution().getClone(), this.context.getFitness()); } @Override @@ -99,48 +107,50 @@ public class SplitCooperativeAlgorithm extends MultiPopulationBasedAlgorithm imp } public CooperativeEntity getContext() { - return context; + return this.context; } public void setContext(CooperativeEntity c) { - context = c; + this.context = c; } @Override public void addPopulationBasedAlgorithm(PopulationBasedAlgorithm algorithm) { - if (!(algorithm instanceof ParticipatingAlgorithm)) + if (!(algorithm instanceof ParticipatingAlgorithm)) { throw new IllegalArgumentException("The given Algorithm is not a ParticipatingAlgorithm"); - subPopulationsAlgorithms.add(algorithm); + } + + this.subPopulationsAlgorithms.add(algorithm); } public int getNumberOfParticipants() { - return subPopulationsAlgorithms.size(); + return this.subPopulationsAlgorithms.size(); } public SplitStrategy getSplitStrategy() { - return splitStrategy; + return this.splitStrategy; } public void setSplitStrategy(SplitStrategy split) { - splitStrategy = split; + this.splitStrategy = split; } public ContributionUpdateStrategy getContributionUpdateStrategy() { - return contributionUpdateStrategy; + return this.contributionUpdateStrategy; } public void setContributionUpdateStrategy(ContributionUpdateStrategy contributionUpdate) { - contributionUpdateStrategy = contributionUpdate; + this.contributionUpdateStrategy = contributionUpdate; } @Override public Entity getContribution() { - return context; + return this.context; } @Override public Fitness getContributionFitness() { - return context.getFitness(); + return this.context.getFitness(); } /** @@ -150,46 +160,110 @@ public class SplitCooperativeAlgorithm extends MultiPopulationBasedAlgorithm imp */ @Override public void updateContributionFitness(Fitness fitness) { - context.setFitness(fitness); + this.context.setFitness(fitness); } public FitnessUpdateStrategy getFitnessUpdateStrategy() { - return fitnessUpdateStrategy; + return this.fitnessUpdateStrategy; } public void setFitnessUpdateStrategy(FitnessUpdateStrategy fitnessUpdate) { this.fitnessUpdateStrategy = fitnessUpdate; } + public void setNumberOfThreads(int nof) { + this.numberOfThreads = nof; + } + @Override public void performInitialisation() { - context.setCandidateSolution(optimisationProblem.getDomain().getBuiltRepresenation().getClone()); - splitStrategy.split(optimisationProblem, context, subPopulationsAlgorithms); - context.reset(); - for (Algorithm participant : subPopulationsAlgorithms) { - participant.performInitialisation(); - context.append(((ParticipatingAlgorithm) participant).getContribution()); + ExecutorService executorService = Executors.newFixedThreadPool(this.numberOfThreads); + final CountDownLatch latch = new CountDownLatch(this.subPopulationsAlgorithms.size()); + + this.context.setCandidateSolution(this.optimisationProblem.getDomain().getBuiltRepresenation().getClone()); + this.splitStrategy.split(this.optimisationProblem, this.context, this.subPopulationsAlgorithms); + this.context.reset(); + + for (final Algorithm population : this) { + executorService.execute(new Runnable() { + + @Override + public void run() { + try { + population.performInitialisation(); + } + catch (Exception e) { + logger.error("Unexpected exception has occured", e); + } + finally { + latch.countDown(); + } + } + + }); + } + + this.waitForCompletion(executorService, latch); + + for (Algorithm population : this) { + this.context.append(((ParticipatingAlgorithm) population).getContribution()); } } @Override public void performUninitialisation() { - // DataSetBuilder dataset = optimisationProblem.getDataSetBuilder(); - // ((ClusterableDataSet)dataset).assign((MixedVector)context.get()); - // dataset.uninitialise((MixedVector)context.get()); } @Override public void algorithmIteration() { + CooperativeEntity previousContext = this.context.getClone(); + ExecutorService executorService = Executors.newFixedThreadPool(this.numberOfThreads); + final CountDownLatch latch = new CountDownLatch(this.subPopulationsAlgorithms.size()); + + for (final Algorithm population : this) { + executorService.execute(new Runnable() { + + @Override + public void run() { + try { + population.performIteration(); + } + catch (Exception e) { + logger.error("Unexpected exception has occured", e); + } + finally { + latch.countDown(); + } + } + + }); + } + + this.waitForCompletion(executorService, latch); + for (Algorithm population : this) { - population.performIteration(); CooperativeOptimisationProblemAdapter participantProblem = (CooperativeOptimisationProblemAdapter) population.getOptimisationProblem(); - participantProblem.updateContext(context); + participantProblem.updateContext(this.context); ParticipatingAlgorithm participantAlgorithm = (ParticipatingAlgorithm) population; - contributionUpdateStrategy.updateContribution(participantAlgorithm.getContribution(), 0, context, participantProblem.getOffset(), participantProblem.getDimension()); - //TODO: The following statement might move out of this for-loop when I start clustering using the algorithm - fitnessUpdateStrategy.updateFitness(context); + this.contributionUpdateStrategy.updateContribution(participantAlgorithm.getContribution(), 0, this.context, participantProblem.getOffset(), participantProblem.getDimension()); + } + + this.fitnessUpdateStrategy.updateFitness(this.context); + + if (previousContext.compareTo(this.context) > 0) { + this.context = previousContext; } } + private void waitForCompletion(ExecutorService executorService, CountDownLatch latch) { + try { + latch.await(); + } + catch (InterruptedException ie) { + logger.error("Count down latch in awaiting state was interrupted", ie); + } + finally { + executorService.shutdown(); + } + } } -- 1.6.0.6 |
From: Theuns C. <the...@gm...> - 2009-06-10 06:43:17
|
All the changes in this commit is related to removal of the objects in ClusteringUtils that caused it to have a state. ThreadLocal is now removed and the important methods are static. Another important addition is the Cluster<C extends Vector> class is also a Type, more specifically a Set<Pattern<C>>. The Pattern<S extends Vector> class is also now a Type, more specifically a ForwardingStructuredType<S>. The notion of a weight was also incorporated into the Pattern class. All the other changes are related to incorporating the above two points. --- ...ngPotentialCentroidsInitialisationStrategy.java | 12 +- ...ataSetBasedCentroidsInitialisationStrategy.java | 8 +- .../cilib/clustering/kmeans/KMeans.java | 31 +- .../cooperative/SplitCooperativeAlgorithm.java | 2 +- .../clustering/ClusteringFitnessFunction.java | 155 ++++----- .../clustering/KHarmonicMeansFunction.java | 13 +- .../clustering/ParametricClusteringFunction.java | 6 +- .../ClusterCenterStrategy.java | 11 +- .../ClusterCentroidStrategy.java | 12 +- .../ClusterMeanStrategy.java | 19 +- .../validityindices/DaviesBouldinIndex.java | 15 +- .../clustering/validityindices/DunnIndex33.java | 27 +- .../clustering/validityindices/DunnIndex53.java | 21 +- .../validityindices/GeneralisedDunnIndex.java | 8 +- .../validityindices/HalkidiVazirgiannisIndex.java | 43 ++-- .../validityindices/MaulikBandyopadhyayIndex.java | 25 +- .../validityindices/ScatterSeperationRatio.java | 22 +- .../clustering/validityindices/TuriIndex.java | 12 +- .../VeenmanReindersBackerIndex.java | 46 ++-- .../java/net/sourceforge/cilib/math/StatUtils.java | 55 ++-- .../single/clustering/ClusterCentroids.java | 11 +- .../single/clustering/ClusterMeans.java | 15 +- .../clustering/ClusterStandardDeviations.java | 16 +- .../single/clustering/ClusterVariances.java | 16 +- .../single/clustering/DataSetDiameter.java | 13 +- .../single/clustering/NumberOfClustersFormed.java | 8 +- .../clustering/PlotClustersAndCentroids.java | 26 +- .../PlotHighDimensionalClustersAndCentroids.java | 49 ++-- .../cilib/problem/ClusteringProblem.java | 61 +++- .../sourceforge/cilib/problem/dataset/DataSet.java | 5 +- .../cilib/problem/dataset/DataSetManager.java | 8 +- .../problem/dataset/DynamicCirclesDataSet.java | 11 +- .../cilib/problem/dataset/DynamicDataSet.java | 4 +- .../dataset/DynamicHelixSpheresDataSet.java | 4 +- .../cilib/problem/dataset/LocalDataSet.java | 9 +- .../sourceforge/cilib/problem/dataset/Pattern.java | 52 --- .../problem/dataset/StaticDataSetBuilder.java | 73 +++-- ...DataSetBasedPositionInitialisationStrategy.java | 7 +- .../cilib/type/types/container/Cluster.java | 81 +++++ .../types/container/ForwardingStructuredType.java | 130 +++++++ .../cilib/type/types/container/Pattern.java | 134 +++++++ .../cilib/type/types/container/Set.java | 9 + .../sourceforge/cilib/util/ClusteringUtils.java | 365 +++++--------------- .../clustering/ClusteringFitnessFunctionTest.java | 7 + .../net/sourceforge/cilib/math/StatUtilsTest.java | 15 +- .../cilib/problem/dataset/MockStringDataSet.java | 13 +- .../cilib/util/ClusteringUtilsTest.java | 235 ++++++++----- 47 files changed, 1055 insertions(+), 865 deletions(-) delete mode 100644 src/main/java/net/sourceforge/cilib/problem/dataset/Pattern.java create mode 100644 src/main/java/net/sourceforge/cilib/type/types/container/Cluster.java create mode 100644 src/main/java/net/sourceforge/cilib/type/types/container/ForwardingStructuredType.java create mode 100644 src/main/java/net/sourceforge/cilib/type/types/container/Pattern.java diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/ContributingPotentialCentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/ContributingPotentialCentroidsInitialisationStrategy.java index 75132a8..9b34471 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/ContributingPotentialCentroidsInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/ContributingPotentialCentroidsInitialisationStrategy.java @@ -25,8 +25,8 @@ import java.util.ArrayList; import net.sourceforge.cilib.math.random.generator.MersenneTwister; import net.sourceforge.cilib.math.random.generator.Random; import net.sourceforge.cilib.problem.ClusteringProblem; -import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; +import net.sourceforge.cilib.type.types.container.Pattern; import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.DistanceMeasure; import org.slf4j.Logger; @@ -48,7 +48,7 @@ import org.slf4j.LoggerFactory; public class ContributingPotentialCentroidsInitialisationStrategy implements CentroidsInitialisationStrategy { private static final Logger logger = LoggerFactory.getLogger(ContributingPotentialCentroidsInitialisationStrategy.class); - private ArrayList<Pattern> patterns; + private ArrayList<Pattern<Vector>> patterns; private DistanceMeasure distanceMeasure; public ContributingPotentialCentroidsInitialisationStrategy() { @@ -79,12 +79,12 @@ public class ContributingPotentialCentroidsInitialisationStrategy implements Cen ArrayList<Vector> chosenCentroids = new ArrayList<Vector>(); for (int i = 0; i < numberOfClusters; ++i) { - Vector candidateCentroid = patterns.get(randomPattern.nextInt(patterns.size())).data.getClone(); + Vector candidateCentroid = patterns.get(randomPattern.nextInt(patterns.size())).getData().getClone(); if (i > 0) { while (randomProbability.nextDouble() >= this.calculateProbability(chosenCentroids, candidateCentroid)) { logger.debug("Trying another candidate centroid"); - candidateCentroid = patterns.get(randomPattern.nextInt(patterns.size())).data.getClone(); + candidateCentroid = patterns.get(randomPattern.nextInt(patterns.size())).getData().getClone(); } } chosenCentroids.add(candidateCentroid); @@ -105,7 +105,7 @@ public class ContributingPotentialCentroidsInitialisationStrategy implements Cen Random randomProbability = new MersenneTwister(); do { - candidateCentroid = patterns.get(randomPattern.nextInt(patterns.size())).data.getClone(); + candidateCentroid = patterns.get(randomPattern.nextInt(patterns.size())).getData().getClone(); } while (randomProbability.nextDouble() >= this.calculateProbability(centroids, candidateCentroid)); @@ -125,7 +125,7 @@ public class ContributingPotentialCentroidsInitialisationStrategy implements Cen double denominator = Double.MAX_VALUE; for (Vector chosenCentroid : chosenCentroids) { - denominator = Math.min(denominator, this.distanceMeasure.distance(chosenCentroid, pattern.data)); + denominator = Math.min(denominator, this.distanceMeasure.distance(chosenCentroid, pattern.getData())); } probability += denominator; } diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java index 1df40d6..2eda852 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java @@ -26,8 +26,8 @@ import java.util.ArrayList; import net.sourceforge.cilib.math.random.generator.MersenneTwister; import net.sourceforge.cilib.math.random.generator.Random; import net.sourceforge.cilib.problem.ClusteringProblem; -import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; +import net.sourceforge.cilib.type.types.container.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** @@ -39,7 +39,7 @@ import net.sourceforge.cilib.type.types.container.Vector; public class DataSetBasedCentroidsInitialisationStrategy implements CentroidsInitialisationStrategy { private static final long serialVersionUID = -3016201656688883387L; - private ArrayList<Pattern> patterns; + private ArrayList<Pattern<Vector>> patterns; public DataSetBasedCentroidsInitialisationStrategy() { this.patterns = null; @@ -69,7 +69,7 @@ public class DataSetBasedCentroidsInitialisationStrategy implements CentroidsIni Random random = new MersenneTwister(); for (int i = 0; i < numberOfCentroids; ++i) { - Vector centroid = patterns.get(random.nextInt(patterns.size())).data.getClone(); + Vector centroid = patterns.get(random.nextInt(patterns.size())).getData().getClone(); centroids.add(centroid); } @@ -83,7 +83,7 @@ public class DataSetBasedCentroidsInitialisationStrategy implements CentroidsIni @Override public Vector reinitialise(ArrayList<Vector> centroids, int which) { Random random = new MersenneTwister(); - Vector reinitialised = patterns.get(random.nextInt(patterns.size())).data.getClone(); + Vector reinitialised = patterns.get(random.nextInt(patterns.size())).getData().getClone(); centroids.set(which, reinitialised); return reinitialised; diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java index c1f3f98..b395120 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java @@ -23,14 +23,14 @@ package net.sourceforge.cilib.clustering.kmeans; import java.util.ArrayList; import java.util.Arrays; -import java.util.Hashtable; import java.util.List; import net.sourceforge.cilib.algorithm.Algorithm; import net.sourceforge.cilib.algorithm.SingularAlgorithm; -import net.sourceforge.cilib.math.StatUtils; +import net.sourceforge.cilib.problem.ClusteringProblem; import net.sourceforge.cilib.problem.OptimisationSolution; -import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; +import net.sourceforge.cilib.type.types.container.Cluster; import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.ClusteringUtils; import net.sourceforge.cilib.util.VectorUtils; @@ -83,10 +83,9 @@ public class KMeans extends SingularAlgorithm { super(rhs); this.centroidsInitialisationStrategy = rhs.centroidsInitialisationStrategy.getClone(); this.centroidsDiversificationStrategy = rhs.centroidsDiversificationStrategy.getClone(); - this.calculator = rhs.calculator.getClone(); - this.centroids = new ArrayList<Vector>(); + for (Vector centroid : rhs.centroids) { this.centroids.add(centroid.getClone()); } @@ -106,9 +105,9 @@ public class KMeans extends SingularAlgorithm { */ @Override public void performInitialisation() { - ClusteringUtils helper = ClusteringUtils.get(); + ClusteringProblem problem = (ClusteringProblem) this.getOptimisationProblem(); - this.centroids = this.centroidsInitialisationStrategy.initialise(helper.getClusteringProblem(), helper.getDataSetBuilder()); + this.centroids = this.centroidsInitialisationStrategy.initialise(problem, (StaticDataSetBuilder) problem.getDataSetBuilder()); this.centroidsDiversificationStrategy.initialise(this.centroids); } @@ -119,12 +118,13 @@ public class KMeans extends SingularAlgorithm { public void algorithmIteration() { calculator.getFitness(ClusteringUtils.assembleCentroids(this.centroids), true); - // the fitness calculation step already arranged the clusters and centroids with the help of ClusteringUtils - ClusteringUtils helper = ClusteringUtils.get(); - ArrayList<Hashtable<Integer, Pattern>> clusters = helper.getOriginalClusters(); + //TODO: When we start using Guice, this statement should be updated + //TODO: This algorithm is not a population based algorithm and therefore Algorithm.get() will return the correct algorithm + ClusteringProblem problem = (ClusteringProblem) Algorithm.get().getOptimisationProblem(); + ArrayList<Cluster<Vector>> clusters = ClusteringUtils.arrangeClustersAndCentroids(this.centroids, problem, (StaticDataSetBuilder) problem.getDataSetBuilder()); - for (int i = 0; i < clusters.size(); i++) { - Hashtable<Integer, Pattern> cluster = clusters.get(i); + for (int i = 0; i < clusters.size(); ++i) { + Cluster<Vector> cluster = clusters.get(i); Vector centroid = null; // TODO: I don't know if this if-else is part of the original KMeans algorithm @@ -133,15 +133,16 @@ public class KMeans extends SingularAlgorithm { centroid = this.centroidsInitialisationStrategy.reinitialise(centroids, i); // might return unbounded Vector } else { - // the centroid becomes the mean of cluster i - centroid = StatUtils.meanVector(cluster.values()); // returns unbounded Vector + // the centroid becomes the mean of the cluster + centroid = cluster.getMean(); // returns unbounded Vector } // we need to set the bounds of the centroid, because some centroids might be unbounded Vectors - Vector builtRepresentation = (Vector) helper.getClusteringProblem().getBehaviouralDomain().getBuiltRepresenation(); + Vector builtRepresentation = (Vector) problem.getBehaviouralDomain().getBuiltRepresenation(); centroid = VectorUtils.setBounds(centroid, VectorUtils.createLowerBoundVector(builtRepresentation), VectorUtils.createUpperBoundVector(builtRepresentation)); this.centroids.set(i, centroid); + cluster.setCentroid(centroid); this.centroidsDiversificationStrategy.diversify(centroids, i); } } diff --git a/src/main/java/net/sourceforge/cilib/cooperative/SplitCooperativeAlgorithm.java b/src/main/java/net/sourceforge/cilib/cooperative/SplitCooperativeAlgorithm.java index e9b640b..3a2acac 100644 --- a/src/main/java/net/sourceforge/cilib/cooperative/SplitCooperativeAlgorithm.java +++ b/src/main/java/net/sourceforge/cilib/cooperative/SplitCooperativeAlgorithm.java @@ -193,7 +193,7 @@ public class SplitCooperativeAlgorithm extends MultiPopulationBasedAlgorithm imp population.performInitialisation(); } catch (Exception e) { - logger.error("Unexpected exception has occured", e); + logger.error("Unexpected exception occured", e); } finally { latch.countDown(); diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java b/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java index c3a1514..ce5207d 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java @@ -22,16 +22,18 @@ package net.sourceforge.cilib.functions.clustering; import java.util.ArrayList; -import java.util.Collection; -import java.util.Hashtable; +import net.sourceforge.cilib.algorithm.Algorithm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.sourceforge.cilib.functions.ContinuousFunction; import net.sourceforge.cilib.functions.clustering.clustercenterstrategies.ClusterCenterStrategy; import net.sourceforge.cilib.functions.clustering.clustercenterstrategies.ClusterCentroidStrategy; -import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.problem.ClusteringProblem; +import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; +import net.sourceforge.cilib.type.types.container.Cluster; +import net.sourceforge.cilib.type.types.container.Pattern; import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.ClusteringUtils; @@ -52,10 +54,9 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { private static final long serialVersionUID = 4834673666638644106L; protected Logger logger = LoggerFactory.getLogger(this.getClass()); - protected ClusteringUtils helper = null; - protected ClusterCenterStrategy clusterCenterStrategy = null; - protected ArrayList<Hashtable<Integer, Pattern>> arrangedClusters = null; - protected ArrayList<Vector> arrangedCentroids = null; + protected ClusteringProblem problem; + protected ClusterCenterStrategy clusterCenterStrategy; + protected ArrayList<Cluster<Vector>> significantClusters; protected int clustersFormed = 0; /** @@ -64,7 +65,7 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { * domain is not set, because it should be specified on the {@link ClusteringProblem}. */ public ClusteringFitnessFunction() { - clusterCenterStrategy = new ClusterCentroidStrategy(); + this.clusterCenterStrategy = new ClusterCentroidStrategy(); } @Override @@ -75,34 +76,28 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { * <ol> * <li>Arrange the patterns in the dataset to belong to its closest centroid. We don't * care how this is done, since it is handled by the - * {@link ClusteringUtils#arrangeClustersAndCentroids(Vector)} method. We also assume - * that this method removes empty clusters and their associated centroids from the - * <i>arranged lists</i></li> - * <li>Sets the {@link #arrangedClusters} member variable which is available to - * sub-classes.</li> - * <li>Sets the {@link #arrangedCentroids} member variable which is available to + * {@link ClusteringUtils#arrangeClustersAndCentroids(net.sourceforge.cilib.type.types.container.Vector, net.sourceforge.cilib.problem.ClusteringProblem, net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder)} + * method. We also assume that this method only returns significant clusters</li> + * <li>Sets the {@link #significantClusters} member variable which is available to * sub-classes.</li> * <li>Calculate the fitness using the given centroids {@linkplain Vector}. We don't * care how this is done, since it is handled by the abstraction (polymorphism) created - * by the hierarchy of this class. This is achieved via the abstact + * by the hierarchy of this class. This is achieved via the abstract * {@link #calculateFitness()} method</li> - * <li>Validate the fitness, i.e. make sure the fitness is positive - * <code>>= 0.0</code>.</li> * </ol> - * Steps 1 - 3 have to be performed before the fitness is calculated, using the given - * <tt>centroids</tt> {@linkplain Vector}, in step 4. + * Steps 1 and 2 have to be performed before the fitness is calculated, using the given + * <tt>centroids</tt> {@linkplain Vector}, in step 3. * * @param centroids The {@link Vector} representing the centroid vectors * @return the fitness that has been calculated */ @Override public double evaluate(Vector centroids) { - helper = ClusteringUtils.get(); //this statement should not be in a constructor - helper.arrangeClustersAndCentroids(centroids); - arrangedClusters = helper.getArrangedClusters(); - arrangedCentroids = helper.getArrangedCentroids(); + //TODO: When we start using Guice, this statement should be updated (we want the main algorithm) + this.problem = (ClusteringProblem) Algorithm.getAlgorithmList().get(0).getOptimisationProblem(); - clustersFormed = arrangedClusters.size(); + significantClusters = ClusteringUtils.arrangeClustersAndCentroids(centroids, this.problem, (StaticDataSetBuilder) this.problem.getDataSetBuilder()); + clustersFormed = significantClusters.size(); /* * TODO: Figure out a nice OO way to determine whether this function is being @@ -134,13 +129,12 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { public double calculateQuantisationError() { double quantisationError = 0.0; - for (int i = 0; i < clustersFormed; i++) { + for (Cluster<Vector> cluster : this.significantClusters) { double averageDistance = 0.0; - Collection<Pattern> cluster = arrangedClusters.get(i).values(); - Vector center = clusterCenterStrategy.getCenter(i); + Vector center = this.clusterCenterStrategy.getCenter(cluster); - for (Pattern pattern : cluster) { - averageDistance += helper.calculateDistance(pattern.data, center); + for (Pattern<Vector> pattern : cluster) { + averageDistance += this.problem.calculateDistance(pattern.getData(), center); } averageDistance /= cluster.size(); quantisationError += averageDistance; @@ -167,13 +161,12 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { public double calculateMaximumAverageDistance() { double maximumAverageDistance = 0.0; - for (int i = 0; i < clustersFormed; i++) { + for (Cluster<Vector> cluster : this.significantClusters) { double averageDistance = 0.0; - Collection<Pattern> cluster = arrangedClusters.get(i).values(); - Vector center = clusterCenterStrategy.getCenter(i); + Vector center = this.clusterCenterStrategy.getCenter(cluster); - for (Pattern pattern : cluster) { - averageDistance += helper.calculateDistance(pattern.data, center); + for (Pattern<Vector> pattern : cluster) { + averageDistance += this.problem.calculateDistance(pattern.getData(), center); } averageDistance /= cluster.size(); maximumAverageDistance = Math.max(maximumAverageDistance, averageDistance); @@ -190,11 +183,13 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { public double calculateMinimumInterClusterDistance() { double minimumInterClusterDistance = Double.MAX_VALUE; - for (int i = 0; i < clustersFormed - 1; i++) { - Vector leftCenter = clusterCenterStrategy.getCenter(i); - for (int j = i + 1; j < clustersFormed; j++) { - Vector rightCenter = clusterCenterStrategy.getCenter(j); - minimumInterClusterDistance = Math.min(minimumInterClusterDistance, helper.calculateDistance(leftCenter, rightCenter)); + for (int i = 0; i < clustersFormed - 1; ++i) { + Vector leftCenter = this.clusterCenterStrategy.getCenter(this.significantClusters.get(i)); + + for (int j = i + 1; j < clustersFormed; ++j) { + Vector rightCenter = this.clusterCenterStrategy.getCenter(this.significantClusters.get(j)); + + minimumInterClusterDistance = Math.min(minimumInterClusterDistance, this.problem.calculateDistance(leftCenter, rightCenter)); } } return minimumInterClusterDistance; @@ -209,11 +204,13 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { public double calculateMaximumInterClusterDistance() { double maximumInterClusterDistance = -Double.MAX_VALUE; - for (int i = 0; i < clustersFormed - 1; i++) { - Vector leftCenter = clusterCenterStrategy.getCenter(i); - for (int j = i + 1; j < clustersFormed; j++) { - Vector rightCenter = clusterCenterStrategy.getCenter(j); - maximumInterClusterDistance = Math.max(maximumInterClusterDistance, helper.calculateDistance(leftCenter, rightCenter)); + for (int i = 0; i < clustersFormed - 1; ++i) { + Vector leftCenter = this.clusterCenterStrategy.getCenter(this.significantClusters.get(i)); + + for (int j = i + 1; j < clustersFormed; ++j) { + Vector rightCenter = this.clusterCenterStrategy.getCenter(this.significantClusters.get(j)); + + maximumInterClusterDistance = Math.max(maximumInterClusterDistance, this.problem.calculateDistance(leftCenter, rightCenter)); } } return maximumInterClusterDistance; @@ -236,9 +233,9 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { public double calculateMinimumSetDistance(int i, int j) { double distance = Double.MAX_VALUE; - for (int leftPatternIndex : arrangedClusters.get(i).keySet()) { - for (int rightPatternIndex : arrangedClusters.get(j).keySet()) { - distance = Math.min(distance, helper.calculateDistance(leftPatternIndex, rightPatternIndex)); + for (Pattern<Vector> leftPattern : this.significantClusters.get(i)) { + for (Pattern<Vector> rightPattern : this.significantClusters.get(j)) { + distance = Math.min(distance, this.problem.calculateDistance(leftPattern.getPatternIndex(), rightPattern.getPatternIndex())); } } return distance; @@ -260,9 +257,9 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { public double calculateMaximumSetDistance(int i, int j) { double distance = -Double.MAX_VALUE; - for (int leftPatternIndex : arrangedClusters.get(i).keySet()) { - for (int rightPatternIndex : arrangedClusters.get(j).keySet()) { - distance = Math.max(distance, helper.calculateDistance(leftPatternIndex, rightPatternIndex)); + for (Pattern<Vector> leftPattern : this.significantClusters.get(i)) { + for (Pattern<Vector> rightPattern : this.significantClusters.get(j)) { + distance = Math.max(distance, this.problem.calculateDistance(leftPattern.getPatternIndex(), rightPattern.getPatternIndex())); } } return distance; @@ -285,12 +282,12 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { public double calculateAverageSetDistance(int i, int j) { double distance = 0.0; - for (int leftPatternIndex : arrangedClusters.get(i).keySet()) { - for (int rightPatternIndex : arrangedClusters.get(j).keySet()) { - distance += helper.calculateDistance(leftPatternIndex, rightPatternIndex); + for (Pattern<Vector> leftPattern : this.significantClusters.get(i)) { + for (Pattern<Vector> rightPattern : this.significantClusters.get(j)) { + distance += this.problem.calculateDistance(leftPattern.getPatternIndex(), rightPattern.getPatternIndex()); } } - return distance / (arrangedClusters.get(i).size() * arrangedClusters.get(j).size()); + return distance / (this.significantClusters.get(i).size() * this.significantClusters.get(j).size()); } /** @@ -303,15 +300,12 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { */ public double calculateClusterDiameter(int k) { double diameter = 0.0; - Collection<Integer> indices = arrangedClusters.get(k).keySet(); + Cluster<Vector> cluster = this.significantClusters.get(k); - for (int leftPatternIndex : indices) { - for (int rightPatternIndex : indices) { - if (leftPatternIndex == rightPatternIndex) { - continue; - } - else { - diameter = Math.max(diameter, helper.calculateDistance(leftPatternIndex, rightPatternIndex)); + for (Pattern<Vector> leftPattern : cluster) { + for (Pattern<Vector> rightPattern : cluster) { + if (leftPattern != rightPattern) { + diameter = Math.max(diameter, this.problem.calculateDistance(leftPattern.getPatternIndex(), rightPattern.getPatternIndex())); } } } @@ -333,12 +327,11 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { public double calculateIntraClusterDistance() { double intraClusterDistance = 0.0; - for (int i = 0; i < clustersFormed; i++) { - Collection<Pattern> cluster = arrangedClusters.get(i).values(); - Vector center = clusterCenterStrategy.getCenter(i); + for (Cluster<Vector> cluster : this.significantClusters) { + Vector center = this.clusterCenterStrategy.getCenter(cluster); - for (Pattern pattern : cluster) { - intraClusterDistance += helper.calculateDistance(pattern.data, center); + for (Pattern<Vector> pattern : cluster) { + intraClusterDistance += this.problem.calculateDistance(pattern.getData(), center); } } return intraClusterDistance; @@ -355,11 +348,7 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { * @return the average intra-cluster distance for all clusters. */ public double calculateAverageIntraClusterDistance() { - return calculateIntraClusterDistance() / helper.getNumberOfPatternsInDataSet(); - } - - public void setClusterCenterStrategy(ClusterCenterStrategy ccs) { - clusterCenterStrategy = ccs; + return calculateIntraClusterDistance() / ((StaticDataSetBuilder) this.problem.getDataSetBuilder()).getNumberOfPatterns(); } @Override @@ -375,26 +364,4 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { protected Double worstFitness() { return getMaximum(); } - - /** - * This method logs the cases when the fitness is less than zero. We do not want the - * Parametric fitness to be less than zero. Fitnesses drop below zero when the centroids - * are outside the given domain which causes {@linkplain zMax} to be too small to - * compensate. - * - * TODO: Should this function always return the fitness? - * TODO: Or should it return NaN when the fitness drops below 0.0? - * TODO: Or should we throw an exception? - * - * @param fitness the fitness value that will be validated. - * @return the fitness. - * @deprecated depending on the distance measure used, a negative fitness function may be allowed - */ - protected double validateFitness(double fitness) { - if (fitness < 0.0) { - logger.error(this.getClass().getSimpleName() + " fitness < 0.0 : " + fitness); - logger.error("Number of clusters formed = " + clustersFormed); - } - return fitness; - } } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/KHarmonicMeansFunction.java b/src/main/java/net/sourceforge/cilib/functions/clustering/KHarmonicMeansFunction.java index e963b61..3634821 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/KHarmonicMeansFunction.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/KHarmonicMeansFunction.java @@ -21,7 +21,9 @@ */ package net.sourceforge.cilib.functions.clustering; -import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; +import net.sourceforge.cilib.type.types.container.Cluster; +import net.sourceforge.cilib.type.types.container.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** @@ -38,12 +40,13 @@ public class KHarmonicMeansFunction extends ClusteringFitnessFunction { public double calculateFitness() { double harmonicMean = 0.0; - for (Pattern pattern : helper.getPatternsInDataSet()) { + for (Pattern<Vector> pattern : ((StaticDataSetBuilder) this.problem.getDataSetBuilder()).getPatterns()) { double sumOfReciprocals = 0.0; - for (int i = 0; i < arrangedClusters.size(); i++) { - Vector center = clusterCenterStrategy.getCenter(i); - sumOfReciprocals += 1.0 / Math.max(helper.calculateDistance(pattern.data, center), Double.MIN_VALUE); // if the distance == 0.0, use a very small value + for (Cluster<Vector> cluster : this.significantClusters) { + Vector center = this.clusterCenterStrategy.getCenter(cluster); + + sumOfReciprocals += 1.0 / Math.max(this.problem.calculateDistance(pattern.getData(), center), Double.MIN_VALUE); // if the distance == 0.0, use a very small value } harmonicMean += clustersFormed / sumOfReciprocals; } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/ParametricClusteringFunction.java b/src/main/java/net/sourceforge/cilib/functions/clustering/ParametricClusteringFunction.java index b21794e..cdd6546 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/ParametricClusteringFunction.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/ParametricClusteringFunction.java @@ -47,12 +47,12 @@ public class ParametricClusteringFunction extends ClusteringFitnessFunction { protected double zMax = -1.0; public ParametricClusteringFunction() { - super(); w1 = new ConstantControlParameter(0.5); w2 = new ConstantControlParameter(0.5); zMax = -1.0; } + @Override public ParametricClusteringFunction getClone() { return new ParametricClusteringFunction(); } @@ -114,11 +114,11 @@ public class ParametricClusteringFunction extends ClusteringFitnessFunction { * @return the maximum distance possible between two {@linkplain Vector}s for the specified domain. */ protected double zMax() { - Vector prototype = (Vector) helper.getClusteringProblem().getDomain().getBuiltRepresenation(); + Vector prototype = (Vector) this.problem.getDomain().getBuiltRepresenation(); Vector upperBoundVector = VectorUtils.createUpperBoundVector(prototype); Vector lowerBoundVector = VectorUtils.createLowerBoundVector(prototype); - return helper.calculateDistance(upperBoundVector, lowerBoundVector); + return this.problem.calculateDistance(upperBoundVector, lowerBoundVector); } public void updateControlParameters() { diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterCenterStrategy.java b/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterCenterStrategy.java index dd3bb87..add5eac 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterCenterStrategy.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterCenterStrategy.java @@ -23,6 +23,7 @@ package net.sourceforge.cilib.functions.clustering.clustercenterstrategies; import java.io.Serializable; +import net.sourceforge.cilib.type.types.container.Cluster; import net.sourceforge.cilib.type.types.container.Vector; /** @@ -31,11 +32,11 @@ import net.sourceforge.cilib.type.types.container.Vector; * refers to a cluster's {@link ClusterMeanStrategy mean}. * @author Theuns Cloete */ -public interface ClusterCenterStrategy extends Serializable { +public interface ClusterCenterStrategy<C extends Vector> extends Serializable { /** - * Sub-classes should implement this method to return the desired center of cluster i. - * @param i The integer representing the cluster for which a center should be returned - * @return a {@link Vector} representing the center of cluster i + * Sub-classes should implement this method to return the desired center of the given cluster. + * @param cluster the cluster whose center should be returned + * @return a {@link Vector} representing the center of the given {@link Cluster} */ - public Vector getCenter(int i); + public C getCenter(Cluster<C> cluster); } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterCentroidStrategy.java b/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterCentroidStrategy.java index 9b2807d..80b0558 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterCentroidStrategy.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterCentroidStrategy.java @@ -21,18 +21,18 @@ */ package net.sourceforge.cilib.functions.clustering.clustercenterstrategies; +import net.sourceforge.cilib.type.types.container.Cluster; import net.sourceforge.cilib.type.types.container.Vector; -import net.sourceforge.cilib.util.ClusteringUtils; /** - * The <i>center of a cluster</i> is interpreted as the <i>centroid of a cluster</i>. + * The <i>center of the cluster</i> is interpreted as the <i>centroid of the cluster</i>. + * * @author Theuns Cloete */ -public class ClusterCentroidStrategy implements ClusterCenterStrategy { +public class ClusterCentroidStrategy<C extends Vector> implements ClusterCenterStrategy<C> { private static final long serialVersionUID = -7831635507079248268L; public ClusterCentroidStrategy() { - super(); } /** @@ -41,7 +41,7 @@ public class ClusterCentroidStrategy implements ClusterCenterStrategy { * @return the centroid of cluster i */ @Override - public Vector getCenter(int i) { - return ClusteringUtils.get().getArrangedCentroids().get(i); + public C getCenter(Cluster<C> cluster) { + return cluster.getCentroid(); } } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterMeanStrategy.java b/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterMeanStrategy.java index 575faa7..d707c8e 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterMeanStrategy.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterMeanStrategy.java @@ -21,33 +21,26 @@ */ package net.sourceforge.cilib.functions.clustering.clustercenterstrategies; -import java.util.Collection; - -import net.sourceforge.cilib.math.StatUtils; -import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.type.types.container.Cluster; import net.sourceforge.cilib.type.types.container.Vector; -import net.sourceforge.cilib.util.ClusteringUtils; /** * The <i>center of a cluster</i> is interpreted as the <i>mean of a cluster</i>. * @author Theuns Cloete */ -public class ClusterMeanStrategy implements ClusterCenterStrategy { +public class ClusterMeanStrategy<C extends Vector> implements ClusterCenterStrategy<C> { private static final long serialVersionUID = 9080168372118441393L; public ClusterMeanStrategy() { - super(); } /** * In this case, we are interested in the mean of the cluster. - * @param i The integer representing the cluster for which the mean should be returned - * @return the mean of cluster i + * @param cluster the cluster whose mean should be returned + * @return the mean of the given {@link Cluster} */ @Override - public Vector getCenter(int i) { - Collection<Pattern> cluster = ClusteringUtils.get().getArrangedClusters().get(i).values(); - - return StatUtils.meanVector(cluster); + public C getCenter(Cluster<C> cluster) { + return cluster.getMean(); } } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DaviesBouldinIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DaviesBouldinIndex.java index de48927..b0ed542 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DaviesBouldinIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DaviesBouldinIndex.java @@ -21,9 +21,8 @@ */ package net.sourceforge.cilib.functions.clustering.validityindices; -import java.util.Collection; - -import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.type.types.container.Cluster; +import net.sourceforge.cilib.type.types.container.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** @@ -68,11 +67,11 @@ public class DaviesBouldinIndex extends ScatterSeperationRatio { @Override protected double calculateWithinClusterScatter(int k) { double withinClusterScatter = 0.0; - Collection<Pattern> cluster = arrangedClusters.get(k).values(); - Vector center = clusterCenterStrategy.getCenter(k); + Cluster<Vector> cluster = this.significantClusters.get(k); + Vector center = this.clusterCenterStrategy.getCenter(cluster); - for (Pattern pattern : cluster) { - withinClusterScatter += helper.calculateDistance(pattern.data, center); + for (Pattern<Vector> pattern : cluster) { + withinClusterScatter += this.problem.calculateDistance(pattern.getData(), center); } return withinClusterScatter /= cluster.size(); } @@ -83,7 +82,7 @@ public class DaviesBouldinIndex extends ScatterSeperationRatio { */ @Override protected double calculateBetweenClusterSeperation(int i, int j) { - return helper.calculateDistance(clusterCenterStrategy.getCenter(i), clusterCenterStrategy.getCenter(j)); + return this.problem.calculateDistance(this.clusterCenterStrategy.getCenter(this.significantClusters.get(i)), this.clusterCenterStrategy.getCenter(this.significantClusters.get(j))); } @Override diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex33.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex33.java index 2eb95dd..781ff5c 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex33.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex33.java @@ -21,10 +21,9 @@ */ package net.sourceforge.cilib.functions.clustering.validityindices; -import java.util.Collection; - import net.sourceforge.cilib.functions.clustering.clustercenterstrategies.ClusterMeanStrategy; -import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.type.types.container.Cluster; +import net.sourceforge.cilib.type.types.container.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** @@ -42,7 +41,12 @@ public class DunnIndex33 extends GeneralisedDunnIndex { private static final long serialVersionUID = -3307601269742583865L; public DunnIndex33() { - clusterCenterStrategy = new ClusterMeanStrategy(); + this.clusterCenterStrategy = new ClusterMeanStrategy(); + } + + @Override + public DunnIndex33 getClone() { + return new DunnIndex33(); } /** @@ -51,11 +55,11 @@ public class DunnIndex33 extends GeneralisedDunnIndex { @Override protected double calculateWithinClusterScatter(int k) { double averageDistance = 0.0; - Collection<Pattern> cluster = arrangedClusters.get(k).values(); - Vector center = clusterCenterStrategy.getCenter(k); + Cluster<Vector> cluster = this.significantClusters.get(k); + Vector center = this.clusterCenterStrategy.getCenter(cluster); - for (Pattern pattern : cluster) { - averageDistance += helper.calculateDistance(pattern.data, center); + for (Pattern<Vector> pattern : cluster) { + averageDistance += this.problem.calculateDistance(pattern.getData(), center); } return 2.0 * (averageDistance / cluster.size()); } @@ -65,11 +69,6 @@ public class DunnIndex33 extends GeneralisedDunnIndex { */ @Override protected double calculateBetweenClusterSeperation(int i, int j) { - return calculateAverageSetDistance(i, j); - } - - @Override - public DunnIndex33 getClone() { - return new DunnIndex33(); + return this.calculateAverageSetDistance(i, j); } } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex53.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex53.java index c238c40..c50154a 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex53.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex53.java @@ -21,9 +21,8 @@ */ package net.sourceforge.cilib.functions.clustering.validityindices; -import java.util.Collection; - -import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.type.types.container.Cluster; +import net.sourceforge.cilib.type.types.container.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** @@ -49,17 +48,17 @@ public class DunnIndex53 extends DunnIndex33 { @Override protected double calculateBetweenClusterSeperation(int i, int j) { double lhsAverage = 0.0, rhsAverage = 0.0; - Collection<Pattern> leftCluster = arrangedClusters.get(i).values(); - Collection<Pattern> rightCluster = arrangedClusters.get(j).values(); - Vector leftCenter = clusterCenterStrategy.getCenter(i); - Vector rightCenter = clusterCenterStrategy.getCenter(j); + Cluster<Vector> leftCluster = this.significantClusters.get(i); + Cluster<Vector> rightCluster = this.significantClusters.get(j); + Vector leftCenter = this.clusterCenterStrategy.getCenter(leftCluster); + Vector rightCenter = this.clusterCenterStrategy.getCenter(rightCluster); - for (Pattern pattern : leftCluster) { - lhsAverage += helper.calculateDistance(pattern.data, rightCenter); + for (Pattern<Vector> pattern : leftCluster) { + lhsAverage += this.problem.calculateDistance(pattern.getData(), rightCenter); } - for (Pattern pattern : rightCluster) { - rhsAverage += helper.calculateDistance(pattern.data, leftCenter); + for (Pattern<Vector> pattern : rightCluster) { + rhsAverage += this.problem.calculateDistance(pattern.getData(), leftCenter); } return (lhsAverage + rhsAverage) / (leftCluster.size() + rightCluster.size()); diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/GeneralisedDunnIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/GeneralisedDunnIndex.java index 0765962..342baa7 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/GeneralisedDunnIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/GeneralisedDunnIndex.java @@ -48,16 +48,16 @@ public abstract class GeneralisedDunnIndex extends ScatterSeperationRatio { public double calculateFitness() { double withinScatter = -Double.MAX_VALUE, betweenSeperation = Double.MAX_VALUE; - cacheWithinClusterScatter(); - cacheBetweenClusterSeperation(); + this.cacheWithinClusterScatter(); + this.cacheBetweenClusterSeperation(); for (int i = 0; i < clustersFormed; i++) { - withinScatter = Math.max(withinScatter, getWithinClusterScatter(i)); + withinScatter = Math.max(withinScatter, this.getWithinClusterScatter(i)); } for (int i = 0; i < clustersFormed - 1; i++) { for (int j = i + 1; j < clustersFormed; j++) { - betweenSeperation = Math.min(betweenSeperation, getBetweenClusterSeperation(i, j)); + betweenSeperation = Math.min(betweenSeperation, this.getBetweenClusterSeperation(i, j)); } } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/HalkidiVazirgiannisIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/HalkidiVazirgiannisIndex.java index 6de0316..4cad822 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/HalkidiVazirgiannisIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/HalkidiVazirgiannisIndex.java @@ -22,8 +22,9 @@ package net.sourceforge.cilib.functions.clustering.validityindices; import net.sourceforge.cilib.functions.clustering.ClusteringFitnessFunction; -import net.sourceforge.cilib.math.StatUtils; -import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; +import net.sourceforge.cilib.type.types.container.Cluster; +import net.sourceforge.cilib.type.types.container.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** @@ -52,7 +53,7 @@ public class HalkidiVazirgiannisIndex extends ClusteringFitnessFunction { */ @Override public double calculateFitness() { - return calculateWithinClusterScatter() + calculateBetweenClusterSeperation(); + return this.calculateWithinClusterScatter() + this.calculateBetweenClusterSeperation(); } /** @@ -62,17 +63,17 @@ public class HalkidiVazirgiannisIndex extends ClusteringFitnessFunction { */ protected double calculateWithinClusterScatter() { double scattering = 0.0; - double datasetVariance = helper.getDataSetVariance(); + double datasetVariance = ((StaticDataSetBuilder) this.problem.getDataSetBuilder()).getVariance(); double clusterVariance = 0.0; - stdev = 0.0; - for (int i = 0; i < clustersFormed; i++) { - clusterVariance = StatUtils.variance(arrangedClusters.get(i).values(), clusterCenterStrategy.getCenter(i)); + this.stdev = 0.0; + for (Cluster<Vector> cluster : this.significantClusters) { + clusterVariance = cluster.getVariance(this.clusterCenterStrategy.getCenter(cluster)); scattering += clusterVariance; - stdev += clusterVariance; + this.stdev += clusterVariance; } - stdev = Math.sqrt(stdev); - stdev /= clustersFormed; + this.stdev = Math.sqrt(this.stdev); + this.stdev /= clustersFormed; scattering /= datasetVariance; return scattering /= clustersFormed; } @@ -86,26 +87,26 @@ public class HalkidiVazirgiannisIndex extends ClusteringFitnessFunction { double density = 0.0; int midDensity = 0, leftDensity = 0, rightDensity = 0; - for (int i = 0; i < clustersFormed; i++) { - leftCenter = clusterCenterStrategy.getCenter(i); - for (int j = 0; j < clustersFormed; j++) { - if (i != j) { - rightCenter = clusterCenterStrategy.getCenter(j); + for (Cluster<Vector> leftCluster : this.significantClusters) { + leftCenter = this.clusterCenterStrategy.getCenter(leftCluster); + for (Cluster<Vector> rightCluster : this.significantClusters) { + if (leftCluster != rightCluster) { + rightCenter = this.clusterCenterStrategy.getCenter(rightCluster); midPoint = leftCenter.plus(rightCenter); midPoint = midPoint.divide(2.0); midDensity = leftDensity = rightDensity = 0; - for (Pattern pattern : arrangedClusters.get(i).values()) { - if (helper.calculateDistance(pattern.data, midPoint) <= stdev) + for (Pattern<Vector> pattern : leftCluster) { + if (this.problem.calculateDistance(pattern.getData(), midPoint) <= stdev) ++midDensity; - if (helper.calculateDistance(pattern.data, leftCenter) <= stdev) + if (this.problem.calculateDistance(pattern.getData(), leftCenter) <= stdev) ++leftDensity; } - for (Pattern pattern : arrangedClusters.get(j).values()) { - if (helper.calculateDistance(pattern.data, midPoint) <= stdev) + for (Pattern<Vector> pattern : rightCluster) { + if (this.problem.calculateDistance(pattern.getData(), midPoint) <= stdev) ++midDensity; - if (helper.calculateDistance(pattern.data, rightCenter) <= stdev) + if (this.problem.calculateDistance(pattern.getData(), rightCenter) <= stdev) ++rightDensity; } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/MaulikBandyopadhyayIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/MaulikBandyopadhyayIndex.java index 979b030..b5ad4a7 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/MaulikBandyopadhyayIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/MaulikBandyopadhyayIndex.java @@ -22,7 +22,8 @@ package net.sourceforge.cilib.functions.clustering.validityindices; import net.sourceforge.cilib.functions.clustering.ClusteringFitnessFunction; -import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; +import net.sourceforge.cilib.type.types.container.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** @@ -46,12 +47,17 @@ public class MaulikBandyopadhyayIndex extends ClusteringFitnessFunction { } @Override + public MaulikBandyopadhyayIndex getClone() { + return new MaulikBandyopadhyayIndex(); + } + + @Override public double calculateFitness() { return Math.pow(termOne() * termTwo() * termThree(), p); } private double termOne() { - return 1.0 / clustersFormed; + return 1.0 / this.clustersFormed; } private double termTwo() { @@ -62,16 +68,16 @@ public class MaulikBandyopadhyayIndex extends ClusteringFitnessFunction { * cluster. In this case, the dataset mean can be thought of as the dataset's centroid as * well. */ - Vector mean = helper.getDataSetMean(); - for (Pattern pattern : helper.getPatternsInDataSet()) { - intraDatasetDistance += helper.calculateDistance(pattern.data, mean); + Vector mean = ((StaticDataSetBuilder) this.problem.getDataSetBuilder()).getMean(); + for (Pattern<Vector> pattern : ((StaticDataSetBuilder) this.problem.getDataSetBuilder()).getPatterns()) { + intraDatasetDistance += this.problem.calculateDistance(pattern.getData(), mean); } - return intraDatasetDistance / calculateIntraClusterDistance(); + return intraDatasetDistance / this.calculateIntraClusterDistance(); } private double termThree() { - return calculateMaximumInterClusterDistance(); + return this.calculateMaximumInterClusterDistance(); } public void setP(int pu) { @@ -79,9 +85,4 @@ public class MaulikBandyopadhyayIndex extends ClusteringFitnessFunction { throw new IllegalArgumentException("The p-value cannot be < 1"); p = pu; } - - @Override - public MaulikBandyopadhyayIndex getClone() { - return new MaulikBandyopadhyayIndex(); - } } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/ScatterSeperationRatio.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/ScatterSeperationRatio.java index c61a830..ef171fd 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/ScatterSeperationRatio.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/ScatterSeperationRatio.java @@ -35,29 +35,29 @@ import net.sourceforge.cilib.functions.clustering.ClusteringFitnessFunction; public abstract class ScatterSeperationRatio extends ClusteringFitnessFunction { private static final long serialVersionUID = 6758442782079174817L; - protected ArrayList<Double> withinClusterScatterCache = null; - protected ArrayList<Double> betweenClusterSeperationCache = null; + protected ArrayList<Double> withinClusterScatterCache; + protected ArrayList<Double> betweenClusterSeperationCache; protected void cacheWithinClusterScatter() { - withinClusterScatterCache = new ArrayList<Double>(); + this.withinClusterScatterCache = new ArrayList<Double>(); - for (int i = 0; i < clustersFormed; i++) { - withinClusterScatterCache.add(calculateWithinClusterScatter(i)); + for (int i = 0; i < this.clustersFormed; ++i) { + this.withinClusterScatterCache.add(calculateWithinClusterScatter(i)); } } protected abstract double calculateWithinClusterScatter(int k); protected double getWithinClusterScatter(int i) { - return withinClusterScatterCache.get(i); + return this.withinClusterScatterCache.get(i); } protected void cacheBetweenClusterSeperation() { - betweenClusterSeperationCache = new ArrayList<Double>(); + this.betweenClusterSeperationCache = new ArrayList<Double>(); - for(int i = 0; i < clustersFormed - 1; i++) { - for(int j = i + 1; j < clustersFormed; j++) { - betweenClusterSeperationCache.add(calculateBetweenClusterSeperation(i, j)); + for(int i = 0; i < clustersFormed - 1; ++i) { + for(int j = i + 1; j < clustersFormed; ++j) { + this.betweenClusterSeperationCache.add(this.calculateBetweenClusterSeperation(i, j)); } } } @@ -76,6 +76,6 @@ public abstract class ScatterSeperationRatio extends ClusteringFitnessFunction { i = j; j = tmp; } - return betweenClusterSeperationCache.get(i + (clustersFormed * j) - (((j + 1) * (j + 2)) / 2)); + return this.betweenClusterSeperationCache.get(i + (this.clustersFormed * j) - (((j + 1) * (j + 2)) / 2)); } } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/TuriIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/TuriIndex.java index e4c933d..a36eecf 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/TuriIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/TuriIndex.java @@ -44,18 +44,18 @@ public class TuriIndex extends ClusteringFitnessFunction { } @Override + public TuriIndex getClone() { + return new TuriIndex(); + } + + @Override public double calculateFitness() { // gaussian = random.getGaussian(2, 1); - return /*(c * gaussian + 1) * */(calculateAverageIntraClusterDistance() / calculateMinimumInterClusterDistance()); + return /*(c * gaussian + 1) * */(this.calculateAverageIntraClusterDistance() / this.calculateMinimumInterClusterDistance()); } // public void setC(double c) { // this.c = c; // } - - @Override - public TuriIndex getClone() { - return new TuriIndex(); - } } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/VeenmanReindersBackerIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/VeenmanReindersBackerIndex.java index 36eff1f..b11a956 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/VeenmanReindersBackerIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/va... [truncated message content] |
From: Theuns C. <the...@gm...> - 2009-06-10 06:42:38
|
1. Modified ClusteringUtils to work with SplitCooperativeAlgorithm. CooperativeEntity was also refactored to make use of the "candidate solution" property available in AbstractEntity. Previously, the CooperativeEntity had its own Vector object to represent the context. CooperativeOptimisationProblemAdapter needed the ability to return the "higher level" problem - it was implemented. 2. Removed the AbsoluteDistanceMeasure that has been deprecated a very long while ago. Implemented the HammingDistanceMeasure - like XOR. 3. Implemented a new dynamic environment response strategy that reinitialises a user-specified percentage of the least fit entities in the population. 4. Updated measurements used for clustering including a new class to print GNUplot commands to plot high dimensional (> 2) clusters and centroids. 5. Updated some JavaDoc comments. 6. Corrected MOO response strategy after rebase, because I renamed some classes in earlier pathces that have not yet been applied to master. Also corrected dynamic-vepso.xml file. --- ...gPotentialCentroidsInitialisationStrategy.java} | 17 ++- .../cilib/cooperative/CooperativeEntity.java | 61 ++++++---- .../clustering/ClusteringFitnessFunction.java | 4 +- .../clustering/PlotClustersAndCentroids.java | 4 +- .../PlotHighDimensionalClustersAndCentroids.java | 130 ++++++++++++++++++++ .../CooperativeOptimisationProblemAdapter.java | 12 ++- .../sourceforge/cilib/problem/dataset/Pattern.java | 11 +- .../pso/dynamic/ChargedVelocityUpdateStrategy.java | 20 +++- .../ArchiveReevaluationResponseStrategy.java | 5 +- .../LeastFitReinitialisationResponseStrategy.java | 54 ++++++++ .../cilib/util/ChebyshevDistanceMeasure.java | 3 +- .../sourceforge/cilib/util/ClusteringUtils.java | 12 ++- .../cilib/util/CosineDistanceMeasure.java | 4 +- ...nceMeasure.java => HammingDistanceMeasure.java} | 54 +++++---- xml/kmeans.xml | 11 +- 15 files changed, 324 insertions(+), 78 deletions(-) rename src/main/java/net/sourceforge/cilib/clustering/kmeans/{KMeansPlusPlusCentroidsInitialisationStrategy.java => ContributingPotentialCentroidsInitialisationStrategy.java} (85%) create mode 100644 src/main/java/net/sourceforge/cilib/measurement/single/clustering/PlotHighDimensionalClustersAndCentroids.java create mode 100644 src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/LeastFitReinitialisationResponseStrategy.java rename src/main/java/net/sourceforge/cilib/util/{AbsoluteDistanceMeasure.java => HammingDistanceMeasure.java} (54%) diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeansPlusPlusCentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/ContributingPotentialCentroidsInitialisationStrategy.java similarity index 85% rename from src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeansPlusPlusCentroidsInitialisationStrategy.java rename to src/main/java/net/sourceforge/cilib/clustering/kmeans/ContributingPotentialCentroidsInitialisationStrategy.java index 5ad35f8..75132a8 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeansPlusPlusCentroidsInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/ContributingPotentialCentroidsInitialisationStrategy.java @@ -29,6 +29,8 @@ import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.DistanceMeasure; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Initialises each centroid with probability proportional to its contribution to the overall potential. @@ -43,11 +45,13 @@ import net.sourceforge.cilib.util.DistanceMeasure; * * @author Theuns Cloete */ -public class KMeansPlusPlusCentroidsInitialisationStrategy implements CentroidsInitialisationStrategy { +public class ContributingPotentialCentroidsInitialisationStrategy implements CentroidsInitialisationStrategy { + private static final Logger logger = LoggerFactory.getLogger(ContributingPotentialCentroidsInitialisationStrategy.class); + private ArrayList<Pattern> patterns; private DistanceMeasure distanceMeasure; - public KMeansPlusPlusCentroidsInitialisationStrategy() { + public ContributingPotentialCentroidsInitialisationStrategy() { patterns = null; distanceMeasure = null; } @@ -56,8 +60,8 @@ public class KMeansPlusPlusCentroidsInitialisationStrategy implements CentroidsI * {@inheritDoc} */ @Override - public KMeansPlusPlusCentroidsInitialisationStrategy getClone() { - return new KMeansPlusPlusCentroidsInitialisationStrategy(); + public ContributingPotentialCentroidsInitialisationStrategy getClone() { + return new ContributingPotentialCentroidsInitialisationStrategy(); } /** @@ -79,10 +83,12 @@ public class KMeansPlusPlusCentroidsInitialisationStrategy implements CentroidsI if (i > 0) { while (randomProbability.nextDouble() >= this.calculateProbability(chosenCentroids, candidateCentroid)) { + logger.debug("Trying another candidate centroid"); candidateCentroid = patterns.get(randomPattern.nextInt(patterns.size())).data.getClone(); } } chosenCentroids.add(candidateCentroid); + logger.debug("Adding candidate centroid " + i); } return chosenCentroids; } @@ -123,6 +129,9 @@ public class KMeansPlusPlusCentroidsInitialisationStrategy implements CentroidsI } probability += denominator; } + logger.debug("numerator = " + numerator); + logger.debug("denominator = " + probability); + logger.debug("probability = " + numerator / probability); return numerator / probability; } } diff --git a/src/main/java/net/sourceforge/cilib/cooperative/CooperativeEntity.java b/src/main/java/net/sourceforge/cilib/cooperative/CooperativeEntity.java index 38723b4..faefa8d 100644 --- a/src/main/java/net/sourceforge/cilib/cooperative/CooperativeEntity.java +++ b/src/main/java/net/sourceforge/cilib/cooperative/CooperativeEntity.java @@ -23,75 +23,81 @@ package net.sourceforge.cilib.cooperative; import net.sourceforge.cilib.entity.AbstractEntity; import net.sourceforge.cilib.entity.Entity; +import net.sourceforge.cilib.problem.CooperativeOptimisationProblemAdapter; import net.sourceforge.cilib.problem.Fitness; import net.sourceforge.cilib.problem.InferiorFitness; import net.sourceforge.cilib.problem.OptimisationProblem; import net.sourceforge.cilib.type.types.Numeric; import net.sourceforge.cilib.type.types.Type; -import net.sourceforge.cilib.type.types.container.StructuredType; -import net.sourceforge.cilib.type.types.container.TypeList; import net.sourceforge.cilib.type.types.container.Vector; /** + * The cooperative entity is used in cooperative multi-population based algorithms such as the + * {@link SplitCooperativeAlgorithm} in conjunction with the {@link CooperativeOptimisationProblemAdapter}. It + * represents the context, which is a possible solution to the problem being optimised, and is usually a combination of + * smaller entities which represent the solutions to sub-problems. * * @author Theuns Cloete */ public class CooperativeEntity extends AbstractEntity { private static final long serialVersionUID = -8298684370426283216L; - protected Vector context = null; protected Fitness fitness = null; public CooperativeEntity() { - context = new Vector(); fitness = InferiorFitness.instance(); } public CooperativeEntity(CooperativeEntity rhs) { - context = rhs.context.getClone(); - fitness = rhs.fitness; + super(rhs); + fitness = rhs.fitness.getClone(); } + @Override public CooperativeEntity getClone() { return new CooperativeEntity(this); } @Override public boolean equals(Object object) { - if (this == object) + if (this == object) { return true; + } - if ((object == null) || (this.getClass() != object.getClass())) + if ((object == null) || (this.getClass() != object.getClass())) { return false; + } CooperativeEntity other = (CooperativeEntity) object; - return super.equals(other) && - (this.context.equals(other.context)) && - (this.fitness.equals(other.fitness)); + return super.equals(other) && this.fitness.equals(other.fitness); } @Override public int hashCode() { int hash = 7; hash = 31 * hash + super.hashCode(); - hash = 31 * hash + (this.context == null ? 0 : this.context.hashCode()); hash = 31 * hash + (this.fitness == null ? 0 : this.fitness.hashCode()); return hash; } public void reset() { - context.clear(); + this.getCandidateSolution().clear(); } + @Override public int compareTo(Entity o) { return getFitness().compareTo(o.getFitness()); } public void append(Type value) { - if(value instanceof Vector) + Vector context = (Vector) this.getCandidateSolution(); + + if (value instanceof Vector) { context.append((Vector) value); - else + } + else { context.append((Numeric) value); + } } public void append(Entity entity) { @@ -99,28 +105,33 @@ public class CooperativeEntity extends AbstractEntity { } public void update(Entity src, int srcPos, int dstPos, int length) { - for(int i = dstPos; i < dstPos + length; ++i) { + Vector context = (Vector) this.getCandidateSolution(); + + for (int i = dstPos; i < dstPos + length; ++i) { context.setReal(i, ((Vector) src.getCandidateSolution()).getReal(srcPos + i - dstPos)); } } - + /* public StructuredType getCandidateSolution() { - return context; + return context; } public void setCandidateSolution(Type type) { - context.clear(); - append(type); + context.clear(); + append(type); } + */ + @Override public int getDimension() { - return context.getDimension(); + return ((Vector) this.getCandidateSolution()).getDimension(); } public void setDimension(int dim) { throw new UnsupportedOperationException("The dimension of a CooperativeEntity is determined by its context"); } + @Override public Fitness getFitness() { return fitness; } @@ -129,18 +140,22 @@ public class CooperativeEntity extends AbstractEntity { fitness = f; } + @Override public void initialise(OptimisationProblem problem) { - context = (Vector) problem.getDomain().getBuiltRepresenation().getClone(); + this.setCandidateSolution(problem.getDomain().getBuiltRepresenation().getClone()); } + @Override public void reinitialise() { - throw new UnsupportedOperationException("Methd not implemented"); + ((Vector) this.getCandidateSolution()).randomize(); } + @Override public void calculateFitness() { calculateFitness(true); } + @Override public void calculateFitness(boolean count) { fitness = getFitnessCalculator().getFitness(this, count); } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java b/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java index a60d7d5..c3a1514 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java @@ -113,7 +113,8 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { return worstFitness(); } - return validateFitness(calculateFitness()); + return calculateFitness(); +// return validateFitness(calculateFitness()); } public abstract double calculateFitness(); @@ -387,6 +388,7 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { * * @param fitness the fitness value that will be validated. * @return the fitness. + * @deprecated depending on the distance measure used, a negative fitness function may be allowed */ protected double validateFitness(double fitness) { if (fitness < 0.0) { diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/clustering/PlotClustersAndCentroids.java b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/PlotClustersAndCentroids.java index 0f9a6cd..3cd6101 100644 --- a/src/main/java/net/sourceforge/cilib/measurement/single/clustering/PlotClustersAndCentroids.java +++ b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/PlotClustersAndCentroids.java @@ -80,12 +80,12 @@ public class PlotClustersAndCentroids implements Measurement { for (Pattern pattern : cluster.values()) { System.out.println(pattern); } - System.out.println('e'); + System.out.println("e"); } for (Vector centroid : arrangedCentroids) { System.out.println(centroid.toString('\0', '\0', '\t')); - System.out.println('e'); + System.out.println("e"); } return new Int(0, 0); } diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/clustering/PlotHighDimensionalClustersAndCentroids.java b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/PlotHighDimensionalClustersAndCentroids.java new file mode 100644 index 0000000..9db85cc --- /dev/null +++ b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/PlotHighDimensionalClustersAndCentroids.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2003 - 2008 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package net.sourceforge.cilib.measurement.single.clustering; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Hashtable; +import net.sourceforge.cilib.algorithm.Algorithm; +import net.sourceforge.cilib.measurement.Measurement; +import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.type.types.Int; +import net.sourceforge.cilib.type.types.Type; +import net.sourceforge.cilib.type.types.container.Vector; +import net.sourceforge.cilib.util.ClusteringUtils; + +/** + * This measurement is handy when debugging a clustering in R^n space using GNUplot. Logging should be disabled and no + * other output should be written to standard out. To try it, start GNUplot, execute:<br/> + * load "<./simulator.sh path/to/your/cilib.config.file.xml -noprogress"<br/> + * and enjoy. + * + * @author Theuns Cloete + */ +public class PlotHighDimensionalClustersAndCentroids implements Measurement { + + @Override + public Measurement getClone() { + return this; + } + + @Override + public String getDomain() { + return "Z"; + } + + @Override + public Type getValue(Algorithm algorithm) { + ClusteringUtils helper = ClusteringUtils.get(); + Vector centroids = (Vector) algorithm.getBestSolution().getPosition(); + helper.arrangeClustersAndCentroids(centroids); + + System.out.println("reset"); + System.out.println("set term jpeg medium"); + System.out.println("set style data lines"); + System.out.println("set key off"); + + + ArrayList<Hashtable<Integer, Pattern>> arrangedClusters = helper.getArrangedClusters(); + ArrayList<Vector> arrangedCentroids = helper.getArrangedCentroids(); + int iteration = Algorithm.get().getIterations(); + + this.plotCentroids(iteration, arrangedCentroids); + this.plotClustersWithCentroids(iteration, arrangedClusters, arrangedCentroids); + + return new Int(0, 0); + } + + private void plotCentroids(int iteration, ArrayList<Vector> centroids) { + System.out.println("set output \"centroids.all.iteration." + String.format("%04d", iteration) + ".jpg\""); + System.out.println("set title 'Iteration " + iteration + ": Centroids (" + centroids.size() + ")'"); + System.out.print("plot "); + + for (int i = 0; i < centroids.size(); ++i) { + System.out.print("'-' title 'centroid " + i + "'"); + if (i < centroids.size() - 1) { + System.out.print(", "); + } + } + System.out.println(); + + for (Vector centroid : centroids) { + for (int i = 0; i < centroid.size(); ++i) { + System.out.println(String.format("%d\t%f", i, centroid.getReal(i))); + } + System.out.println("e"); + } + } + + private void plotClustersWithCentroids(int iteration, ArrayList<Hashtable<Integer, Pattern>> clusters, ArrayList<Vector> centroids) { + for (int i = 0; i < clusters.size(); ++i) { + System.out.println("set output \"cluster." + String.format("%02d", i) + ".iteration."+ String.format("%04d", iteration) + ".jpg\""); + + plotClusterWithCentroid(iteration, i, clusters.get(i).values(), centroids.get(i)); + } + } + + private void plotClusterWithCentroid(int iteration, int id, Collection<Pattern> cluster, Vector centroid) { + System.out.println("set title 'Iteration " + iteration + ": Cluster " + id + " (" + cluster.size() + " patterns)'"); + System.out.print("plot "); + + for (Pattern pattern : cluster) { + System.out.print("'-' title '" + pattern.clazz + "', "); + } + + System.out.println("'-' title 'centroid' linetype 1 linewidth 5"); + + for (Pattern pattern : cluster) { + Vector vector = pattern.data; + + for (int i = 0; i < vector.size(); ++i) { + System.out.println(String.format("%d\t%f", i, vector.getReal(i))); + } + System.out.println("e"); + } + + for (int i = 0; i < centroid.size(); ++i) { + System.out.println(String.format("%d\t%f", i, centroid.getReal(i))); + } + System.out.println("e"); + } +} diff --git a/src/main/java/net/sourceforge/cilib/problem/CooperativeOptimisationProblemAdapter.java b/src/main/java/net/sourceforge/cilib/problem/CooperativeOptimisationProblemAdapter.java index 8d45549..fd22cce 100644 --- a/src/main/java/net/sourceforge/cilib/problem/CooperativeOptimisationProblemAdapter.java +++ b/src/main/java/net/sourceforge/cilib/problem/CooperativeOptimisationProblemAdapter.java @@ -59,7 +59,7 @@ public class CooperativeOptimisationProblemAdapter extends OptimisationProblemAd offset = o; domainRegistry = new StringBasedDomainRegistry(); String expandedDomain = ""; - for (int i = offset; i < offset + dimension; i++) { + for (int i = offset; i < offset + dimension; ++i) { String tmp = TypeUtil.getRepresentation(((Vector) context.getCandidateSolution()).get(i)); expandedDomain += tmp;//((Vector) context.getCandidateSolution()).get(i).getRepresentation(); if (i < offset + dimension - 1) @@ -82,6 +82,7 @@ public class CooperativeOptimisationProblemAdapter extends OptimisationProblemAd offset = copy.offset; } + @Override public CooperativeOptimisationProblemAdapter getClone() { return new CooperativeOptimisationProblemAdapter(this); } @@ -107,13 +108,18 @@ public class CooperativeOptimisationProblemAdapter extends OptimisationProblemAd return problem.getFitness(context.getCandidateSolution(), true); } + public OptimisationProblem getWrappingProblem() { + return this.problem; + } + + @Override public DomainRegistry getDomain() { return domainRegistry; } + @Override public DomainRegistry getBehaviouralDomain() { - // QUESTION What exactly does the problem.getBehaviouralDomain() method return and what is - // really needed? + // QUESTION What exactly does the problem.getBehaviouralDomain() method return and what is really needed? return domainRegistry; } } diff --git a/src/main/java/net/sourceforge/cilib/problem/dataset/Pattern.java b/src/main/java/net/sourceforge/cilib/problem/dataset/Pattern.java index a6bfa0b..bcd8cec 100644 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/Pattern.java +++ b/src/main/java/net/sourceforge/cilib/problem/dataset/Pattern.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (C) 2003 - 2008 * Computational Intelligence Research Group (CIRG@UP) * Department of Computer Science @@ -27,16 +27,17 @@ import net.sourceforge.cilib.type.types.container.Vector; public class Pattern implements Cloneable, Serializable { private static final long serialVersionUID = 3018524182531891291L; - private String clas = "<not set>"; + + public String clazz = "<not set>"; public Vector data = null; public Pattern(String c, Vector d) { - clas = c; + clazz = c; data = d; } public Pattern(Pattern rhs) { - clas = rhs.clas; + clazz = rhs.clazz; data = rhs.data; } @@ -46,6 +47,6 @@ public class Pattern implements Cloneable, Serializable { @Override public String toString() { - return data.toString('\0', '\0', '\t') + '\t' + clas; + return data.toString('\0', '\0', '\t') + '\t' + clazz; } } diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedVelocityUpdateStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedVelocityUpdateStrategy.java index 2f2346b..fd7b8c0 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedVelocityUpdateStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedVelocityUpdateStrategy.java @@ -37,10 +37,13 @@ import net.sourceforge.cilib.util.EuclideanDistanceMeasure; import net.sourceforge.cilib.util.VectorUtils; /** - * This is the velocity update mechanism that the Charged PSO makes use of. This is an - * implementation of the original Charged PSO algorithm developed by Blackwell and Bentley - * and then further improved by Blackwell and Branke. NOTE: A requirement for this velocity - * update to produce good results is that coreRadius < perceptionLimit + * This is the velocity update mechanism that the ChargedPSO makes use of. This is an implementation of the original + * charged velocity update mechanism used for the ChargedPSO algorithm developed by Blackwell and Bentley and then + * further improved by Blackwell and Branke. NOTE: A requirement for this velocity update to produce good results is + * that <code>coreRadius < perceptionLimit</code>. A user-specified {@link VelocityUpdateStrategy} can also be given + * and this class will effectively adapt it into having <i>charged</i> behaviour. The default wrapped velocity update + * strategy is the {@link StandardVelocityUpdate} which causes this velocity update strategy to adhere to the original + * ChargedPSO implementation. * * @author Anna Rakitianskaia * @author Theuns Cloete @@ -67,11 +70,20 @@ public class ChargedVelocityUpdateStrategy implements VelocityUpdateStrategy { this.distanceMeasure = rhs.distanceMeasure; } + /** + * {@inheritDoc} + */ @Override public ChargedVelocityUpdateStrategy getClone() { return new ChargedVelocityUpdateStrategy(this); } + /** + * First perform the velocity update as configured for the + * {@link #velocityUpdateStrategy wrapped velovity update strategy} and then add a charge if required. + * + * {@inheritDoc} + */ @Override public void updateVelocity(Particle particle) { // perform the standard (wrapped / decorated) velocity update diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ArchiveReevaluationResponseStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ArchiveReevaluationResponseStrategy.java index 2ae1f2b..a4dcd8e 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ArchiveReevaluationResponseStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ArchiveReevaluationResponseStrategy.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (C) 2003 - 2008 * Computational Intelligence Research Group (CIRG@UP) * Department of Computer Science @@ -19,7 +19,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - package net.sourceforge.cilib.pso.dynamic.responsestrategies; import java.util.LinkedList; @@ -45,7 +44,7 @@ public class ArchiveReevaluationResponseStrategy extends EnvironmentChangeRespon } @Override - protected void performReaction(PopulationBasedAlgorithm algorithm) { + protected void performResponse(PopulationBasedAlgorithm algorithm) { for (Entity entity : algorithm.getTopology()) { entity.getProperties().put(EntityType.Particle.BEST_FITNESS, entity.getFitnessCalculator().getFitness(entity, true)); //entity.getProperties().put(EntityType.Particle.BEST_POSITION, entity.getCandidateSolution()); diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/LeastFitReinitialisationResponseStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/LeastFitReinitialisationResponseStrategy.java new file mode 100644 index 0000000..2f26cee --- /dev/null +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/LeastFitReinitialisationResponseStrategy.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2003 - 2008 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package net.sourceforge.cilib.pso.dynamic.responsestrategies; + +import java.util.List; +import net.sourceforge.cilib.algorithm.population.PopulationBasedAlgorithm; +import net.sourceforge.cilib.container.SortedList; +import net.sourceforge.cilib.entity.Entity; +import net.sourceforge.cilib.type.types.TypeUtil; + +/** + * @author Theuns Cloete + */ +public class LeastFitReinitialisationResponseStrategy<E extends PopulationBasedAlgorithm> extends ReinitializationResponseStrategy<E> { + + /** + * Reinitialise the least fit entities in the provided list. + * + * @param entities a {@link List} of entities that should be considered for reinitialization + * @param reinitializeCount the number of least fit entities that should be reinitialized + */ + @Override + protected void reinitialize(List<? extends Entity> entities, int reinitializeCount) { + SortedList<Entity> sortedList = new SortedList<Entity>(); + sortedList.addAll(entities); + + for (int i = 0; i < reinitializeCount; ++i) { + Entity entity = sortedList.get(i); + TypeUtil.randomize(entity.getCandidateSolution()); + + entity.calculateFitness(); + } + } +} diff --git a/src/main/java/net/sourceforge/cilib/util/ChebyshevDistanceMeasure.java b/src/main/java/net/sourceforge/cilib/util/ChebyshevDistanceMeasure.java index c42edeb..ddab6d4 100644 --- a/src/main/java/net/sourceforge/cilib/util/ChebyshevDistanceMeasure.java +++ b/src/main/java/net/sourceforge/cilib/util/ChebyshevDistanceMeasure.java @@ -27,7 +27,6 @@ import java.util.Iterator; import net.sourceforge.cilib.type.types.Numeric; import net.sourceforge.cilib.type.types.Type; import net.sourceforge.cilib.type.types.container.StructuredType; -import net.sourceforge.cilib.type.types.container.Vector; /** * Chebyshev Distance is a special case of the @@ -76,6 +75,7 @@ public class ChebyshevDistanceMeasure extends MinkowskiMetric { /** * {@inheritDoc} */ + @Override public <T extends Collection<? extends Number>> double distance(T x, T y) { /* * TODO: Consider re-implementing for different sized collections, especially as everything is @@ -100,6 +100,7 @@ public class ChebyshevDistanceMeasure extends MinkowskiMetric { /** * {@inheritDoc} */ + @Override public void setAlpha(int a) { throw new IllegalArgumentException("The 'alpha' parameter of the Chebyshev Distance Measure cannot be set directly"); } diff --git a/src/main/java/net/sourceforge/cilib/util/ClusteringUtils.java b/src/main/java/net/sourceforge/cilib/util/ClusteringUtils.java index d8c2972..5ddca83 100644 --- a/src/main/java/net/sourceforge/cilib/util/ClusteringUtils.java +++ b/src/main/java/net/sourceforge/cilib/util/ClusteringUtils.java @@ -28,6 +28,8 @@ import java.util.Hashtable; import net.sourceforge.cilib.algorithm.Algorithm; import net.sourceforge.cilib.functions.clustering.ClusteringFitnessFunction; import net.sourceforge.cilib.problem.ClusteringProblem; +import net.sourceforge.cilib.problem.CooperativeOptimisationProblemAdapter; +import net.sourceforge.cilib.problem.OptimisationProblem; import net.sourceforge.cilib.problem.dataset.DataSet; import net.sourceforge.cilib.problem.dataset.DataSetBuilder; import net.sourceforge.cilib.problem.dataset.DataSetManager; @@ -87,7 +89,15 @@ public final class ClusteringUtils { if (clusteringProblem == null || dataSetBuilder == null) { try { Algorithm algorithm = Algorithm.get(); - clusteringProblem = (ClusteringProblem) algorithm.getOptimisationProblem(); + OptimisationProblem problem = algorithm.getOptimisationProblem(); + + if (problem instanceof ClusteringProblem) { + clusteringProblem = (ClusteringProblem) problem; + } + else if (problem instanceof CooperativeOptimisationProblemAdapter) { + clusteringProblem = (ClusteringProblem) (((CooperativeOptimisationProblemAdapter) problem).getWrappingProblem()); + } + dataSetBuilder = (StaticDataSetBuilder) clusteringProblem.getDataSetBuilder(); logger.info("Initialised Algorithm found: " + ClusteringUtils.class.getSimpleName() + " is now configured"); diff --git a/src/main/java/net/sourceforge/cilib/util/CosineDistanceMeasure.java b/src/main/java/net/sourceforge/cilib/util/CosineDistanceMeasure.java index 874abdc..ba399cf 100644 --- a/src/main/java/net/sourceforge/cilib/util/CosineDistanceMeasure.java +++ b/src/main/java/net/sourceforge/cilib/util/CosineDistanceMeasure.java @@ -83,7 +83,9 @@ public class CosineDistanceMeasure implements DistanceMeasure { if(norm_x <= 0.0 || norm_y <= 0.0) throw new ArithmeticException("Division by zero"); - // TODO: return x.dot(y) ??? + // TODO: the following (single line) statement returns exactly the same value + // TODO: but x and y should then be Vectors + // return 1.0 - (x.dot(y) / (x.norm() * y.norm())); ??? //convert to distance by subtracting from 1 return 1.0 - (distance / (norm_x * norm_y)); diff --git a/src/main/java/net/sourceforge/cilib/util/AbsoluteDistanceMeasure.java b/src/main/java/net/sourceforge/cilib/util/HammingDistanceMeasure.java similarity index 54% rename from src/main/java/net/sourceforge/cilib/util/AbsoluteDistanceMeasure.java rename to src/main/java/net/sourceforge/cilib/util/HammingDistanceMeasure.java index 14f3485..f0fa78e 100644 --- a/src/main/java/net/sourceforge/cilib/util/AbsoluteDistanceMeasure.java +++ b/src/main/java/net/sourceforge/cilib/util/HammingDistanceMeasure.java @@ -23,61 +23,65 @@ package net.sourceforge.cilib.util; import java.util.Collection; import java.util.Iterator; - import net.sourceforge.cilib.type.types.Numeric; import net.sourceforge.cilib.type.types.Type; import net.sourceforge.cilib.type.types.container.StructuredType; /** - * @deprecated Make use of {@link net.sourceforge.cilib.util.ManhattanDistance Manhattan Distance}. It is the correct name. - * @author Edwin Peer + * Calculates the Hamming distance between two points. As an example, the Hamming distance between the two vectors<br/> + * [1, 2, 3, 4, 5] and<br/> + * [1, 5, 3, 2, 4]<br/> + * is 3.<br/> + * In other words, it counts the number of elements that are different. + * + * @author Theuns Cloete */ -@Deprecated -public class AbsoluteDistanceMeasure implements DistanceMeasure { - +public class HammingDistanceMeasure implements DistanceMeasure { /** * {@inheritDoc} */ + @Override public <T extends Type, U extends StructuredType<T>> double distance(U x, U y) { if (x.size() != y.size()) { - throw new IllegalArgumentException("Unmatched argument lengths"); + throw new IllegalArgumentException("Cannot calculate Hamming Distance for vectors of different dimensions: " + x.size() + " != " + y.size()); } Iterator<T> xIterator = x.iterator(); Iterator<T> yIterator = y.iterator(); + int distance = 0; - double distance = 0; for (int i = 0; i < x.size(); ++i) { - Numeric xNumeric = (Numeric) xIterator.next(); - Numeric yNumeric = (Numeric) yIterator.next(); + Numeric xElement = (Numeric) xIterator.next(); + Numeric yElement = (Numeric) yIterator.next(); - distance += Math.abs(xNumeric.getReal() - yNumeric.getReal()); + if (xElement.getReal() != yElement.getReal()) { + ++distance; + } } - return distance; } /** * {@inheritDoc} */ + @Override public <T extends Collection<? extends Number>> double distance(T x, T y) { - if (x.size() != y.size()) - throw new IllegalArgumentException("Unmatched argument lengths"); - - double distance = 0; - Iterator<? extends Number> i = x.iterator(); - Iterator<? extends Number> j = y.iterator(); + if (x.size() != y.size()) { + throw new IllegalArgumentException("Cannot calculate Hamming Distance for vectors of different dimensions: " + x.size() + " != " + y.size()); + } - while (i.hasNext() && j.hasNext()) { - Number n1 = i.next(); - Number n2 = j.next(); + Iterator<? extends Number> xIterator = x.iterator(); + Iterator<? extends Number> yIterator = y.iterator(); + int distance = 0; - double tmp = Math.abs(n1.doubleValue() - n2.doubleValue()); + while (xIterator.hasNext() && yIterator.hasNext()) { + double xElement = xIterator.next().doubleValue(); + double yElement = yIterator.next().doubleValue(); - distance += tmp; + if (xElement != yElement) { + ++distance; + } } - return distance; } - } diff --git a/xml/kmeans.xml b/xml/kmeans.xml index 7421622..f0bc119 100644 --- a/xml/kmeans.xml +++ b/xml/kmeans.xml @@ -17,9 +17,9 @@ <centroidsInitialisationStrategy class="clustering.kmeans.DataSetBasedCentroidsInitialisationStrategy"/> </algorithm> - <algorithm id="kmeans.plusplus" class="clustering.kmeans.KMeans"> + <algorithm id="kmeans.potential" class="clustering.kmeans.KMeans"> <addStoppingCondition class="stoppingcondition.MaximumIterations" maximumIterations="100"/> - <centroidsInitialisationStrategy class="clustering.kmeans.KMeansPlusPlusCentroidsInitialisationStrategy"/> + <centroidsInitialisationStrategy class="clustering.kmeans.ContributingPotentialCentroidsInitialisationStrategy"/> <centroidsDiversificationStrategy class="clustering.kmeans.StandardCentroidsDiversificationStrategy" interval="1" diversifyRatio="0.1" /> </algorithm> </algorithms> @@ -37,7 +37,8 @@ <measurements id="measurements" class="simulator.MeasurementSuite" resolution="1" samples="1"> <addMeasurement class="measurement.single.Fitness" /> -<!-- <addMeasurement class="measurement.single.GenericFunctionMeasurement"> +<!-- + <addMeasurement class="measurement.single.GenericFunctionMeasurement"> <function class="functions.clustering.InterClusterDistance" /> </addMeasurement> <addMeasurement class="measurement.single.GenericFunctionMeasurement"> @@ -62,9 +63,9 @@ </simulation> <simulation> - <algorithm idref="kmeans.plusplus"/> + <algorithm idref="kmeans.potential"/> <problem idref="artificial.combined" numberOfClusters="4" /> - <measurements idref="measurements" file="measurements/kmeans.plusplus.artificial.4.txt" /> + <measurements idref="measurements" file="measurements/kmeans.potential.artificial.4.txt" /> </simulation> </simulations> </simulator> -- 1.6.0.6 |
From: Theuns C. <the...@gm...> - 2009-06-10 06:42:35
|
Unit tests failed due to these mistakes that were made: 1. Incorrectly ignored the asList() method for VonNeumannTopology. 2. Accidentally deleted CompetitiveCoevolutionParticleReevaluationResponseStrategy class. Also updated the predatorPreyCoevolution.xml file to make use of the new ChargedPSO code. This example shows how an AtomicPSO (ChargedPSO with only 50% of particles charged) is configured. --- .../pso/dynamic/ChargedVelocityUpdateStrategy.java | 26 ++++++++++++++++---- xml/predatorPreyCoevolution.xml | 23 ++++++++--------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedVelocityUpdateStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedVelocityUpdateStrategy.java index fcbae61..2f2346b 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedVelocityUpdateStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedVelocityUpdateStrategy.java @@ -48,20 +48,20 @@ import net.sourceforge.cilib.util.VectorUtils; public class ChargedVelocityUpdateStrategy implements VelocityUpdateStrategy { private static final long serialVersionUID = 365924556746583124L; - private VelocityUpdateStrategy velocityUpdateStrategy; + private VelocityUpdateStrategy wrappedVelocityUpdateStrategy; private double coreRadius; // lower limit private double perceptionLimit; // upper limit private DistanceMeasure distanceMeasure; public ChargedVelocityUpdateStrategy() { - this.velocityUpdateStrategy = new StandardVelocityUpdate(); + this.wrappedVelocityUpdateStrategy = new StandardVelocityUpdate(); this.coreRadius = 1; this.perceptionLimit = -1; // the perception limit can only be calculated once we know the domain this.distanceMeasure = new EuclideanDistanceMeasure(); } public ChargedVelocityUpdateStrategy(ChargedVelocityUpdateStrategy rhs) { - this.velocityUpdateStrategy = rhs.velocityUpdateStrategy.getClone(); + this.wrappedVelocityUpdateStrategy = rhs.wrappedVelocityUpdateStrategy.getClone(); this.perceptionLimit = rhs.perceptionLimit; this.coreRadius = rhs.coreRadius; this.distanceMeasure = rhs.distanceMeasure; @@ -75,7 +75,7 @@ public class ChargedVelocityUpdateStrategy implements VelocityUpdateStrategy { @Override public void updateVelocity(Particle particle) { // perform the standard (wrapped / decorated) velocity update - this.velocityUpdateStrategy.updateVelocity(particle); + this.wrappedVelocityUpdateStrategy.updateVelocity(particle); double particleCharge = ((Numeric) particle.getProperties().get(EntityType.Particle.CHARGE)).getReal(); // no update needed if the particle is not charged @@ -129,7 +129,7 @@ public class ChargedVelocityUpdateStrategy implements VelocityUpdateStrategy { @Override public void updateControlParameters(Particle particle) { - this.velocityUpdateStrategy.updateControlParameters(particle); + this.wrappedVelocityUpdateStrategy.updateControlParameters(particle); } /** @@ -159,4 +159,20 @@ public class ChargedVelocityUpdateStrategy implements VelocityUpdateStrategy { public void setCoreRadius(double coreRadius) { this.coreRadius = coreRadius; } + + /** + * Get the {@link VelocityUpdateStrategy} that is adapted to include a charge. + * @return the {@link VelocityUpdateStrategy} that is wrapped + */ + public VelocityUpdateStrategy getWrappedVelocityUpdateStrategy() { + return this.wrappedVelocityUpdateStrategy; + } + + /** + * Set the {@link VelocityUpdateStrategy} that should be adapted to include a charge. + * @param vus a {@link VelocityUpdateStrategy} that should be wrapped + */ + public void setWrappedVelocityUpdateStrategy(VelocityUpdateStrategy vus) { + this.wrappedVelocityUpdateStrategy = vus; + } } diff --git a/xml/predatorPreyCoevolution.xml b/xml/predatorPreyCoevolution.xml index 4df35f2..57e443f 100644 --- a/xml/predatorPreyCoevolution.xml +++ b/xml/predatorPreyCoevolution.xml @@ -43,16 +43,15 @@ </problem> <algorithms> - <algorithm id="lbest" class="pso.PSO"> - <initialisationStrategy class="algorithm.initialisation.ClonedPopulationInitialisationStrategy" entityNumber="40"> -<!-- - <entityType class="pso.dynamic.ChargedParticle"> - <velocityUpdateStrategy class="pso.dynamic.ChargedVelocityUpdateStrategy"> - <vMax class="controlparameter.ConstantControlParameter" parameter="0.8"/> - </velocityUpdateStrategy> - <chargedParticleInitialisationStrategy class="pso.dynamic.StandardChargedParticleInitialisationStrategy"/> - </entityType> ---> + <algorithm id="atomic.swarm" class="pso.PSO"> + <initialisationStrategy class="pso.dynamic.ChargedSwarmInitialisationStrategy" entityNumber="40" chargedRatio="0.5" chargeMagnitude="16"> + <entityType class="pso.particle.StandardParticle"> + <velocityUpdateStrategy class="pso.dynamic.ChargedVelocityUpdateStrategy"> + <wrappedVelocityUpdateStrategy class="pso.velocityupdatestrategies.StandardVelocityUpdate"> + <vMax class="controlparameter.ConstantControlParameter" parameter="0.8"/> + </wrappedVelocityUpdateStrategy> + </velocityUpdateStrategy> + </entityType> </initialisationStrategy> <topology class="entity.topologies.LBestTopology"> <neighbourhoodSize class = "controlparameter.ConstantControlParameter" parameter = "5"/> @@ -77,8 +76,8 @@ <simulations> <simulation> <algorithm idref="compcoevol"> - <algorithm idref="lbest"/> - <algorithm idref="lbest"/> + <algorithm idref="atomic.swarm"/> + <algorithm idref="atomic.swarm"/> </algorithm> <problem idref="PredatorPrey"/> <measurements idref="fitness" file="data/PredatorPreyCoevolutionPSO.txt"/> -- 1.6.0.6 |
From: Theuns C. <the...@gm...> - 2009-06-10 06:42:33
|
...that were not merged correctly when I did: git rebase master on my clustering branch. Signed-off-by: Theuns Cloete <the...@gm...> --- .../pso/dynamic/DynamicIterationStrategy.java | 5 +- .../EnvironmentChangeDetectionStrategy.java | 8 +- ...NeighbourhoodBestSentriesDetectionStrategy.java | 5 +- .../PeriodicDetectionStrategy.java | 4 +- .../RandomSentryPointsDetectionStrategy.java | 4 +- .../TopologyBestSentryDetectionStrategy.java | 3 +- ...lutionParticleReevaluationResponseStrategy.java | 16 ++-- ...tionStrategy.java => DualResponseStrategy.java} | 32 ++++---- .../EnvironmentChangeResponseStrategy.java | 20 ++++- ...NeighbourhoodBestSentriesResponseStrategy.java} | 24 +++--- .../PartialReinitialisationResponseStrategy.java | 13 ++-- .../ParticleReevaluationResponseStrategy.java | 87 -------------------- ...tegy.java => ReevaluationResponseStrategy.java} | 16 ++-- ....java => ReinitializationResponseStrategy.java} | 16 ++-- 14 files changed, 84 insertions(+), 169 deletions(-) rename src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/{DualReactionStrategy.java => DualResponseStrategy.java} (86%) rename src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/{NeighbourhoodBestSentriesReactionStrategy.java => NeighbourhoodBestSentriesResponseStrategy.java} (71%) delete mode 100644 src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ParticleReevaluationResponseStrategy.java rename src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/{ReevaluationReactionStrategy.java => ReevaluationResponseStrategy.java} (92%) rename src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/{ReinitializationReactionStrategy.java => ReinitializationResponseStrategy.java} (91%) diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/DynamicIterationStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/DynamicIterationStrategy.java index 0189bd2..a737305 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/DynamicIterationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/DynamicIterationStrategy.java @@ -26,7 +26,7 @@ import net.sourceforge.cilib.algorithm.population.PopulationBasedAlgorithm; import net.sourceforge.cilib.pso.dynamic.detectionstrategies.EnvironmentChangeDetectionStrategy; import net.sourceforge.cilib.pso.dynamic.detectionstrategies.RandomSentryEntitiesDetectionStrategy; import net.sourceforge.cilib.pso.dynamic.responsestrategies.EnvironmentChangeResponseStrategy; -import net.sourceforge.cilib.pso.dynamic.responsestrategies.PartialReinitialisationResponseStrategy; +import net.sourceforge.cilib.pso.dynamic.responsestrategies.ReinitializationResponseStrategy; /** * The dynamic iteration strategy allows {@link PopulationBasedAlgorithm population based algorithms} to detect and @@ -49,9 +49,10 @@ public class DynamicIterationStrategy<E extends PopulationBasedAlgorithm> implem * Create a new instance of {@linkplain DynamicIterationStrategy}. */ public DynamicIterationStrategy() { +// TODO: SynchronousIterationStrategy is only applicable to PSO // this.iterationStrategy = new SynchronousIterationStrategy(); this.detectionStrategy = new RandomSentryEntitiesDetectionStrategy<E>(); - this.responseStrategy = new PartialReinitialisationResponseStrategy<E>(); + this.responseStrategy = new ReinitializationResponseStrategy<E>(); } /** diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/EnvironmentChangeDetectionStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/EnvironmentChangeDetectionStrategy.java index 7382987..820a7ef 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/EnvironmentChangeDetectionStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/EnvironmentChangeDetectionStrategy.java @@ -22,6 +22,8 @@ package net.sourceforge.cilib.pso.dynamic.detectionstrategies; import java.io.Serializable; + +import net.sourceforge.cilib.algorithm.Algorithm; import net.sourceforge.cilib.algorithm.population.PopulationBasedAlgorithm; import net.sourceforge.cilib.pso.dynamic.DynamicIterationStrategy; import net.sourceforge.cilib.util.Cloneable; @@ -29,7 +31,7 @@ import net.sourceforge.cilib.util.Cloneable; /** * This abstract class defines the interface that detection strategies have to adhere to. * Detection strategies are used within the scope of a {@link DynamicIterationStrategy} to - * detect whether the environment has change during the course of an + * detect whether the environment has changed during the course of an * {@link Algorithm algorithm's} execution. * @author Anna Rakatianskaia * @author Gary Pampara @@ -57,8 +59,8 @@ public abstract class EnvironmentChangeDetectionStrategy<E extends PopulationBas public abstract EnvironmentChangeDetectionStrategy<E> getClone(); /** - * Check the environment in which the specified PSO algorithm is running for changes. - * @param algorithm The <tt>PSO</tt> that runs in a dynamic environment. + * Check the environment in which the specified algorithm is running for changes. + * @param algorithm The {@link PopulationBasedAlgorithm} that runs in a dynamic environment. * @return true if any changes are detected, false otherwise */ public abstract boolean detect(E algorithm); diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/NeighbourhoodBestSentriesDetectionStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/NeighbourhoodBestSentriesDetectionStrategy.java index 85241eb..07613fb 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/NeighbourhoodBestSentriesDetectionStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/NeighbourhoodBestSentriesDetectionStrategy.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (C) 2003 - 2008 * Computational Intelligence Research Group (CIRG@UP) * Department of Computer Science @@ -19,10 +19,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - package net.sourceforge.cilib.pso.dynamic.detectionstrategies; - import java.util.Set; import net.sourceforge.cilib.algorithm.population.PopulationBasedAlgorithm; @@ -33,7 +31,6 @@ public class NeighbourhoodBestSentriesDetectionStrategy<E extends PopulationBase private static final long serialVersionUID = 3598067152913033487L; public NeighbourhoodBestSentriesDetectionStrategy() { - // super() is automatically called } public NeighbourhoodBestSentriesDetectionStrategy(NeighbourhoodBestSentriesDetectionStrategy<E> rhs) { diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/PeriodicDetectionStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/PeriodicDetectionStrategy.java index 6e34aec..f25a2ad 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/PeriodicDetectionStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/PeriodicDetectionStrategy.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (C) 2003 - 2008 * Computational Intelligence Research Group (CIRG@UP) * Department of Computer Science @@ -19,7 +19,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - package net.sourceforge.cilib.pso.dynamic.detectionstrategies; import net.sourceforge.cilib.algorithm.population.PopulationBasedAlgorithm; @@ -28,7 +27,6 @@ public class PeriodicDetectionStrategy<E extends PopulationBasedAlgorithm> exten private static final long serialVersionUID = 4079212153655661164L; public PeriodicDetectionStrategy() { - // super() is automatically called } public PeriodicDetectionStrategy(EnvironmentChangeDetectionStrategy<E> rhs) { diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryPointsDetectionStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryPointsDetectionStrategy.java index 92a1bb8..081eba6 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryPointsDetectionStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryPointsDetectionStrategy.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (C) 2003 - 2008 * Computational Intelligence Research Group (CIRG@UP) * Department of Computer Science @@ -19,7 +19,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - package net.sourceforge.cilib.pso.dynamic.detectionstrategies; import java.util.ArrayList; @@ -47,7 +46,6 @@ public class RandomSentryPointsDetectionStrategy<E extends PopulationBasedAlgori protected ArrayList<Entity> sentries = null; public RandomSentryPointsDetectionStrategy() { - // super() is automatically called int size = Double.valueOf(numberOfSentries.getParameter()).intValue(); sentries = new ArrayList<Entity>(size); } diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/TopologyBestSentryDetectionStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/TopologyBestSentryDetectionStrategy.java index 16a7e2d..bd579d9 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/TopologyBestSentryDetectionStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/TopologyBestSentryDetectionStrategy.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (C) 2003 - 2008 * Computational Intelligence Research Group (CIRG@UP) * Department of Computer Science @@ -37,7 +37,6 @@ public class TopologyBestSentryDetectionStrategy<E extends PopulationBasedAlgori private static final long serialVersionUID = 7060690546029355964L; public TopologyBestSentryDetectionStrategy() { - // super() is automatically called } public TopologyBestSentryDetectionStrategy(EnvironmentChangeDetectionStrategy<E> rhs) { diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/CompetitiveCoevolutionParticleReevaluationResponseStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/CompetitiveCoevolutionParticleReevaluationResponseStrategy.java index 10b6809..ff1949a 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/CompetitiveCoevolutionParticleReevaluationResponseStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/CompetitiveCoevolutionParticleReevaluationResponseStrategy.java @@ -33,9 +33,9 @@ import net.sourceforge.cilib.type.types.Int; import net.sourceforge.cilib.type.types.Type; /** - * This class re-calculates all the personal best positions in the population. It will only work for PSO algorithms. - * @author leo + * This class re-calculates all the personal best positions in the population. It will only work for PSO algorithms. * + * @author Leo Langenhoven */ public class CompetitiveCoevolutionParticleReevaluationResponseStrategy<E extends PopulationBasedAlgorithm> extends EnvironmentChangeResponseStrategy<E> { @@ -43,7 +43,7 @@ public class CompetitiveCoevolutionParticleReevaluationResponseStrategy<E extend public CompetitiveCoevolutionParticleReevaluationResponseStrategy() { } - + public CompetitiveCoevolutionParticleReevaluationResponseStrategy(CompetitiveCoevolutionParticleReevaluationResponseStrategy<E> other) { } @@ -51,6 +51,7 @@ public class CompetitiveCoevolutionParticleReevaluationResponseStrategy<E extend /** * {@inheritDoc} */ + @Override public CompetitiveCoevolutionParticleReevaluationResponseStrategy<E> getClone() { return new CompetitiveCoevolutionParticleReevaluationResponseStrategy<E>(this); } @@ -58,8 +59,9 @@ public class CompetitiveCoevolutionParticleReevaluationResponseStrategy<E extend /** * {@inheritDoc} */ - public void performReaction(PopulationBasedAlgorithm algorithm) { - //select new competitors and re-evaluate PBest vector of Particle + @Override + public void performResponse(PopulationBasedAlgorithm algorithm) { + //select new competitors and re-evaluate PBest vector of Particle PopulationBasedAlgorithm currentAlgorithm = (PopulationBasedAlgorithm)Algorithm.get(); //the current sub population algorithm int populationID = -1; for(Entity e: currentAlgorithm.getTopology().asList()) { @@ -69,11 +71,11 @@ public class CompetitiveCoevolutionParticleReevaluationResponseStrategy<E extend populationID = ((Int)e.getProperties().get(EntityType.Coevolution.POPULATION_ID)).getInt(); Blackboard<Enum<?>, Type> blackboard = new Blackboard<Enum<?>, Type>(); blackboard.put(EntityType.CANDIDATE_SOLUTION, ((AbstractParticle)e).getBestPosition()); - blackboard.put(EntityType.Coevolution.BOARD, new EntityScoreboard()); + blackboard.put(EntityType.Coevolution.BOARD, new EntityScoreboard()); Fitness val = currentAlgorithm.getOptimisationProblem().getFitness(blackboard, false); e.getProperties().put(EntityType.Particle.BEST_FITNESS, val); //if currentV is better than re-evaluated pBest, then replace it - if (e.getFitness().compareTo(e.getBestFitness()) > 0) { + if (e.getFitness().compareTo(e.getBestFitness()) > 0) { e.getProperties().put(EntityType.Particle.BEST_FITNESS, e.getFitness()); e.getProperties().put(EntityType.Particle.BEST_POSITION, e.getProperties().get(EntityType.CANDIDATE_SOLUTION).getClone()); } diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/DualReactionStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/DualResponseStrategy.java similarity index 86% rename from src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/DualReactionStrategy.java rename to src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/DualResponseStrategy.java index f367dac..146d51c 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/DualReactionStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/DualResponseStrategy.java @@ -30,7 +30,7 @@ import net.sourceforge.cilib.math.random.generator.Random; /** * This {@link EnvironmentChangeResponseStrategy reaction strategy} wraps both a - * {@link ReinitializationReactionStrategy} and a {@link ReevaluationReactionStrategy}. It + * {@link ReinitializationResponseStrategy} and a {@link ReevaluationResponseStrategy}. It * firstly performs the specified * {@link #setReinitializationRatio(double) number of reinitializations} on randomly chosen * entities in the {@link Topology}. Then it performs the specified @@ -40,20 +40,20 @@ import net.sourceforge.cilib.math.random.generator.Random; * @author Theuns Cloete * @param <E> some {@link PopulationBasedAlgorithm population based algorithm} */ -public class DualReactionStrategy<E extends PopulationBasedAlgorithm> extends EnvironmentChangeResponseStrategy<E> { +public class DualResponseStrategy<E extends PopulationBasedAlgorithm> extends EnvironmentChangeResponseStrategy<E> { private static final long serialVersionUID = -1944318436718779296L; - protected ReevaluationReactionStrategy<E> reevaluation = null; - protected ReinitializationReactionStrategy<E> reinitialization = null; + + protected ReevaluationResponseStrategy<E> reevaluation = null; + protected ReinitializationResponseStrategy<E> reinitialization = null; protected Random randomGenerator = null; - public DualReactionStrategy() { - // calls super() automatically - reevaluation = new ReevaluationReactionStrategy<E>(); - reinitialization = new ReinitializationReactionStrategy<E>(); + public DualResponseStrategy() { + reevaluation = new ReevaluationResponseStrategy<E>(); + reinitialization = new ReinitializationResponseStrategy<E>(); this.setRandomGenerator(new MersenneTwister()); } - public DualReactionStrategy(DualReactionStrategy<E> rhs) { + public DualResponseStrategy(DualResponseStrategy<E> rhs) { super(rhs); reevaluation = rhs.reevaluation.getClone(); reinitialization = rhs.reinitialization.getClone(); @@ -61,8 +61,8 @@ public class DualReactionStrategy<E extends PopulationBasedAlgorithm> extends En } @Override - public DualReactionStrategy<E> getClone() { - return new DualReactionStrategy<E>(this); + public DualResponseStrategy<E> getClone() { + return new DualResponseStrategy<E>(this); } /** @@ -72,7 +72,7 @@ public class DualReactionStrategy<E extends PopulationBasedAlgorithm> extends En * {@inheritDoc} */ @Override - public void performReaction(E algorithm) { + public void performResponse(E algorithm) { List<? extends Entity> entities = algorithm.getTopology().asList(); int reinitializeCount = (int) Math.floor(reinitialization.getReinitializationRatio() * entities.size()); int reevaluateCount = (int) Math.floor(reevaluation.getReevaluationRatio() * entities.size()); @@ -99,7 +99,7 @@ public class DualReactionStrategy<E extends PopulationBasedAlgorithm> extends En /** * Set the ratio of entities that should be reinitialized. This is defered to the wrapped - * {@link ReinitializationReactionStrategy}. + * {@link ReinitializationResponseStrategy}. * * @param rr a double value in the range <code>(0.0, 1.0)</code> */ @@ -110,7 +110,7 @@ public class DualReactionStrategy<E extends PopulationBasedAlgorithm> extends En /** * Get the ratio of entities that should be reinitialized. This is defered to the wrapped - * {@link ReinitializationReactionStrategy}. + * {@link ReinitializationResponseStrategy}. * * @return the ratio of entities that should be reinitialized */ @@ -120,7 +120,7 @@ public class DualReactionStrategy<E extends PopulationBasedAlgorithm> extends En /** * Set the ratio of entities that should be reevaluated. This is defered to the wrapped - * {@link ReevaluationReactionStrategy}. + * {@link ReevaluationResponseStrategy}. * * @param rer a double value in the range <code>(0.0, 1.0)</code> */ @@ -131,7 +131,7 @@ public class DualReactionStrategy<E extends PopulationBasedAlgorithm> extends En /** * Get the ratio of entities that should be reevaluated. This is defered to the wrapped - * {@link ReevaluationReactionStrategy}. + * {@link ReevaluationResponseStrategy}. * * @return the ratio of entities that should be reevaluated */ diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/EnvironmentChangeResponseStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/EnvironmentChangeResponseStrategy.java index 68dc940..2574766 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/EnvironmentChangeResponseStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/EnvironmentChangeResponseStrategy.java @@ -31,7 +31,13 @@ import net.sourceforge.cilib.entity.Topology; import net.sourceforge.cilib.util.Cloneable; /** - * TODO: Complete this Javadoc. + * Abstract class that is responsible for responding to environment changes. Sub-classes should provide an + * implementation for the {@link #performResponse(net.sourceforge.cilib.algorithm.population.PopulationBasedAlgorithm)} + * method. + * + * @author Anna Rakatianskaia + * @author Gary Pampara + * @author Theuns Cloete */ public abstract class EnvironmentChangeResponseStrategy<E extends PopulationBasedAlgorithm> implements Cloneable, Serializable { protected boolean hasMemory = true; @@ -49,28 +55,32 @@ public abstract class EnvironmentChangeResponseStrategy<E extends PopulationBase * * @return A cloned <tt>EnvironmentChangeResponseStrategy</tt> */ + @Override public abstract EnvironmentChangeResponseStrategy<E> getClone(); /** * Respond to the environment change and ensure that the neighbourhood best entities are * updated. This method (Template Method) calls two other methods in turn: * <ul> - * <li>{@link #performReaction(PopulationBasedAlgorithm)}</li> + * <li>{@link #performResponse(PopulationBasedAlgorithm)}</li> * <li>{@link #updateNeighbourhoodBestEntities(Topology)}</li> * </ul> * * @param algorithm some {@link PopulationBasedAlgorithm population based algorithm} */ public void respond(E algorithm) { - performReaction(algorithm); - if(hasMemory) updateNeighbourhoodBestEntities(algorithm.getTopology()); + performResponse(algorithm); + + if (hasMemory) { + updateNeighbourhoodBestEntities(algorithm.getTopology()); + } } /** * This is the method responsible for responding that should be overridden by sub-classes. * @param algorithm */ - protected abstract void performReaction(E algorithm); + protected abstract void performResponse(E algorithm); /** * TODO: The problem with this is that it is PSO specific. It uses {@link Particle particles} diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/NeighbourhoodBestSentriesReactionStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/NeighbourhoodBestSentriesResponseStrategy.java similarity index 71% rename from src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/NeighbourhoodBestSentriesReactionStrategy.java rename to src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/NeighbourhoodBestSentriesResponseStrategy.java index 2c7d2b0..da73dfa 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/NeighbourhoodBestSentriesReactionStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/NeighbourhoodBestSentriesResponseStrategy.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (C) 2003 - 2008 * Computational Intelligence Research Group (CIRG@UP) * Department of Computer Science @@ -19,7 +19,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - package net.sourceforge.cilib.pso.dynamic.responsestrategies; import net.sourceforge.cilib.algorithm.population.PopulationBasedAlgorithm; @@ -27,27 +26,28 @@ import net.sourceforge.cilib.entity.Entity; import net.sourceforge.cilib.entity.Topologies; import net.sourceforge.cilib.type.types.TypeUtil; -public class NeighbourhoodBestSentriesReactionStrategy<E extends PopulationBasedAlgorithm> extends EnvironmentChangeResponseStrategy<E> { +public class NeighbourhoodBestSentriesResponseStrategy<E extends PopulationBasedAlgorithm> extends EnvironmentChangeResponseStrategy<E> { private static final long serialVersionUID = -2142727048293776335L; - public NeighbourhoodBestSentriesReactionStrategy() { - // super() is called automatically + public NeighbourhoodBestSentriesResponseStrategy() { } - public NeighbourhoodBestSentriesReactionStrategy(NeighbourhoodBestSentriesReactionStrategy<E> rhs) { + public NeighbourhoodBestSentriesResponseStrategy(NeighbourhoodBestSentriesResponseStrategy<E> rhs) { super(rhs); } @Override - public NeighbourhoodBestSentriesReactionStrategy<E> getClone() { - return new NeighbourhoodBestSentriesReactionStrategy<E>(this); + public NeighbourhoodBestSentriesResponseStrategy<E> getClone() { + return new NeighbourhoodBestSentriesResponseStrategy<E>(this); } @Override - public void performReaction(PopulationBasedAlgorithm algorithm) { - for (Entity entity : Topologies.getNeighbourhoodBestEntities(algorithm.getTopology())) + public void performResponse(PopulationBasedAlgorithm algorithm) { + for (Entity entity : Topologies.getNeighbourhoodBestEntities(algorithm.getTopology())) { TypeUtil.randomize(entity.getCandidateSolution()); - // TODO: What is the influence of reevaluation? -// entity.calculateFitness(false); + } + +// TODO: What is the influence of reevaluation? +// entity.calculateFitness(false); } } diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/PartialReinitialisationResponseStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/PartialReinitialisationResponseStrategy.java index 5411ccd..614da8b 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/PartialReinitialisationResponseStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/PartialReinitialisationResponseStrategy.java @@ -33,14 +33,13 @@ import net.sourceforge.cilib.type.types.TypeUtil; /** * @author Anna Rakitianskaia */ -public class PartialReinitialisationResponseStrategy<E extends PopulationBasedAlgorithm> extends ParticleReevaluationResponseStrategy<E> { +public class PartialReinitialisationResponseStrategy<E extends PopulationBasedAlgorithm> extends ReevaluationResponseStrategy<E> { private static final long serialVersionUID = 4619744183683905269L; private double reinitialisationRatio; private Random randomiser; public PartialReinitialisationResponseStrategy() { - super(); reinitialisationRatio = 0.5; randomiser = new MersenneTwister(); } @@ -56,12 +55,12 @@ public class PartialReinitialisationResponseStrategy<E extends PopulationBasedAl } /** - * Respond to environment change by re-evaluating each particle's position, personal best and neighbourhood best, - * and reinitialising the positions of a specified percentage of particles. - * @param algorithm PSO algorithm that has to respond to environment change + * Respond to environment change by re-evaluating each entity and reinitialising a specified percentage of the + * entities. + * @param algorithm the {@link PopulationBasedAlgorithm} that has to respond to environment change */ @Override - public void performReaction(E algorithm) { + public void performResponse(E algorithm) { // Reset positions: Topology<? extends Entity> topology = algorithm.getTopology(); int populationSize = algorithm.getPopulationSize(); @@ -84,7 +83,7 @@ public class PartialReinitialisationResponseStrategy<E extends PopulationBasedAl } } // Re-evaluate: - super.performReaction(algorithm); // super class method + super.performResponse(algorithm); // super class method } /** diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ParticleReevaluationResponseStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ParticleReevaluationResponseStrategy.java deleted file mode 100644 index 71da50a..0000000 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ParticleReevaluationResponseStrategy.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2003 - 2008 - * Computational Intelligence Research Group (CIRG@UP) - * Department of Computer Science - * University of Pretoria - * South Africa - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package net.sourceforge.cilib.pso.dynamic.responsestrategies; - -import java.util.Iterator; - -import net.sourceforge.cilib.algorithm.population.PopulationBasedAlgorithm; -import net.sourceforge.cilib.entity.Entity; -import net.sourceforge.cilib.entity.Particle; -import net.sourceforge.cilib.entity.Topology; -import net.sourceforge.cilib.pso.dynamic.DynamicParticle; - -/** - * @author Anna Rakitianskaia - * @deprecated Rather use {@link ReevaluationReactionStrategy} - */ -public class ParticleReevaluationResponseStrategy<E extends PopulationBasedAlgorithm> extends EnvironmentChangeResponseStrategy<E> { - private static final long serialVersionUID = -4389695103800841288L; - - public ParticleReevaluationResponseStrategy() { - // empty constructor - } - - public ParticleReevaluationResponseStrategy(ParticleReevaluationResponseStrategy<E> copy) { - // empty copy constructor - } - - public ParticleReevaluationResponseStrategy<E> getClone() { - return new ParticleReevaluationResponseStrategy<E>(this); - } - - /** - * Respond to environment change by re-evaluating each particle's position, personal best and neighbourhood best. - * @param algorithm PSO algorithm that has to respond to environment change - */ - public void respond(E algorithm) { - performReaction(algorithm); - } - - /** - * Re-evaluate each particle's position, personal best and neighbourhood best. - * @param algorithm PSO algorithm that has to respond to environment change - */ - protected void performReaction(E algorithm) { - - Topology<? extends Entity> topology = algorithm.getTopology(); - - // Reevaluate current position. Update personal best (done by reevaluate()). - Iterator<? extends Entity> iterator = topology.iterator(); - while (iterator.hasNext()) { - DynamicParticle current = (DynamicParticle) iterator.next(); - current.reevaluate(); - } - - // Update the neighbourhood best - iterator = topology.iterator(); - while (iterator.hasNext()) { - Particle current = (Particle) iterator.next(); - Iterator<? extends Entity> j = topology.neighbourhood(iterator); - while (j.hasNext()) { - Particle other = (Particle) j.next(); - if (current.getSocialBestFitness().compareTo(other.getNeighbourhoodBest().getSocialBestFitness()) > 0) { - other.setNeighbourhoodBest(current); - } - } // end for - } // end for - } -} // end class diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ReevaluationReactionStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ReevaluationResponseStrategy.java similarity index 92% rename from src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ReevaluationReactionStrategy.java rename to src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ReevaluationResponseStrategy.java index 89fb156..7b8c4a2 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ReevaluationReactionStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ReevaluationResponseStrategy.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (C) 2003 - 2008 * Computational Intelligence Research Group (CIRG@UP) * Department of Computer Science @@ -19,7 +19,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - package net.sourceforge.cilib.pso.dynamic.responsestrategies; import java.util.List; @@ -40,27 +39,26 @@ import net.sourceforge.cilib.pso.particle.StandardParticle; * @author Theuns Cloete * @param <E> some {@link PopulationBasedAlgorithm population based algorithm} */ -public class ReevaluationReactionStrategy<E extends PopulationBasedAlgorithm> extends EnvironmentChangeResponseStrategy<E> { +public class ReevaluationResponseStrategy<E extends PopulationBasedAlgorithm> extends EnvironmentChangeResponseStrategy<E> { private static final long serialVersionUID = -5549918743502730714L; protected double reevaluationRatio = 0.0; protected Random randomGenerator = null; - public ReevaluationReactionStrategy() { - // super() called automatically + public ReevaluationResponseStrategy() { reevaluationRatio = 0.1; randomGenerator = new MersenneTwister(); } - public ReevaluationReactionStrategy(ReevaluationReactionStrategy<E> rhs) { + public ReevaluationResponseStrategy(ReevaluationResponseStrategy<E> rhs) { super(rhs); reevaluationRatio = rhs.reevaluationRatio; randomGenerator = rhs.randomGenerator.getClone(); } @Override - public ReevaluationReactionStrategy<E> getClone() { - return new ReevaluationReactionStrategy<E>(this); + public ReevaluationResponseStrategy<E> getClone() { + return new ReevaluationResponseStrategy<E>(this); } /** @@ -72,7 +70,7 @@ public class ReevaluationReactionStrategy<E extends PopulationBasedAlgorithm> ex * {@inheritDoc} */ @Override - public void performReaction(E algorithm) { + public void performResponse(E algorithm) { List<? extends Entity> entities = algorithm.getTopology().asList(); int reevaluateCount = (int) Math.floor(reevaluationRatio * entities.size()); diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ReinitializationReactionStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ReinitializationResponseStrategy.java similarity index 91% rename from src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ReinitializationReactionStrategy.java rename to src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ReinitializationResponseStrategy.java index 66e07be..7b0f5ac 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ReinitializationReactionStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/responsestrategies/ReinitializationResponseStrategy.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (C) 2003 - 2008 * Computational Intelligence Research Group (CIRG@UP) * Department of Computer Science @@ -19,7 +19,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - package net.sourceforge.cilib.pso.dynamic.responsestrategies; import java.util.List; @@ -39,27 +38,26 @@ import net.sourceforge.cilib.type.types.TypeUtil; * @author Theuns Cloete * @param <E> some {@link PopulationBasedAlgorithm population based algorithm} */ -public class ReinitializationReactionStrategy<E extends PopulationBasedAlgorithm> extends EnvironmentChangeResponseStrategy<E> { +public class ReinitializationResponseStrategy<E extends PopulationBasedAlgorithm> extends EnvironmentChangeResponseStrategy<E> { private static final long serialVersionUID = -7283513652737895281L; protected double reinitializationRatio = 0.0; protected Random randomGenerator = null; - public ReinitializationReactionStrategy() { - // super() is automatically called + public ReinitializationResponseStrategy() { reinitializationRatio = 0.1; randomGenerator = new MersenneTwister(); } - public ReinitializationReactionStrategy(ReinitializationReactionStrategy<E> rhs) { + public ReinitializationResponseStrategy(ReinitializationResponseStrategy<E> rhs) { super(rhs); reinitializationRatio = rhs.reinitializationRatio; randomGenerator = rhs.randomGenerator.getClone(); } @Override - public ReinitializationReactionStrategy<E> getClone() { - return new ReinitializationReactionStrategy<E>(this); + public ReinitializationResponseStrategy<E> getClone() { + return new ReinitializationResponseStrategy<E>(this); } /** @@ -68,7 +66,7 @@ public class ReinitializationReactionStrategy<E extends PopulationBasedAlgorithm * {@inheritDoc} */ @Override - public void performReaction(E algorithm) { + public void performResponse(E algorithm) { List<? extends Entity> entities = algorithm.getTopology().asList(); int reinitializeCount = (int) Math.floor(reinitializationRatio * entities.size()); -- 1.6.0.6 |
From: Theuns C. <the...@gm...> - 2009-06-10 06:42:31
|
... to be able to get a "variance vector" as well as a "standard deviation" vector. The unit tests have also been updated. Also created the measurements.single.clustering package and implemented some measurements that make use of the above statistics methods. Some measurements were moved to the new package. Updated the xml files accordingly. --- .../java/net/sourceforge/cilib/math/StatUtils.java | 45 +++++++++++-- .../single/GenericFunctionMeasurement.java | 7 ++- .../single/clustering/ClusterCentroids.java | 55 ++++++++++++++++ .../ClusterMeans.java} | 40 +++++------- .../ClusterStandardDeviations.java} | 41 +++++------- .../single/clustering/ClusterVariances.java | 62 ++++++++++++++++++ .../single/clustering/DataSetDiameter.java | 69 ++++++++++++++++++++ .../{ => clustering}/NumberOfClustersFormed.java | 6 +- .../{ => clustering}/PlotClustersAndCentroids.java | 6 +- .../single/clustering/SearchSpaceDiameter.java | 61 +++++++++++++++++ .../net/sourceforge/cilib/math/StatUtilsTest.java | 29 ++++++++- xml/clustering-gbest-pso.xml | 2 +- xml/clustering.dynamic.circles.xml | 2 +- xml/kmeans.xml | 4 +- 14 files changed, 363 insertions(+), 66 deletions(-) create mode 100644 src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterCentroids.java copy src/main/java/net/sourceforge/cilib/measurement/single/{NumberOfClustersFormed.java => clustering/ClusterMeans.java} (50%) copy src/main/java/net/sourceforge/cilib/measurement/single/{NumberOfClustersFormed.java => clustering/ClusterStandardDeviations.java} (50%) create mode 100644 src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterVariances.java create mode 100644 src/main/java/net/sourceforge/cilib/measurement/single/clustering/DataSetDiameter.java rename src/main/java/net/sourceforge/cilib/measurement/single/{ => clustering}/NumberOfClustersFormed.java (96%) rename src/main/java/net/sourceforge/cilib/measurement/single/{ => clustering}/PlotClustersAndCentroids.java (95%) create mode 100644 src/main/java/net/sourceforge/cilib/measurement/single/clustering/SearchSpaceDiameter.java diff --git a/src/main/java/net/sourceforge/cilib/math/StatUtils.java b/src/main/java/net/sourceforge/cilib/math/StatUtils.java index 6cc73d4..1dce793 100644 --- a/src/main/java/net/sourceforge/cilib/math/StatUtils.java +++ b/src/main/java/net/sourceforge/cilib/math/StatUtils.java @@ -21,6 +21,7 @@ */ package net.sourceforge.cilib.math; +import java.util.ArrayList; import java.util.Collection; import net.sourceforge.cilib.problem.dataset.Pattern; @@ -59,8 +60,9 @@ public final class StatUtils { * @return a {@link Vector} that represents the mean/center of the given set */ public static Vector meanVector(Collection<Pattern> set) { - if (set.isEmpty()) + if (set.isEmpty()) { throw new IllegalArgumentException("Cannot calculate the mean for an empty set"); + } Vector mean = null; @@ -97,25 +99,41 @@ public final class StatUtils { * @return a double representing the variance of the given set with the given center */ public static double variance(Collection<Pattern> set, Vector center) { - if (set.isEmpty()) + return varianceVector(set, center).norm(); + } + + /** + * Calculates the variance vector of the given set/cluster/collection of @{link Pattern}s. + * + * @param set a set ({@link ArrayList}) of {@link Pattern}s + * @param center a {@link Vector} that represents the mean/center of the accompanied set + * @return a {@link Vector} representing the variance vector of the given set with the given center. When the norm + * of this vector is taken, you will get the actual variance scalar of the given set with given center. + */ + public static Vector varianceVector(Collection<Pattern> set, Vector center) { + if (set.isEmpty()) { throw new IllegalArgumentException("Cannot calculate the variance for an empty set"); + } Vector variance = center.getClone(); variance.reset(); // initialize the variance to be all zeroes for (Pattern pattern : set) { Vector diffSquare = pattern.data.subtract(center); - for (Numeric numeric : diffSquare) - numeric.setReal(numeric.getReal()*numeric.getReal()); + + for (Numeric numeric : diffSquare) { + numeric.setReal(numeric.getReal() * numeric.getReal()); + } variance = variance.plus(diffSquare); } - return variance.norm() / set.size(); + return variance.divide(set.size()); } private static double[] unwrap(Vector vector) { double[] unwrapped = new double[vector.getDimension()]; - for (int i = 0; i < vector.getDimension(); i++) + for (int i = 0; i < vector.getDimension(); i++) { unwrapped[i] = vector.getReal(i); + } return unwrapped; } @@ -129,4 +147,19 @@ public final class StatUtils { return Math.sqrt(variance(vector)); } + public static double stdDeviation(Collection<Pattern> set, Vector center) { + return Math.sqrt(variance(set, center)); + } + + public static Vector stdDeviationVector(Collection<Pattern> set, Vector center) { + Vector stdDev = varianceVector(set, center); + + for (int i = 0; i < stdDev.size(); ++i) { + Numeric numeric = stdDev.get(i); + double sqrt = Math.sqrt(numeric.getReal()); + + numeric.set(sqrt); + } + return stdDev; + } } diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/GenericFunctionMeasurement.java b/src/main/java/net/sourceforge/cilib/measurement/single/GenericFunctionMeasurement.java index 43aae19..a87eead 100644 --- a/src/main/java/net/sourceforge/cilib/measurement/single/GenericFunctionMeasurement.java +++ b/src/main/java/net/sourceforge/cilib/measurement/single/GenericFunctionMeasurement.java @@ -34,6 +34,7 @@ import net.sourceforge.cilib.type.types.container.Vector; */ public class GenericFunctionMeasurement implements Measurement { private static final long serialVersionUID = 3301062975775598397L; + private Function function = null; /** @@ -54,6 +55,7 @@ public class GenericFunctionMeasurement implements Measurement { /** * {@inheritDoc} */ + @Override public GenericFunctionMeasurement getClone() { return new GenericFunctionMeasurement(this); } @@ -61,6 +63,7 @@ public class GenericFunctionMeasurement implements Measurement { /** * {@inheritDoc} */ + @Override public String getDomain() { return "R"; } @@ -68,9 +71,11 @@ public class GenericFunctionMeasurement implements Measurement { /** * {@inheritDoc} */ + @Override public Type getValue(Algorithm algorithm) { - if (function == null) + if (function == null) { throw new InitialisationException("The function that should be evaluated has not been set"); + } Vector vector = (Vector) algorithm.getBestSolution().getPosition(); return new Real(function.evaluate(vector)); diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterCentroids.java b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterCentroids.java new file mode 100644 index 0000000..181fd8f --- /dev/null +++ b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterCentroids.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2003 - 2008 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package net.sourceforge.cilib.measurement.single.clustering; + +import net.sourceforge.cilib.algorithm.Algorithm; +import net.sourceforge.cilib.measurement.Measurement; +import net.sourceforge.cilib.type.types.Type; +import net.sourceforge.cilib.type.types.container.Vector; +import net.sourceforge.cilib.util.ClusteringUtils; + +/** + * Combines and measures the centroid vectors of the clusters optimised by the given algorithm. + * + * @author Theuns Cloete + */ +public class ClusterCentroids implements Measurement { + @Override + public Measurement getClone() { + return this; + } + + @Override + public String getDomain() { + return "(R^?)^?"; + } + + @Override + public Type getValue(Algorithm algorithm) { + Vector combined = new Vector(); + + for (Vector centroid : ClusteringUtils.get().getArrangedCentroids()) { + combined.append(centroid); + } + return combined; + } +} diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterMeans.java similarity index 50% copy from src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java copy to src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterMeans.java index 2cbd70e..028b3a2 100644 --- a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java +++ b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterMeans.java @@ -19,51 +19,43 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -package net.sourceforge.cilib.measurement.single; +package net.sourceforge.cilib.measurement.single.clustering; +import java.util.ArrayList; +import java.util.Hashtable; import net.sourceforge.cilib.algorithm.Algorithm; +import net.sourceforge.cilib.math.StatUtils; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.problem.dataset.DataSetBuilder; -import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; -import net.sourceforge.cilib.type.types.Int; +import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.Type; import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.ClusteringUtils; /** - * This measurement measures the number of clusters that were formed during a particular clustering. - * For this measurement to work, the following is important: - * <ol> - * <li><tt>Algorithm.get()</tt> should not be <tt>null</tt>.</li> - * <li>The algorithm's best solution (best position) should return a {@link Vector}.</li> - * <li>The algorithm's problem's {@link DataSetBuilder} should be a - * {@link StaticDataSetBuilder}.</li> - * <li>The {@link ClusteringUtils#arrangeClustersAndCentroids(net.sourceforge.cilib.type.types.container.Vector)} method - * should be implemented to remove <i>empty clusters</i>.</li> - * <li>The {@link ClusteringUtils#getArrangedClusters()} method should be implemented to return the list of non-empty - * clusters.</li> - * </ol> + * Combines and measures the mean vectors of the clusters optimised by the given algorithm. + * * @author Theuns Cloete */ -public class NumberOfClustersFormed implements Measurement { - private static final long serialVersionUID = 2174807313995885918L; - +public class ClusterMeans implements Measurement { @Override - public NumberOfClustersFormed getClone() { + public Measurement getClone() { return this; } @Override public String getDomain() { - return "Z"; + return "(R^?)^?"; } @Override public Type getValue(Algorithm algorithm) { ClusteringUtils helper = ClusteringUtils.get(); - Vector centroids = (Vector) algorithm.getBestSolution().getPosition(); + ArrayList<Hashtable<Integer, Pattern>> clusters = helper.getArrangedClusters(); + Vector combined = new Vector(); - helper.arrangeClustersAndCentroids(centroids); - return new Int(helper.getArrangedCentroids().size()); + for (Hashtable<Integer, Pattern> cluster : clusters) { + combined.append(StatUtils.meanVector(cluster.values())); + } + return combined; } } diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterStandardDeviations.java similarity index 50% copy from src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java copy to src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterStandardDeviations.java index 2cbd70e..a1ad236 100644 --- a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java +++ b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterStandardDeviations.java @@ -19,51 +19,44 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -package net.sourceforge.cilib.measurement.single; +package net.sourceforge.cilib.measurement.single.clustering; +import java.util.ArrayList; +import java.util.Hashtable; import net.sourceforge.cilib.algorithm.Algorithm; +import net.sourceforge.cilib.math.StatUtils; import net.sourceforge.cilib.measurement.Measurement; -import net.sourceforge.cilib.problem.dataset.DataSetBuilder; -import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; -import net.sourceforge.cilib.type.types.Int; +import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.Type; import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.ClusteringUtils; /** - * This measurement measures the number of clusters that were formed during a particular clustering. - * For this measurement to work, the following is important: - * <ol> - * <li><tt>Algorithm.get()</tt> should not be <tt>null</tt>.</li> - * <li>The algorithm's best solution (best position) should return a {@link Vector}.</li> - * <li>The algorithm's problem's {@link DataSetBuilder} should be a - * {@link StaticDataSetBuilder}.</li> - * <li>The {@link ClusteringUtils#arrangeClustersAndCentroids(net.sourceforge.cilib.type.types.container.Vector)} method - * should be implemented to remove <i>empty clusters</i>.</li> - * <li>The {@link ClusteringUtils#getArrangedClusters()} method should be implemented to return the list of non-empty - * clusters.</li> - * </ol> + * Combines and measures the standard deviation vectors of the clusters optimised by the given algorithm. + * * @author Theuns Cloete */ -public class NumberOfClustersFormed implements Measurement { - private static final long serialVersionUID = 2174807313995885918L; - +public class ClusterStandardDeviations implements Measurement { @Override - public NumberOfClustersFormed getClone() { + public Measurement getClone() { return this; } @Override public String getDomain() { - return "Z"; + return "(R^?)^?"; } @Override public Type getValue(Algorithm algorithm) { ClusteringUtils helper = ClusteringUtils.get(); - Vector centroids = (Vector) algorithm.getBestSolution().getPosition(); + ArrayList<Hashtable<Integer, Pattern>> clusters = helper.getArrangedClusters(); + ArrayList<Vector> centroids = helper.getArrangedCentroids(); + Vector combined = new Vector(); - helper.arrangeClustersAndCentroids(centroids); - return new Int(helper.getArrangedCentroids().size()); + for (int i = 0; i < clusters.size(); ++i) { + combined.append(StatUtils.stdDeviationVector(clusters.get(i).values(), centroids.get(i))); + } + return combined; } } diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterVariances.java b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterVariances.java new file mode 100644 index 0000000..7192cf0 --- /dev/null +++ b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/ClusterVariances.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2003 - 2008 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package net.sourceforge.cilib.measurement.single.clustering; + +import java.util.ArrayList; +import java.util.Hashtable; +import net.sourceforge.cilib.algorithm.Algorithm; +import net.sourceforge.cilib.math.StatUtils; +import net.sourceforge.cilib.measurement.Measurement; +import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.type.types.Type; +import net.sourceforge.cilib.type.types.container.Vector; +import net.sourceforge.cilib.util.ClusteringUtils; + +/** + * Combines and measures the variance vectors of the clusters optimised by the given algorithm. + * + * @author theuns.cloete + */ +public class ClusterVariances implements Measurement { + @Override + public Measurement getClone() { + return this; + } + + @Override + public String getDomain() { + return "(R^?)^?"; + } + + @Override + public Type getValue(Algorithm algorithm) { + ClusteringUtils helper = ClusteringUtils.get(); + ArrayList<Hashtable<Integer, Pattern>> clusters = helper.getArrangedClusters(); + ArrayList<Vector> centroids = helper.getArrangedCentroids(); + Vector combined = new Vector(); + + for (int i = 0; i < clusters.size(); ++i) { + combined.append(StatUtils.varianceVector(clusters.get(i).values(), centroids.get(i))); + } + return combined; + } +} diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/clustering/DataSetDiameter.java b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/DataSetDiameter.java new file mode 100644 index 0000000..b89e75a --- /dev/null +++ b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/DataSetDiameter.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2003 - 2008 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package net.sourceforge.cilib.measurement.single.clustering; + +import net.sourceforge.cilib.algorithm.Algorithm; +import net.sourceforge.cilib.measurement.Measurement; +import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; +import net.sourceforge.cilib.type.types.Real; +import net.sourceforge.cilib.type.types.Type; +import net.sourceforge.cilib.util.ClusteringUtils; + +/** + * Calculates the data set diameter as the maximum distance between any two patterns in the data set. The + * {@link StaticDataSetBuilder} already cached the distances from every pattern to every other pattern using its own + * customisable {@link DistanceMeasure}. + * + * @author Theuns Cloete + */ +public class DataSetDiameter implements Measurement { + private Real xMax = null; + + @Override + public Measurement getClone() { + return this; + } + + @Override + public String getDomain() { + return "R"; + } + + @Override + public Type getValue(Algorithm algorithm) { + // we only have to calculate it once as long as the data set remains static/unchanged + if (xMax == null) { + ClusteringUtils helper = ClusteringUtils.get(); + StaticDataSetBuilder dataSetBuilder = helper.getDataSetBuilder(); + int numPatterns = helper.getNumberOfPatternsInDataSet(); + double maxDistance = 0.0; + + for (int y = 0; y < numPatterns - 1; y++) { + for (int x = y + 1; x < numPatterns; x++) { + maxDistance = Math.max(maxDistance, dataSetBuilder.getCachedDistance(x, y)); + } + } + this.xMax = new Real(maxDistance); + } + return this.xMax; + } +} diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/NumberOfClustersFormed.java similarity index 96% rename from src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java rename to src/main/java/net/sourceforge/cilib/measurement/single/clustering/NumberOfClustersFormed.java index 2cbd70e..676a9b5 100644 --- a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java +++ b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/NumberOfClustersFormed.java @@ -19,7 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -package net.sourceforge.cilib.measurement.single; +package net.sourceforge.cilib.measurement.single.clustering; import net.sourceforge.cilib.algorithm.Algorithm; import net.sourceforge.cilib.measurement.Measurement; @@ -36,13 +36,13 @@ import net.sourceforge.cilib.util.ClusteringUtils; * <ol> * <li><tt>Algorithm.get()</tt> should not be <tt>null</tt>.</li> * <li>The algorithm's best solution (best position) should return a {@link Vector}.</li> - * <li>The algorithm's problem's {@link DataSetBuilder} should be a - * {@link StaticDataSetBuilder}.</li> + * <li>The algorithm's problem's {@link DataSetBuilder} should be a {@link StaticDataSetBuilder}.</li> * <li>The {@link ClusteringUtils#arrangeClustersAndCentroids(net.sourceforge.cilib.type.types.container.Vector)} method * should be implemented to remove <i>empty clusters</i>.</li> * <li>The {@link ClusteringUtils#getArrangedClusters()} method should be implemented to return the list of non-empty * clusters.</li> * </ol> + * * @author Theuns Cloete */ public class NumberOfClustersFormed implements Measurement { diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/PlotClustersAndCentroids.java b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/PlotClustersAndCentroids.java similarity index 95% rename from src/main/java/net/sourceforge/cilib/measurement/single/PlotClustersAndCentroids.java rename to src/main/java/net/sourceforge/cilib/measurement/single/clustering/PlotClustersAndCentroids.java index e6e4f84..0f9a6cd 100644 --- a/src/main/java/net/sourceforge/cilib/measurement/single/PlotClustersAndCentroids.java +++ b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/PlotClustersAndCentroids.java @@ -19,7 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -package net.sourceforge.cilib.measurement.single; +package net.sourceforge.cilib.measurement.single.clustering; import java.util.ArrayList; import java.util.Hashtable; @@ -34,10 +34,10 @@ import net.sourceforge.cilib.util.ClusteringUtils; /** * This measurement is handy when debugging a clustering in R^2 space using GNUplot. Logging should be disabled and no * other output should be written to standard out. To try it, start GNUplot, execute:<br/> - * load "<./simulator.sh path/to/your/cilib.config.file.xml"<br/> + * load "<./simulator.sh path/to/your/cilib.config.file.xml -noprogress"<br/> * and enjoy. * - * @author theuns.cloete + * @author Theuns Cloete */ public class PlotClustersAndCentroids implements Measurement { @Override diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/clustering/SearchSpaceDiameter.java b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/SearchSpaceDiameter.java new file mode 100644 index 0000000..7c74736 --- /dev/null +++ b/src/main/java/net/sourceforge/cilib/measurement/single/clustering/SearchSpaceDiameter.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2003 - 2008 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package net.sourceforge.cilib.measurement.single.clustering; + +import net.sourceforge.cilib.algorithm.Algorithm; +import net.sourceforge.cilib.measurement.Measurement; +import net.sourceforge.cilib.problem.ClusteringProblem; +import net.sourceforge.cilib.type.types.Real; +import net.sourceforge.cilib.type.types.Type; +import net.sourceforge.cilib.type.types.container.Vector; +import net.sourceforge.cilib.util.VectorUtils; + +/** + * The search space diameter is equal to the distance between the two furthest possible points in the search space. + * + * @author Theuns Cloete + */ +public class SearchSpaceDiameter implements Measurement { + private Real zMax = null; + + @Override + public Measurement getClone() { + return this; + } + + @Override + public String getDomain() { + return "R"; + } + + @Override + public Type getValue(Algorithm algorithm) { + // we only have to calculate it once as long as the search space remains static/unchanged + if (zMax == null) { + ClusteringProblem problem = (ClusteringProblem) algorithm.getOptimisationProblem(); + Vector domain = (Vector) problem.getBehaviouralDomain().getBuiltRepresenation(); + + this.zMax = new Real(VectorUtils.zMax(problem.getDistanceMeasure(), domain)); + } + return this.zMax; + } +} diff --git a/src/test/java/net/sourceforge/cilib/math/StatUtilsTest.java b/src/test/java/net/sourceforge/cilib/math/StatUtilsTest.java index 31595bf..0b6ecf0 100644 --- a/src/test/java/net/sourceforge/cilib/math/StatUtilsTest.java +++ b/src/test/java/net/sourceforge/cilib/math/StatUtilsTest.java @@ -25,6 +25,8 @@ package net.sourceforge.cilib.math; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.hamcrest.CoreMatchers.is; import java.util.ArrayList; @@ -40,6 +42,7 @@ public class StatUtilsTest { private static ArrayList<Pattern> set; private static Vector mean = null; private static final int SIZE = 3; + private static final double EPSILON = 0.000000000000001; @BeforeClass public static void setUpBeforeClass() throws Exception { @@ -93,6 +96,30 @@ public class StatUtilsTest { @Test public void testVarianceScalar() { - assertThat(StatUtils.variance(set, mean), equalTo(1.2)); // more accurate than StatUtils.varianceVector() + assertEquals(1.2, StatUtils.variance(set, mean), EPSILON); + } + + @Test + public void testVarianceVector() { + Vector varianceVector = StatUtils.varianceVector(set, mean); + + assertThat(varianceVector.getReal(0), is(0.8)); + assertThat(varianceVector.getReal(1), is(0.4)); + assertThat(varianceVector.getReal(2), is(0.8)); + assertEquals(1.2, varianceVector.norm(), EPSILON); + } + + @Test + public void testStdDeviationScalar() { + assertEquals(1.0954451150103323, StatUtils.stdDeviation(set, mean), EPSILON); + } + + @Test + public void testStdDeviationVector() { + Vector stdDeviationVector = StatUtils.stdDeviationVector(set, mean); + + assertEquals(0.894427190999916, stdDeviationVector.getReal(0), EPSILON); + assertEquals(0.632455532033676, stdDeviationVector.getReal(1), EPSILON); + assertEquals(0.894427190999916, stdDeviationVector.getReal(2), EPSILON); } } diff --git a/xml/clustering-gbest-pso.xml b/xml/clustering-gbest-pso.xml index c640591..793d8d9 100644 --- a/xml/clustering-gbest-pso.xml +++ b/xml/clustering-gbest-pso.xml @@ -1013,7 +1013,7 @@ <addMeasurement class="measurement.single.GenericFunctionMeasurement"> <function class="functions.clustering.IntraClusterDistance" /> </addMeasurement> - <addMeasurement class="measurement.single.NumberOfClustersFormed" /> + <addMeasurement class="measurement.single.clustering.NumberOfClustersFormed" /> <addMeasurement class="measurement.single.diversity.Diversity" /> </measurements> diff --git a/xml/clustering.dynamic.circles.xml b/xml/clustering.dynamic.circles.xml index 91c637e..7ab11d5 100644 --- a/xml/clustering.dynamic.circles.xml +++ b/xml/clustering.dynamic.circles.xml @@ -47,7 +47,7 @@ <measurements id="measurements" class="simulator.MeasurementSuite" resolution="1" samples="1"> <addMeasurement class="measurement.single.Fitness" /> - <addMeasurement class="measurement.single.NumberOfClustersFormed" /> + <addMeasurement class="measurement.single.clustering.NumberOfClustersFormed" /> </measurements> <simulations> diff --git a/xml/kmeans.xml b/xml/kmeans.xml index b0428d1..7421622 100644 --- a/xml/kmeans.xml +++ b/xml/kmeans.xml @@ -44,8 +44,8 @@ <function class="functions.clustering.IntraClusterDistance" /> </addMeasurement> --> - <addMeasurement class="measurement.single.NumberOfClustersFormed" /> - <addMeasurement class="measurement.single.PlotClustersAndCentroids" /> + <addMeasurement class="measurement.single.clustering.NumberOfClustersFormed" /> + <addMeasurement class="measurement.single.clustering.PlotClustersAndCentroids" /> </measurements> <simulations> -- 1.6.0.6 |
From: Theuns C. <the...@gm...> - 2009-06-10 06:42:30
|
--- xml/kmeans.xml | 30 +++++++++--------------------- 1 files changed, 9 insertions(+), 21 deletions(-) diff --git a/xml/kmeans.xml b/xml/kmeans.xml index 19c6f8b..b0428d1 100644 --- a/xml/kmeans.xml +++ b/xml/kmeans.xml @@ -9,25 +9,18 @@ <simulator> <algorithms> <algorithm id="kmeans.random" class="clustering.kmeans.KMeans"> - <addStoppingCondition class="stoppingcondition.MaximumIterations" maximumIterations="1000"/> + <addStoppingCondition class="stoppingcondition.MaximumIterations" maximumIterations="100"/> </algorithm> <algorithm id="kmeans.biased" class="clustering.kmeans.KMeans"> - <addStoppingCondition class="stoppingcondition.MaximumIterations" maximumIterations="1000"/> + <addStoppingCondition class="stoppingcondition.MaximumIterations" maximumIterations="100"/> <centroidsInitialisationStrategy class="clustering.kmeans.DataSetBasedCentroidsInitialisationStrategy"/> </algorithm> - <algorithm id="pso.random" class="pso.PSO"> - <addStoppingCondition class="stoppingcondition.MaximumIterations" maximumIterations="1000"/> - </algorithm> - - <algorithm id="pso.biased" class="pso.PSO"> - <addStoppingCondition class="stoppingcondition.MaximumIterations" maximumIterations="1000"/> - <initialisationStrategy class="algorithm.initialisation.ClonedPopulationInitialisationStrategy"> - <entityType class="pso.particle.StandardParticle"> - <positionInitialisationStrategy class="pso.particle.initialisation.DataSetBasedPositionInitialisationStrategy"/> - </entityType> - </initialisationStrategy> + <algorithm id="kmeans.plusplus" class="clustering.kmeans.KMeans"> + <addStoppingCondition class="stoppingcondition.MaximumIterations" maximumIterations="100"/> + <centroidsInitialisationStrategy class="clustering.kmeans.KMeansPlusPlusCentroidsInitialisationStrategy"/> + <centroidsDiversificationStrategy class="clustering.kmeans.StandardCentroidsDiversificationStrategy" interval="1" diversifyRatio="0.1" /> </algorithm> </algorithms> @@ -52,6 +45,7 @@ </addMeasurement> --> <addMeasurement class="measurement.single.NumberOfClustersFormed" /> + <addMeasurement class="measurement.single.PlotClustersAndCentroids" /> </measurements> <simulations> @@ -62,21 +56,15 @@ </simulation> <simulation> - <algorithm idref="pso.random"/> - <problem idref="artificial.combined" numberOfClusters="4" /> - <measurements idref="measurements" file="measurements/pso.random.artificial.4.txt" /> - </simulation> - - <simulation> <algorithm idref="kmeans.biased"/> <problem idref="artificial.combined" numberOfClusters="4" /> <measurements idref="measurements" file="measurements/kmeans.biased.artificial.4.txt" /> </simulation> <simulation> - <algorithm idref="pso.biased"/> + <algorithm idref="kmeans.plusplus"/> <problem idref="artificial.combined" numberOfClusters="4" /> - <measurements idref="measurements" file="measurements/pso.biased.artificial.4.txt" /> + <measurements idref="measurements" file="measurements/kmeans.plusplus.artificial.4.txt" /> </simulation> </simulations> </simulator> -- 1.6.0.6 |
From: Theuns C. <the...@gm...> - 2009-06-10 06:42:30
|
This is achieved by introducing a reinitialise() method in the CentroidsInitialisationStrategy interface. Also made some small fixes regarding the DataSetManager and StaticDataSetBuilder. --- .../kmeans/CentroidsInitialisationStrategy.java | 16 +++- ...ataSetBasedCentroidsInitialisationStrategy.java | 23 +++++- .../cilib/clustering/kmeans/KMeans.java | 3 +- ...ansPlusPlusCentroidsInitialisationStrategy.java | 44 +++++++---- .../RandomCentroidsInitialisationStrategy.java | 17 +++- .../cilib/problem/ClusteringProblem.java | 6 +- .../sourceforge/cilib/problem/dataset/DataSet.java | 2 +- .../cilib/problem/dataset/DataSetManager.java | 9 +- .../cilib/problem/dataset/LocalDataSet.java | 8 +- .../problem/dataset/StaticDataSetBuilder.java | 88 ++++++++++++++------ xml/clustering-gbest-pso.xml | 18 ++-- xml/kmeans.xml | 42 +--------- 12 files changed, 163 insertions(+), 113 deletions(-) diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsInitialisationStrategy.java index 22a203e..6465e56 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsInitialisationStrategy.java @@ -30,12 +30,14 @@ import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.Cloneable; /** - * This strategy allows for different ways of initializing the centroids of a clustering. + * This strategy allows for different ways of initializing the centroids of a clustering. It also allows for a specific + * centroid to be {@link #reinitialise(java.util.ArrayList, int) reinitialised}. * The following approaches have already been implemented: * <ul> * <li>Randomly ({@link RandomCentroidsInitialisationStrategy}); or</li> * <li>Based on random patterns chosen from the dataset ({@link DataSetBasedCentroidsInitialisationStrategy})</li> - * <li>Based on the potential that each centroid contributes ({@link KMeansPlusPlusCentroidsInitialisationStrategy})</li> + * <li>Based on the contribution that each centroid contributes towards the overall potential + * ({@link KMeansPlusPlusCentroidsInitialisationStrategy})</li> * </ul> * * @author Theuns Cloete @@ -45,7 +47,7 @@ public interface CentroidsInitialisationStrategy extends Serializable, Cloneable public CentroidsInitialisationStrategy getClone(); /** - * Initialize the centroid vectors for a clustering. Each centroid is individually initialised and then added to an + * Initialise the centroid vectors for a clustering. Each centroid is individually initialised and then added to an * {@link ArrayList} that represents all the centroids. This structure is then returned. The problem and/or dataset * that are currently being clustered can be used to get information about the clustering, such as the dimension of * the search space and centroids. @@ -55,4 +57,12 @@ public interface CentroidsInitialisationStrategy extends Serializable, Cloneable * @return an {@link ArrayList} of {@link Vector}s that represent all the centroids */ public ArrayList<Vector> initialise(ClusteringProblem problem, StaticDataSetBuilder dataset); + + /** + * Reinitialise the specified centroid (residing in the given list of centroids) and return it. + * @param centroids The list of centroid vectors containing the centroid that needs to be reinitialised. + * @param which The index of the centroid that should be reinitialised. + * @return the reinitialised centroid for convenience + */ + public Vector reinitialise(ArrayList<Vector> centroids, int which); } diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java index e15ace7..1df40d6 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java @@ -39,6 +39,12 @@ import net.sourceforge.cilib.type.types.container.Vector; public class DataSetBasedCentroidsInitialisationStrategy implements CentroidsInitialisationStrategy { private static final long serialVersionUID = -3016201656688883387L; + private ArrayList<Pattern> patterns; + + public DataSetBasedCentroidsInitialisationStrategy() { + this.patterns = null; + } + /** * {@inheritDoc} */ @@ -59,14 +65,27 @@ public class DataSetBasedCentroidsInitialisationStrategy implements CentroidsIni public ArrayList<Vector> initialise(ClusteringProblem problem, StaticDataSetBuilder dataset) { int numberOfCentroids = problem.getNumberOfClusters(); ArrayList<Vector> centroids = new ArrayList<Vector>(numberOfCentroids); - ArrayList<Pattern> patterns = dataset.getPatterns(); + this.patterns = dataset.getPatterns(); Random random = new MersenneTwister(); for (int i = 0; i < numberOfCentroids; ++i) { - Vector centroid = patterns.get(Math.round(random.nextInt(patterns.size()))).data.getClone(); + Vector centroid = patterns.get(random.nextInt(patterns.size())).data.getClone(); centroids.add(centroid); } return centroids; } + + /** + * Just pick a random pattern from the data set. + * {@inheritDoc} + */ + @Override + public Vector reinitialise(ArrayList<Vector> centroids, int which) { + Random random = new MersenneTwister(); + Vector reinitialised = patterns.get(random.nextInt(patterns.size())).data.getClone(); + + centroids.set(which, reinitialised); + return reinitialised; + } } diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java index 1f1ab2f..c1f3f98 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java @@ -130,8 +130,7 @@ public class KMeans extends SingularAlgorithm { // TODO: I don't know if this if-else is part of the original KMeans algorithm if (cluster.isEmpty()) { // reinitialise the centroid if no patterns "belong" to it - ArrayList<Vector> tmp = this.centroidsInitialisationStrategy.initialise(helper.getClusteringProblem(), helper.getDataSetBuilder()); - centroid = tmp.get(tmp.size() - 1); // use the last centroid that was generated; might return an unbounded Vector + centroid = this.centroidsInitialisationStrategy.reinitialise(centroids, i); // might return unbounded Vector } else { // the centroid becomes the mean of cluster i diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeansPlusPlusCentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeansPlusPlusCentroidsInitialisationStrategy.java index c8b1e43..5ad35f8 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeansPlusPlusCentroidsInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeansPlusPlusCentroidsInitialisationStrategy.java @@ -46,12 +46,10 @@ import net.sourceforge.cilib.util.DistanceMeasure; public class KMeansPlusPlusCentroidsInitialisationStrategy implements CentroidsInitialisationStrategy { private ArrayList<Pattern> patterns; private DistanceMeasure distanceMeasure; - private ArrayList<Vector> chosenCentroids; public KMeansPlusPlusCentroidsInitialisationStrategy() { patterns = null; distanceMeasure = null; - chosenCentroids = null; } /** @@ -71,29 +69,45 @@ public class KMeansPlusPlusCentroidsInitialisationStrategy implements CentroidsI Random randomPattern = new MersenneTwister(); Random randomProbability = new MersenneTwister(); int numberOfClusters = problem.getNumberOfClusters(); - int centroidsChosen = 0; this.patterns = dataset.getPatterns(); this.distanceMeasure = problem.getDistanceMeasure(); - this.chosenCentroids = new ArrayList<Vector>(); + ArrayList<Vector> chosenCentroids = new ArrayList<Vector>(); - while (centroidsChosen < numberOfClusters) { - Vector candidateCentroid = patterns.get(Math.round(randomPattern.nextInt(patterns.size()))).data.getClone(); + for (int i = 0; i < numberOfClusters; ++i) { + Vector candidateCentroid = patterns.get(randomPattern.nextInt(patterns.size())).data.getClone(); - if (centroidsChosen > 0) { - double probability = calculateProbability(candidateCentroid); - - if (randomProbability.nextDouble() >= probability) { - continue; + if (i > 0) { + while (randomProbability.nextDouble() >= this.calculateProbability(chosenCentroids, candidateCentroid)) { + candidateCentroid = patterns.get(randomPattern.nextInt(patterns.size())).data.getClone(); } } - this.chosenCentroids.add(candidateCentroid); - ++centroidsChosen; + chosenCentroids.add(candidateCentroid); + } + return chosenCentroids; + } + + /** + * Remove the unwanted centroid and replace it with a newly chosen centroid, still based on its contribtution to the + * overall potential. + * {@inheritDoc} + */ + @Override + public Vector reinitialise(ArrayList<Vector> centroids, int which) { + Vector candidateCentroid = null; + Random randomPattern = new MersenneTwister(); + Random randomProbability = new MersenneTwister(); + + do { + candidateCentroid = patterns.get(randomPattern.nextInt(patterns.size())).data.getClone(); } - return this.chosenCentroids; + while (randomProbability.nextDouble() >= this.calculateProbability(centroids, candidateCentroid)); + + centroids.set(which, candidateCentroid); + return candidateCentroid; } - private double calculateProbability(Vector candidateCentroid) { + private double calculateProbability(ArrayList<Vector> chosenCentroids, Vector candidateCentroid) { double probability = 0.0; double numerator = Double.MAX_VALUE; diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/RandomCentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/RandomCentroidsInitialisationStrategy.java index d2abd86..38a2a2a 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/RandomCentroidsInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/RandomCentroidsInitialisationStrategy.java @@ -48,9 +48,7 @@ public class RandomCentroidsInitialisationStrategy implements CentroidsInitialis * space. The built-representation of the behavioural domain of the given {@link ClusteringProblem} is used to build a * {@link Vector} that will house the centroids. * - * @param problem the {@link ClusteringProblem} currently being optimized - * @param dataset the {@link StaticDataSetBuilder} currently being clustered - * @return an {@link ArrayList} of {@link Vector}s that represents all the centroids + * {@inheritDoc} */ @Override public ArrayList<Vector> initialise(ClusteringProblem problem, StaticDataSetBuilder dataset) { @@ -65,4 +63,17 @@ public class RandomCentroidsInitialisationStrategy implements CentroidsInitialis } return centroids; } + + /** + * Just randomize the centroid vector. + * {@inheritDoc} + */ + @Override + public Vector reinitialise(ArrayList<Vector> centroids, int which) { + Vector reinitialised = centroids.get(which); + + reinitialised.randomize(); + + return reinitialised; + } } diff --git a/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java b/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java index ee89d00..dc51c96 100644 --- a/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java +++ b/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java @@ -184,7 +184,7 @@ public class ClusteringProblem extends OptimisationProblemAdapter { /** * Duplicate the domain string of this clustering problem's dataset based on the number * of clusters that have been specified. For example, if the {@link #setDomain(String)} - * method has has been called with <code>"R(-1.0,1.0),R(-1.0,1.0)"</code> as parameter + * method has been called with <code>"R(-1.0,1.0),R(-1.0,1.0)"</code> as parameter * and the {@link #setNumberOfClusters(int)} method has been called with <code>3</code> * as parameter, then the clustering fitness function's domain will automatically be * regenerated to be @@ -200,7 +200,7 @@ public class ClusteringProblem extends OptimisationProblemAdapter { return; } - String duplicated = new String(domainRegistry.getDomainString()); + String duplicated = domainRegistry.getDomainString(); for (int i = 1; i < numberOfClusters; i++) { duplicated += "," + domainRegistry.getDomainString(); @@ -229,7 +229,7 @@ public class ClusteringProblem extends OptimisationProblemAdapter { * clustered */ public void setDomain(String representation) { - DomainParser parser = new DomainParser();//DomainParser.getInstance(); + DomainParser parser = new DomainParser(); parser.parse(representation); domainRegistry.setDomainString(representation); diff --git a/src/main/java/net/sourceforge/cilib/problem/dataset/DataSet.java b/src/main/java/net/sourceforge/cilib/problem/dataset/DataSet.java index d3f156f..9e171e9 100644 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/DataSet.java +++ b/src/main/java/net/sourceforge/cilib/problem/dataset/DataSet.java @@ -39,7 +39,7 @@ public abstract class DataSet implements Cloneable, Serializable { protected String identifier = null; public DataSet() { - identifier = "<not set>"; + identifier = "<unknown data set>"; } public DataSet(DataSet rhs) { diff --git a/src/main/java/net/sourceforge/cilib/problem/dataset/DataSetManager.java b/src/main/java/net/sourceforge/cilib/problem/dataset/DataSetManager.java index 6145dcc..2025ab8 100644 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/DataSetManager.java +++ b/src/main/java/net/sourceforge/cilib/problem/dataset/DataSetManager.java @@ -78,12 +78,11 @@ public final class DataSetManager implements Serializable { public synchronized ArrayList<Pattern> getDataFromSet(DataSet dataset) { String identifier = dataset.getIdentifier(); - logger.debug("Requesting " + identifier); + logger.debug("Requesting data set: " + identifier); if (!datasets.containsKey(identifier)) { - logger.debug("Parsing " + identifier); datasets.put(identifier, dataset.parseDataSet()); } - logger.debug("Returning " + identifier); + logger.debug("Returning data set: " + identifier); return datasets.get(identifier); } @@ -100,12 +99,12 @@ public final class DataSetManager implements Serializable { public synchronized StaticDataSetBuilder getDataSetBuilder(StaticDataSetBuilder datasetBuilder) { String identifier = datasetBuilder.getIdentifier(); - logger.debug("Requesting " + identifier); + logger.debug("Requesting built data set: " + identifier); if (!builders.containsKey(identifier)) { datasetBuilder.initialise(); builders.put(identifier, datasetBuilder); } - logger.debug("Returning " + identifier); + logger.debug("Returning built data set: " + identifier); return builders.get(identifier); } } diff --git a/src/main/java/net/sourceforge/cilib/problem/dataset/LocalDataSet.java b/src/main/java/net/sourceforge/cilib/problem/dataset/LocalDataSet.java index 89705c1..ba5675f 100644 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/LocalDataSet.java +++ b/src/main/java/net/sourceforge/cilib/problem/dataset/LocalDataSet.java @@ -140,7 +140,7 @@ public class LocalDataSet extends DataSet { ArrayList<Pattern> patterns = new ArrayList<Pattern>(); BufferedReader br = new BufferedReader(new InputStreamReader(getInputStream())); - logger.info("Parsing " + identifier); + logger.info("Parsing data set: " + identifier); try { // every line in a dataset represents a pattern String line = br.readLine(); @@ -167,12 +167,12 @@ public class LocalDataSet extends DataSet { */ private Pattern parseLine(String line) { // split the line using the 'delimiter' regular expression - String[] elements = line.split(delimiter); + String [] elements = line.split(delimiter); // the elements of the split are stored inside a vector that will form the pattern Vector pattern = new Vector(endIndex - beginIndex + 1); - for (int i = beginIndex; i <= endIndex; i++) { - pattern.add(new Real(Double.valueOf(elements[i]))); + for (int i = beginIndex; i <= endIndex; ++i) { + pattern.add(new Real(Double.parseDouble(elements[i]))); } String clazz = ""; diff --git a/src/main/java/net/sourceforge/cilib/problem/dataset/StaticDataSetBuilder.java b/src/main/java/net/sourceforge/cilib/problem/dataset/StaticDataSetBuilder.java index a673f58..faa68c1 100644 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/StaticDataSetBuilder.java +++ b/src/main/java/net/sourceforge/cilib/problem/dataset/StaticDataSetBuilder.java @@ -33,10 +33,9 @@ import org.slf4j.LoggerFactory; /** * This class "collects" and holds all the patterns of the {@link DataSet}s specified - * through the {@link #addDataSet(DataSet)} method. The name is no longer relevant, because - * this class no longer keeps track of cluster assignments. That is now the job of the - * {@link ClusteringUtils} class. Therefore, this class' name will probably change to - * something like ClusterableDataSetBuilder. + * through the {@link #addDataSet(DataSet)} method. It was originally the <code>AssociatedPairDataSetBuilder</code> + * class, but has since changed quite a lot. Most of the functionality is now handled by the {@link ClusteringUtils} + * helper class. * * @author Gary Pampara * @author Theuns Cloete @@ -45,26 +44,32 @@ public class StaticDataSetBuilder extends DataSetBuilder { private static final long serialVersionUID = -7035524554252462144L; private static Logger logger = LoggerFactory.getLogger(StaticDataSetBuilder.class); - protected ArrayList<Pattern> patterns = null; - protected Vector cachedMean = null; - protected double cachedVariance = 0.0; - protected double distanceCache[] = null; - protected String identifier = null; + protected ArrayList<Pattern> patterns; + protected Vector cachedMean; + protected double cachedVariance; + protected double distanceCache[]; + protected String identifier; + protected boolean cached; /** * Initialise the patterns data structure and set the identifier to be blank. */ public StaticDataSetBuilder() { - patterns = new ArrayList<Pattern>(); - identifier = ""; + this.patterns = new ArrayList<Pattern>(); + this.identifier = "<unknown built data set>"; + this.cached = true; } public StaticDataSetBuilder(StaticDataSetBuilder rhs) { super(rhs); - patterns = new ArrayList<Pattern>(); + this.patterns = new ArrayList<Pattern>(); + for (Pattern pattern : rhs.patterns) { - patterns.add(pattern.getClone()); + this.patterns.add(pattern.getClone()); } + + this.identifier = rhs.identifier; + this.cached = rhs.cached; } @Override @@ -106,22 +111,17 @@ public class StaticDataSetBuilder extends DataSetBuilder { throw new IllegalArgumentException("Cannot combine datasets of different dimensions"); } patterns.addAll(data); - - if (identifier.equals("")) { - identifier += dataset.getIdentifier(); - } - else { - identifier += "#|#" + dataset.getIdentifier(); - } logger.debug(data.size() + " patterns added"); } - cacheMeanAndVariance(); - cacheDistances(); + this.cacheMeanAndVariance(); + if (this.cached) { + this.cacheDistances(); + } } /** - * Calculate and cache the mean ({@link Vector}) and variance (scalar) of the dataset. + * Calculate and cached the mean ({@link Vector}) and variance (scalar) of the dataset. */ private void cacheMeanAndVariance() { logger.info("Caching dataset mean and variance"); @@ -150,7 +150,7 @@ public class StaticDataSetBuilder extends DataSetBuilder { } /** - * Calculate and cache the distances from all patterns to all other patterns. The cache + * Calculate and cache the distances from all patterns to all other patterns. The cached * structure looks like this (x represents a distance): * 0 1 2 3 4 5 * 0 0 x x x x x @@ -241,11 +241,47 @@ public class StaticDataSetBuilder extends DataSetBuilder { } /** - * Get the identifier that uniquely identifies this constructed/combined/built dataset. + * Get the identifier that uniquely identifies this constructed/combined/built data set. The returned string is + * created on the fly that lists all the {@link DataSet data sets} that comprises this built data set. * * @return the {@link #identifier} */ public String getIdentifier() { - return identifier; + String identifiedAs = this.identifier + " = {"; + + for (int i = 0; i < this.dataSets.size(); ++i) { + identifiedAs += this.dataSets.get(i).getIdentifier(); + + if (i < this.dataSets.size() - 1) { + identifiedAs += ","; + } + } + return identifiedAs + "}"; + } + + /** + * Set the identifier that will initially uniquely identify this constructed/combined/built dataset that should + * still be constructed. + * + * @param id the identifying string that should be used. + */ + public void setIdentifier(String id) { + this.identifier = id; + } + + /** + * Checker whether the distances between every pattern (in this built-up data set) were cached? + * @return true/false + */ + public boolean getCached() { + return this.cached; + } + + /** + * Sets whether the distances between every pattern (in this built-up data set) should be cached. + * @param c true/false + */ + public void setCached(boolean c) { + this.cached = c; } } diff --git a/xml/clustering-gbest-pso.xml b/xml/clustering-gbest-pso.xml index 948fa31..c640591 100644 --- a/xml/clustering-gbest-pso.xml +++ b/xml/clustering-gbest-pso.xml @@ -80,7 +80,7 @@ <!-- wdbc MINIMUMS and MAXIMUMS: R(6.9, 28.2), R(9.7, 39.3), R(43.7, 188.6), R(143.4, 2501.1), R(0.0, 0.2), R(0.0, 0.4), R(0.0, 0.5), R(0.0, 0.3), R(0.1, 0.4), R(0.0, 0.2), R(0.1, 2.9), R(0.3, 4.9), R(0.7, 22.0), R(6.7, 542.3), R(0.0, 0.1), R(0.0, 0.2), R(0.0, 0.5), R(0.0, 0.1), R(0.0, 0.1), R(0.0, 0.1), R(7.9, 36.1), R(12.0, 49.6), R(50.4, 251.3), R(185.1, 4254.1), R(0.0, 0.3), R(0.0, 1.1), R(0.0, 1.3), R(0.0, 0.3), R(0.1, 0.7), R(0.0, 0.3) --> <dataSetBuilder id="wdbc" class="problem.dataset.StaticDataSetBuilder"> <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/uci/breast-cancer-wisconsin/wdbc.data</identifier> + <identifier>../../datasets/uci/breast-cancer-wisconsin/wdbc.data</identifier> <!-- <patternExpression>(\d+,(M|B))?,</patternExpression> --> <delimiter>,</delimiter> <beginIndex>2</beginIndex> @@ -92,7 +92,7 @@ <!-- glass MINIMUMS and MAXIMUMS: R(1.5, 1.6), R(10.7, 17.4), R(0.0, 4.5), R(0.2, 3.6), R(69.8, 75.5), R(0.0, 6.3), R(5.4, 16.2), R(0.0, 3.2), R(0.0, 0.6) --> <dataSetBuilder id="glass" class="problem.dataset.StaticDataSetBuilder"> <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/uci/glass/glass.data</identifier> + <identifier>../../datasets/uci/glass/glass.data</identifier> <!-- <patternExpression>(^\d+,|\d$|,)</patternExpression> --> <delimiter>,</delimiter> <beginIndex>1</beginIndex> @@ -104,7 +104,7 @@ <!-- ionosphere MINIMUMS and MAXIMUMS: Z(0, 1), Z(0, 0), R(-1.0, 1.0)^32 --> <dataSetBuilder id="ionosphere" class="problem.dataset.StaticDataSetBuilder"> <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/uci/ionosphere/ionosphere.data</identifier> + <identifier>../../datasets/uci/ionosphere/ionosphere.data</identifier> <!-- <patternExpression>,(g|b)?</patternExpression> --> <delimiter>,</delimiter> <beginIndex>0</beginIndex> @@ -116,7 +116,7 @@ <!-- iris MINIMUMS and MAXIMUMS: R(4.2, 8.0), R(1.9, 4.5), R(0.9, 6.9), R(0.0, 2.6) --> <dataSetBuilder id="iris" class="problem.dataset.StaticDataSetBuilder"> <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/uci/iris/iris.data</identifier> + <identifier>../../datasets/uci/iris/iris.data</identifier> <!-- <patternExpression>,\D*</patternExpression>--> <delimiter>,</delimiter> <beginIndex>0</beginIndex> @@ -128,7 +128,7 @@ <!-- bupa MINIMUMS and MAXIMUMS: Z(65, 103), Z(23, 138), Z(4, 155), Z(5, 82), Z(5, 297), R(0.0, 20.0) --> <dataSetBuilder id="bupa" class="problem.dataset.StaticDataSetBuilder"> <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/uci/liver-disorders/bupa.data</identifier> + <identifier>../../datasets/uci/liver-disorders/bupa.data</identifier> <!-- <patternExpression>,\d$|,</patternExpression> --> <delimiter>,</delimiter> <beginIndex>0</beginIndex> @@ -140,7 +140,7 @@ <!-- pima indians diabetes MINIMUMS and MAXIMUMS: Z(0, 17), Z(0, 199), Z(0, 122), Z(0, 99), Z(0, 846), R(0, 67.1), R(0.08, 2.42), Z(21, 81) --> <dataSetBuilder id="diabetes" class="problem.dataset.StaticDataSetBuilder"> <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/uci/pima-indians-diabetes/pima-indians-diabetes.data</identifier> + <identifier>../../datasets/uci/pima-indians-diabetes/pima-indians-diabetes.data</identifier> <!-- <patternExpression>,\d$|,</patternExpression> --> <delimiter>,</delimiter> <beginIndex>0</beginIndex> @@ -152,7 +152,7 @@ <!-- new thyroid MINIMUMS and MAXIMUMS: Z(65, 144), R(0.5, 25.3), R(0.2, 10.0), R(0.1, 56.4), R(-0.7, 56.3) --> <dataSetBuilder id="thyroid" class="problem.dataset.StaticDataSetBuilder"> <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/uci/thyroid-disease/new-thyroid.data</identifier> + <identifier>../../datasets/uci/thyroid-disease/new-thyroid.data</identifier> <!-- <patternExpression>^\d,|,</patternExpression> --> <delimiter>,</delimiter> <beginIndex>1</beginIndex> @@ -164,7 +164,7 @@ <!-- wine MINIMUMS and MAXIMUMS: R(11.03, 14.83), R(0.74, 5.8), R(1.36, 3.23), R(10.6, 30.0), Z(70, 162), R(0.98, 3.88), R(0.34, 5.08), R(0.13, 0.66), R(0.41, 3.58), R(1.28, 13.0), R(0.48, 1.71), R(1.27, 4.0), Z(278, 1680) --> <dataSetBuilder id="wine" class="problem.dataset.StaticDataSetBuilder"> <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/uci/wine/wine.data</identifier> + <identifier>../../datasets/uci/wine/wine.data</identifier> <!-- <patternExpression>^\d,|,</patternExpression> --> <delimiter>,</delimiter> <beginIndex>1</beginIndex> @@ -176,7 +176,7 @@ <!-- artificial MINIMUMS and MAXIMUMS: R(-1.0, 1.0), R(-1.0, 1.0) --> <dataSetBuilder id="artificial" class="problem.dataset.StaticDataSetBuilder"> <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/generated/artificial2/artificial.txt</identifier> + <identifier>../../datasets/generated/artificial2/artificial.txt</identifier> <!-- <patternExpression>,Class\d|,</patternExpression> --> <delimiter>,</delimiter> <beginIndex>0</beginIndex> diff --git a/xml/kmeans.xml b/xml/kmeans.xml index 31ae178..19c6f8b 100644 --- a/xml/kmeans.xml +++ b/xml/kmeans.xml @@ -32,50 +32,12 @@ </algorithms> <problems> -<!-- - <problem id="artificial.seperate" class="problem.ClusteringProblem"> - <domain>R(-1.0,1.0),R(-1.0,1.0)</domain> - <innerProblem class="problem.FunctionMinimisationProblem"> - <function class="functions.clustering.QuantisationErrorFunction" /> - </innerProblem> - <dataSetBuilder class="problem.dataset.StaticDataSetBuilder"> - <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/generated/artificial2/class0</identifier> - <delimiter>\s</delimiter> - <beginIndex>0</beginIndex> - <endIndex>1</endIndex> - <classIndex>-1</classIndex> - </addDataSet> - <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/generated/artificial2/class1</identifier> - <delimiter>\s</delimiter> - <beginIndex>0</beginIndex> - <endIndex>1</endIndex> - <classIndex>-1</classIndex> - </addDataSet> - <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/generated/artificial2/class2</identifier> - <delimiter>\s</delimiter> - <beginIndex>0</beginIndex> - <endIndex>1</endIndex> - <classIndex>-1</classIndex> - </addDataSet> - <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/generated/artificial2/class3</identifier> - <delimiter>\s</delimiter> - <beginIndex>0</beginIndex> - <endIndex>1</endIndex> - <classIndex>-1</classIndex> - </addDataSet> - </dataSetBuilder> - </problem> ---> <problem id="artificial.combined" class="problem.ClusteringProblem" domain="R(-1.0,1.0),R(-1.0,1.0)"> <innerProblem class="problem.FunctionMinimisationProblem"> <function class="functions.clustering.QuantisationErrorFunction" /> </innerProblem> - <dataSetBuilder class="problem.dataset.StaticDataSetBuilder"> - <addDataSet class="problem.dataset.LocalDataSet" identifier="../../datasets/generated/artificial2/artificial.txt" delimiter="," beginIndex="0" endIndex="1" classIndex="2" /> + <dataSetBuilder class="problem.dataset.StaticDataSetBuilder" identifier="combined"> + <addDataSet class="problem.dataset.LocalDataSet" identifier="../../datasets/generated/artificial2/artificial.txt" delimiter="\s+" beginIndex="0" endIndex="1" classIndex="2" /> </dataSetBuilder> </problem> </problems> -- 1.6.0.6 |
From: Theuns C. <the...@gm...> - 2009-06-10 06:42:24
|
--- .../cilib/clustering/kmeans/KMeans.java | 5 +- .../net/sourceforge/cilib/entity/EntityType.java | 2 +- .../net/sourceforge/cilib/entity/Topology.java | 22 +++--- .../clustering/ClusteringFitnessFunction.java | 2 +- .../clustering/validityindices/TuriIndex.java | 4 +- .../single/PlotClustersAndCentroids.java | 8 +- .../problem/dataset/DynamicCirclesDataSet.java | 5 +- .../cilib/problem/dataset/DynamicDataSet.java | 2 + .../cilib/problem/dataset/LocalDataSet.java | 1 + .../ChargedSwarmInitialisationStrategy.java | 3 +- .../pso/dynamic/ChargedVelocityUpdateStrategy.java | 1 + .../pso/dynamic/DynamicIterationStrategy.java | 8 +- .../EnvironmentChangeDetectionStrategy.java | 80 ++++++++++---------- ...DataSetBasedPositionInitialisationStrategy.java | 1 + .../clustering/ClusteringFitnessFunctionTest.java | 10 +-- 15 files changed, 80 insertions(+), 74 deletions(-) diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java index c7901f4..1f1ab2f 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java @@ -60,6 +60,7 @@ import net.sourceforge.cilib.util.calculator.StructuredTypeFitnessCalculator; */ public class KMeans extends SingularAlgorithm { private static final long serialVersionUID = -3301123926538450441L; + private CentroidsInitialisationStrategy centroidsInitialisationStrategy; private CentroidsDiversificationStrategy centroidsDiversificationStrategy; private FitnessCalculator<Vector> calculator; @@ -130,11 +131,11 @@ public class KMeans extends SingularAlgorithm { if (cluster.isEmpty()) { // reinitialise the centroid if no patterns "belong" to it ArrayList<Vector> tmp = this.centroidsInitialisationStrategy.initialise(helper.getClusteringProblem(), helper.getDataSetBuilder()); - centroid = tmp.get(tmp.size() - 1); // use the last centroid that was generated; might return an unbounded Vector + centroid = tmp.get(tmp.size() - 1); // use the last centroid that was generated; might return an unbounded Vector } else { // the centroid becomes the mean of cluster i - centroid = StatUtils.meanVector(cluster.values()); // returns unbounded Vector + centroid = StatUtils.meanVector(cluster.values()); // returns unbounded Vector } // we need to set the bounds of the centroid, because some centroids might be unbounded Vectors diff --git a/src/main/java/net/sourceforge/cilib/entity/EntityType.java b/src/main/java/net/sourceforge/cilib/entity/EntityType.java index 115eeb2..e602315 100644 --- a/src/main/java/net/sourceforge/cilib/entity/EntityType.java +++ b/src/main/java/net/sourceforge/cilib/entity/EntityType.java @@ -29,7 +29,7 @@ public enum EntityType { FITNESS; /** - * {@linkplain Particle} specific constants. + * {@linkplain Particle} specific constants including a charge for ChargedPSO. */ public enum Particle { BEST_POSITION, diff --git a/src/main/java/net/sourceforge/cilib/entity/Topology.java b/src/main/java/net/sourceforge/cilib/entity/Topology.java index 5d6e853..d1c1b7a 100644 --- a/src/main/java/net/sourceforge/cilib/entity/Topology.java +++ b/src/main/java/net/sourceforge/cilib/entity/Topology.java @@ -78,17 +78,17 @@ public interface Topology<E extends Entity> */ public boolean isEmpty(); - /** - * Returns an <code>iterator</code> over all entities in the neighbourhood of the given - * {@link net.sourceforge.cilib.entity.Entity}. - * - * @param entity the {@link net.sourceforge.cilib.entity.Entity} in this - * {@link net.sourceforge.cilib.entity.Topology} whose neighbourhood is desired - * @return An iterator over all the neighbours of the given - * {@link net.sourceforge.cilib.entity.Entity} - * @author Theuns Cloete - */ - public abstract Iterator<E> neighbourhood(E entity); + /** + * Returns an <code>iterator</code> over all entities in the neighbourhood of the given + * {@link net.sourceforge.cilib.entity.Entity}. + * + * @param entity the {@link net.sourceforge.cilib.entity.Entity} in this + * {@link net.sourceforge.cilib.entity.Topology} whose neighbourhood is desired + * @return An iterator over all the neighbours of the given + * {@link net.sourceforge.cilib.entity.Entity} + * @author Theuns Cloete + */ + public abstract Iterator<E> neighbourhood(E entity); /** * Remove all the entities from the topology. diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java b/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java index 3956d34..a60d7d5 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java @@ -97,7 +97,7 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { */ @Override public double evaluate(Vector centroids) { - helper = ClusteringUtils.get(); //this statement should not be in a constructor + helper = ClusteringUtils.get(); //this statement should not be in a constructor helper.arrangeClustersAndCentroids(centroids); arrangedClusters = helper.getArrangedClusters(); arrangedCentroids = helper.getArrangedCentroids(); diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/TuriIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/TuriIndex.java index ffa0a97..e4c933d 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/TuriIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/TuriIndex.java @@ -39,8 +39,8 @@ public class TuriIndex extends ClusteringFitnessFunction { // private double gaussian = 0.0; public TuriIndex() { -// random = new RandomNumber(); -// gaussian = random.getGaussian(2, 1); +// random = new RandomNumber(); +// gaussian = random.getGaussian(2, 1); } @Override diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/PlotClustersAndCentroids.java b/src/main/java/net/sourceforge/cilib/measurement/single/PlotClustersAndCentroids.java index f55e5d9..e6e4f84 100644 --- a/src/main/java/net/sourceforge/cilib/measurement/single/PlotClustersAndCentroids.java +++ b/src/main/java/net/sourceforge/cilib/measurement/single/PlotClustersAndCentroids.java @@ -56,10 +56,10 @@ public class PlotClustersAndCentroids implements Measurement { Vector centroids = (Vector) algorithm.getBestSolution().getPosition(); helper.arrangeClustersAndCentroids(centroids); -// System.out.println("reset"); -// System.out.println("set term jpeg medium"); -// System.out.println("set output \"iteration." + String.format("%04d", Algorithm.get().getIterations()) + ".jpg\""); -// System.out.print("plot [-0.5:10][-5:5] sin(x) - 0.5, 0.5 - sin(x), "); +// System.out.println("reset"); +// System.out.println("set term jpeg medium"); +// System.out.println("set output \"iteration." + String.format("%04d", Algorithm.get().getIterations()) + ".jpg\""); +// System.out.print("plot [-0.5:10][-5:5] sin(x) - 0.5, 0.5 - sin(x), "); System.out.print("plot "); ArrayList<Hashtable<Integer, Pattern>> arrangedClusters = helper.getArrangedClusters(); diff --git a/src/main/java/net/sourceforge/cilib/problem/dataset/DynamicCirclesDataSet.java b/src/main/java/net/sourceforge/cilib/problem/dataset/DynamicCirclesDataSet.java index ea99767..a14762a 100644 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/DynamicCirclesDataSet.java +++ b/src/main/java/net/sourceforge/cilib/problem/dataset/DynamicCirclesDataSet.java @@ -31,6 +31,7 @@ import net.sourceforge.cilib.type.types.container.Vector; public class DynamicCirclesDataSet extends DynamicDataSet { private static final long serialVersionUID = -5776534228081566576L; + private ArrayList<Circle> circles = null; private ControlParameter path = null; private double amplitude = 0.0; @@ -42,8 +43,8 @@ public class DynamicCirclesDataSet extends DynamicDataSet { path = new LinearIncreasingControlParameter(); path.setParameter(0.0); -// path.setLowerBound(0.0); -// path.setUpperBound(3.0 * Math.PI); +// path.setLowerBound(0.0); +// path.setUpperBound(3.0 * Math.PI); amplitude = 0.5; } diff --git a/src/main/java/net/sourceforge/cilib/problem/dataset/DynamicDataSet.java b/src/main/java/net/sourceforge/cilib/problem/dataset/DynamicDataSet.java index b043a41..baaa467 100644 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/DynamicDataSet.java +++ b/src/main/java/net/sourceforge/cilib/problem/dataset/DynamicDataSet.java @@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory; public abstract class DynamicDataSet extends DataSet { private static final long serialVersionUID = -4632421439109672965L; private static Logger logger = LoggerFactory.getLogger(DynamicDataSet.class); + protected String dynamicIdentifier = null; protected int changeInterval = -1; @@ -66,6 +67,7 @@ public abstract class DynamicDataSet extends DataSet { * @return an {@link ArrayList} of {@link Pattern}s containing all the patterns in this * dynamic dataset */ + @Override public abstract ArrayList<Pattern> parseDataSet(); protected abstract void updateControlParameters(); diff --git a/src/main/java/net/sourceforge/cilib/problem/dataset/LocalDataSet.java b/src/main/java/net/sourceforge/cilib/problem/dataset/LocalDataSet.java index 31699a7..89705c1 100644 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/LocalDataSet.java +++ b/src/main/java/net/sourceforge/cilib/problem/dataset/LocalDataSet.java @@ -58,6 +58,7 @@ import org.slf4j.LoggerFactory; public class LocalDataSet extends DataSet { private static final long serialVersionUID = -3482617012711168661L; private static Logger logger = LoggerFactory.getLogger(LocalDataSet.class); + protected String delimiter = null; protected int beginIndex = 0; protected int endIndex = 0; diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedSwarmInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedSwarmInitialisationStrategy.java index 4399d44..9be3e76 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedSwarmInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedSwarmInitialisationStrategy.java @@ -40,13 +40,14 @@ import net.sourceforge.cilib.type.types.Real; */ public class ChargedSwarmInitialisationStrategy extends PopulationInitialisationStrategy { private static final long serialVersionUID = -652103945949329612L; + private double chargedRatio; // determines the percentage of the swarm that is to be charged private double chargeMagnitude; // charge magnitude private Particle entityType; public ChargedSwarmInitialisationStrategy() { this.entityNumber = 20; - this.chargedRatio = 0.5; // one half of the swarm is charged => Atomic swarm + this.chargedRatio = 0.5; // one half of the swarm is charged => Atomic swarm this.chargeMagnitude = 16; // the obscure value 16 comes from the article where the charged PSO was analysed for the first time by its creators this.entityType = new StandardParticle(); this.entityType.setVelocityUpdateStrategy(new ChargedVelocityUpdateStrategy()); diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedVelocityUpdateStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedVelocityUpdateStrategy.java index b9e0b1c..fcbae61 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedVelocityUpdateStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedVelocityUpdateStrategy.java @@ -47,6 +47,7 @@ import net.sourceforge.cilib.util.VectorUtils; */ public class ChargedVelocityUpdateStrategy implements VelocityUpdateStrategy { private static final long serialVersionUID = 365924556746583124L; + private VelocityUpdateStrategy velocityUpdateStrategy; private double coreRadius; // lower limit private double perceptionLimit; // upper limit diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/DynamicIterationStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/DynamicIterationStrategy.java index 2081e69..0189bd2 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/DynamicIterationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/DynamicIterationStrategy.java @@ -26,7 +26,7 @@ import net.sourceforge.cilib.algorithm.population.PopulationBasedAlgorithm; import net.sourceforge.cilib.pso.dynamic.detectionstrategies.EnvironmentChangeDetectionStrategy; import net.sourceforge.cilib.pso.dynamic.detectionstrategies.RandomSentryEntitiesDetectionStrategy; import net.sourceforge.cilib.pso.dynamic.responsestrategies.EnvironmentChangeResponseStrategy; -import net.sourceforge.cilib.pso.dynamic.responsestrategies.ReinitializationReactionStrategy; +import net.sourceforge.cilib.pso.dynamic.responsestrategies.PartialReinitialisationResponseStrategy; /** * The dynamic iteration strategy allows {@link PopulationBasedAlgorithm population based algorithms} to detect and @@ -49,16 +49,16 @@ public class DynamicIterationStrategy<E extends PopulationBasedAlgorithm> implem * Create a new instance of {@linkplain DynamicIterationStrategy}. */ public DynamicIterationStrategy() { - //this.iterationStrategy = new SynchronousIterationStrategy(); +// this.iterationStrategy = new SynchronousIterationStrategy(); this.detectionStrategy = new RandomSentryEntitiesDetectionStrategy<E>(); - this.responseStrategy = new ReinitializationReactionStrategy<E>(); + this.responseStrategy = new PartialReinitialisationResponseStrategy<E>(); } /** * Create a copy of the provided instance. * @param copy The instance to copy. */ - public DynamicIterationStrategy(DynamicIterationStrategy copy) { + public DynamicIterationStrategy(DynamicIterationStrategy<E> copy) { this.iterationStrategy = copy.iterationStrategy.getClone(); this.detectionStrategy = copy.detectionStrategy.getClone(); this.responseStrategy = copy.responseStrategy.getClone(); diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/EnvironmentChangeDetectionStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/EnvironmentChangeDetectionStrategy.java index 7a10123..7382987 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/EnvironmentChangeDetectionStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/EnvironmentChangeDetectionStrategy.java @@ -36,54 +36,54 @@ import net.sourceforge.cilib.util.Cloneable; * @author Theuns Cloete */ public abstract class EnvironmentChangeDetectionStrategy<E extends PopulationBasedAlgorithm> implements Cloneable, Serializable { - protected double epsilon = 0.0; - protected int interval = 0; + protected double epsilon = 0.0; + protected int interval = 0; - public EnvironmentChangeDetectionStrategy() { - epsilon = 0.001; - interval = 10; - } + public EnvironmentChangeDetectionStrategy() { + epsilon = 0.001; + interval = 10; + } - public EnvironmentChangeDetectionStrategy(EnvironmentChangeDetectionStrategy<E> rhs) { - epsilon = rhs.epsilon; - interval = rhs.interval; - } + public EnvironmentChangeDetectionStrategy(EnvironmentChangeDetectionStrategy<E> rhs) { + epsilon = rhs.epsilon; + interval = rhs.interval; + } - /** - * Clone the <tt>EnvironmentChangeDetectionStrategy</tt> object. - * @return A cloned <tt>EnvironmentChangeDetectionStrategy</tt> - */ - @Override - public abstract EnvironmentChangeDetectionStrategy<E> getClone(); + /** + * Clone the <tt>EnvironmentChangeDetectionStrategy</tt> object. + * @return A cloned <tt>EnvironmentChangeDetectionStrategy</tt> + */ + @Override + public abstract EnvironmentChangeDetectionStrategy<E> getClone(); - /** - * Check the environment in which the specified PSO algorithm is running for changes. - * @param algorithm The <tt>PSO</tt> that runs in a dynamic environment. - * @return true if any changes are detected, false otherwise - */ - public abstract boolean detect(E algorithm); + /** + * Check the environment in which the specified PSO algorithm is running for changes. + * @param algorithm The <tt>PSO</tt> that runs in a dynamic environment. + * @return true if any changes are detected, false otherwise + */ + public abstract boolean detect(E algorithm); - public void setEpsilon(double e) { - if (e < 0.0) { - throw new IllegalArgumentException("The epsilon value cannot be negative"); - } + public void setEpsilon(double e) { + if (e < 0.0) { + throw new IllegalArgumentException("The epsilon value cannot be negative"); + } - epsilon = e; - } + epsilon = e; + } - public double getEpsilon() { - return epsilon; - } + public double getEpsilon() { + return epsilon; + } - public void setIterationsModulus(int im) { - if (im <= 0) { - throw new IllegalArgumentException("The number of consecutive iterations to pass cannot be <= 0"); - } + public void setIterationsModulus(int im) { + if (im <= 0) { + throw new IllegalArgumentException("The number of consecutive iterations to pass cannot be <= 0"); + } - interval = im; - } + interval = im; + } - public int getIterationsModulus() { - return interval; - } + public int getIterationsModulus() { + return interval; + } } diff --git a/src/main/java/net/sourceforge/cilib/pso/particle/initialisation/DataSetBasedPositionInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/pso/particle/initialisation/DataSetBasedPositionInitialisationStrategy.java index beadb19..d010821 100644 --- a/src/main/java/net/sourceforge/cilib/pso/particle/initialisation/DataSetBasedPositionInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/particle/initialisation/DataSetBasedPositionInitialisationStrategy.java @@ -41,6 +41,7 @@ import net.sourceforge.cilib.util.ClusteringUtils; */ public class DataSetBasedPositionInitialisationStrategy implements PositionInitialisationStrategy { private static final long serialVersionUID = 1341622520702058537L; + private CentroidsInitialisationStrategy centroidsInitialisationStrategy; public DataSetBasedPositionInitialisationStrategy() { diff --git a/src/test/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunctionTest.java b/src/test/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunctionTest.java index 93561db..312f63f 100644 --- a/src/test/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunctionTest.java +++ b/src/test/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunctionTest.java @@ -4,22 +4,21 @@ * Department of Computer Science * University of Pretoria * South Africa - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program 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 General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - package net.sourceforge.cilib.functions.clustering; import static org.junit.Assert.assertEquals; @@ -72,8 +71,7 @@ public class ClusteringFitnessFunctionTest { centroids.append(new Int(5)); centroids.append(new Int(50)); } - - + @AfterClass public static void destroy() { function = null; -- 1.6.0.6 |
From: Theuns C. <the...@gm...> - 2009-06-10 06:42:17
|
A CentroidsDiversificationStrategy allows the KMeans algorithm to add diversity to the centroids once it has been detected that it stagnated. The NullCentroidsDiversificationStrategy is the default and does not add any diversity, i.e. adhering to the standard KMeans algorithm. The StandardCentroidsDiversificationStrategy takes the 'interval' and 'diversifyRatio' as parameters. In other words, diversity is added to the specific centroid only when 'interval' iterations have passed without any change occuring for that centroid. The diversity that is added is achieved by the VectorUtils.jitter() method. Extra helper methods were added in ClusteringUtils to assemble and disassemble centroids. Extra methods were added in VectorUtils to add noise (jitter) to a vector as well as set new bounds for a vector. A scale() method was implemented in MathUtil, but as I continued development I realised that it isn't really necessary for what I am doing. Nonetheless, it is still a valid addition. I also added the PlotClustersAndCentroids measurement that is useful when debugging 2D clusterings using GNUplot. It can also serve as an example for other people to see how to use GNUplot as debugging tool in CIlib. JavaDoc comments were added and modified to explain each addition and modification respectively. --- .../kmeans/CentroidsDiversificationStrategy.java | 56 ++++++++ .../kmeans/CentroidsInitialisationStrategy.java | 20 ++-- ...ataSetBasedCentroidsInitialisationStrategy.java | 25 ++-- .../cilib/clustering/kmeans/KMeans.java | 125 +++++++++-------- ...ansPlusPlusCentroidsInitialisationStrategy.java | 114 ++++++++++++++++ .../NullCentroidsDiversificationStrategy.java | 55 ++++++++ .../RandomCentroidsInitialisationStrategy.java | 17 ++- .../StandardCentroidsDiversificationStrategy.java | 144 ++++++++++++++++++++ .../java/net/sourceforge/cilib/math/MathUtil.java | 4 + .../measurement/single/NumberOfClustersFormed.java | 48 +------ .../single/PlotClustersAndCentroids.java | 92 +++++++++++++ ...DataSetBasedPositionInitialisationStrategy.java | 19 ++- .../sourceforge/cilib/util/ClusteringUtils.java | 19 +++ .../net/sourceforge/cilib/util/VectorUtils.java | 46 ++++++- 14 files changed, 639 insertions(+), 145 deletions(-) create mode 100644 src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsDiversificationStrategy.java create mode 100644 src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeansPlusPlusCentroidsInitialisationStrategy.java create mode 100644 src/main/java/net/sourceforge/cilib/clustering/kmeans/NullCentroidsDiversificationStrategy.java create mode 100644 src/main/java/net/sourceforge/cilib/clustering/kmeans/StandardCentroidsDiversificationStrategy.java create mode 100644 src/main/java/net/sourceforge/cilib/measurement/single/PlotClustersAndCentroids.java diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsDiversificationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsDiversificationStrategy.java new file mode 100644 index 0000000..ca7554b --- /dev/null +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsDiversificationStrategy.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2003 - 2008 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package net.sourceforge.cilib.clustering.kmeans; + +import java.io.Serializable; +import java.util.ArrayList; +import net.sourceforge.cilib.type.types.container.Vector; +import net.sourceforge.cilib.util.Cloneable; + +/** + * Monitor centroids for moments of stagnation and add diversity as and when desired. + * + * @author theuns.cloete + */ +public interface CentroidsDiversificationStrategy extends Serializable, Cloneable { + /** + * {@inheritDoc} + */ + @Override + public CentroidsDiversificationStrategy getClone(); + + /** + * Initialise this centroids diversification strategy based on the given {@link ArrayList} of centroid + * {@link Vector}s. + * + * @param centroids The {@link ArrayList} containing all the centroids. + */ + public void initialise(ArrayList<Vector> centroids); + + /** + * Diversify the specified centroid in the given list of centroids. Note that a diversification will only happen + * based on the rules implemented in the classes that override this method. + * @param centroids The {@link ArrayList} containing all the centroids. + * @param which Which centroid (of the given centroids) should be diversified? + */ + public void diversify(ArrayList<Vector> centroids, int which); +} diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsInitialisationStrategy.java index 5a9fa3d..22a203e 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsInitialisationStrategy.java @@ -23,6 +23,7 @@ package net.sourceforge.cilib.clustering.kmeans; import java.io.Serializable; +import java.util.ArrayList; import net.sourceforge.cilib.problem.ClusteringProblem; import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; import net.sourceforge.cilib.type.types.container.Vector; @@ -30,27 +31,28 @@ import net.sourceforge.cilib.util.Cloneable; /** * This strategy allows for different ways of initializing the centroids of a clustering. - * The two main approaches are either: + * The following approaches have already been implemented: * <ul> * <li>Randomly ({@link RandomCentroidsInitialisationStrategy}); or</li> * <li>Based on random patterns chosen from the dataset ({@link DataSetBasedCentroidsInitialisationStrategy})</li> + * <li>Based on the potential that each centroid contributes ({@link KMeansPlusPlusCentroidsInitialisationStrategy})</li> * </ul> * * @author Theuns Cloete */ public interface CentroidsInitialisationStrategy extends Serializable, Cloneable { + @Override + public CentroidsInitialisationStrategy getClone(); /** - * Initialize the centroid vectors for a clustering. Each centroid is appended to a - * {@link Vector} that represents all the centroids. This {@link Vector} is then - * returned. The problem and/or dataset that are currently being clustered can be used to - * get information about the clustering, such as the dimension of the search space and - * centroids. + * Initialize the centroid vectors for a clustering. Each centroid is individually initialised and then added to an + * {@link ArrayList} that represents all the centroids. This structure is then returned. The problem and/or dataset + * that are currently being clustered can be used to get information about the clustering, such as the dimension of + * the search space and centroids. * * @param problem the {@link ClusteringProblem} currently being optimized * @param dataset the {@link StaticDataSetBuilder} currently being clustered - * @return a {@link Vector} that represents all the centroids + * @return an {@link ArrayList} of {@link Vector}s that represent all the centroids */ - public Vector initialise(ClusteringProblem problem, StaticDataSetBuilder dataset); - + public ArrayList<Vector> initialise(ClusteringProblem problem, StaticDataSetBuilder dataset); } diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java index ef8b1d7..e15ace7 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java @@ -39,15 +39,6 @@ import net.sourceforge.cilib.type.types.container.Vector; public class DataSetBasedCentroidsInitialisationStrategy implements CentroidsInitialisationStrategy { private static final long serialVersionUID = -3016201656688883387L; - private Random random = null; - - /** - * Create a new instance of {@linkplain DataSetBasedCentroidsInitialisationStrategy}. - */ - public DataSetBasedCentroidsInitialisationStrategy() { - random = new MersenneTwister(); - } - /** * {@inheritDoc} */ @@ -62,17 +53,19 @@ public class DataSetBasedCentroidsInitialisationStrategy implements CentroidsIni * * @param problem the {@link ClusteringProblem} currently being optimized * @param dataset the {@link StaticDataSetBuilder} currently being clustered - * @return a {@link Vector} that represents all the centroids + * @return an {@link ArrayList} of {@link Vector}s that represents all the centroids */ @Override - public Vector initialise(ClusteringProblem problem, StaticDataSetBuilder dataset) { - ArrayList<Pattern> patterns = dataset.getPatterns(); + public ArrayList<Vector> initialise(ClusteringProblem problem, StaticDataSetBuilder dataset) { int numberOfCentroids = problem.getNumberOfClusters(); - Vector centroids = new Vector(problem.getDomain().getDimension()); + ArrayList<Vector> centroids = new ArrayList<Vector>(numberOfCentroids); + ArrayList<Pattern> patterns = dataset.getPatterns(); + Random random = new MersenneTwister(); + + for (int i = 0; i < numberOfCentroids; ++i) { + Vector centroid = patterns.get(Math.round(random.nextInt(patterns.size()))).data.getClone(); - for (int i = 0; i < numberOfCentroids; i++) { - Vector centroid = patterns.get((int) Math.round(random.nextInt(patterns.size()))).data; - centroids.append(centroid.getClone()); + centroids.add(centroid); } return centroids; } diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java index 62d532f..c7901f4 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java @@ -33,6 +33,7 @@ import net.sourceforge.cilib.problem.OptimisationSolution; import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.ClusteringUtils; +import net.sourceforge.cilib.util.VectorUtils; import net.sourceforge.cilib.util.calculator.FitnessCalculator; import net.sourceforge.cilib.util.calculator.StructuredTypeFitnessCalculator; @@ -49,35 +50,45 @@ import net.sourceforge.cilib.util.calculator.StructuredTypeFitnessCalculator; * address = "Calcutta, India"} * * This class makes use of a {@link CentroidsInitialisationStrategy} to initialise the - * centroids in the desired manner. The default centroid initialisation strategy is the - * {@link RandomCentroidsInitialisationStrategy}. + * centroids in the desired manner. The default centroids initialisation strategy is the + * {@link RandomCentroidsInitialisationStrategy}. It also makes use of a {@link CentroidsDiversificationStrategy} to add + * diversity at certain moments defined by the strategy. The default centroids diversification strategy is the + * {@link NullCentroidsDiversificationStrategy} which does not add any diversity, i.e. adhering to the normal KMeans + * algorithm. * * @author Theuns Cloete - * @TODO: Check that removing the FitnessCalculator does not break the functionality of this class. */ public class KMeans extends SingularAlgorithm { private static final long serialVersionUID = -3301123926538450441L; - - private CentroidsInitialisationStrategy centroidsInitialisationStrategy = null; - private Vector centroids = null; + private CentroidsInitialisationStrategy centroidsInitialisationStrategy; + private CentroidsDiversificationStrategy centroidsDiversificationStrategy; private FitnessCalculator<Vector> calculator; + private ArrayList<Vector> centroids; /** * Create an instance of {@linkplain KMeans}. */ public KMeans() { - calculator = new StructuredTypeFitnessCalculator<Vector>(); - centroidsInitialisationStrategy = new RandomCentroidsInitialisationStrategy(); + this.centroidsInitialisationStrategy = new RandomCentroidsInitialisationStrategy(); + this.centroidsDiversificationStrategy = new NullCentroidsDiversificationStrategy(); + this.calculator = new StructuredTypeFitnessCalculator<Vector>(); } /** * Create a copy of the provided instance. * @param rhs The instance to copy. */ - public KMeans(KMeans copy) { - super(copy); - centroids = copy.centroids.getClone(); - calculator = copy.calculator.getClone(); + public KMeans(KMeans rhs) { + super(rhs); + this.centroidsInitialisationStrategy = rhs.centroidsInitialisationStrategy.getClone(); + this.centroidsDiversificationStrategy = rhs.centroidsDiversificationStrategy.getClone(); + + this.calculator = rhs.calculator.getClone(); + + this.centroids = new ArrayList<Vector>(); + for (Vector centroid : rhs.centroids) { + this.centroids.add(centroid.getClone()); + } } /** @@ -96,7 +107,8 @@ public class KMeans extends SingularAlgorithm { public void performInitialisation() { ClusteringUtils helper = ClusteringUtils.get(); - centroids = centroidsInitialisationStrategy.initialise(helper.getClusteringProblem(), helper.getDataSetBuilder()); + this.centroids = this.centroidsInitialisationStrategy.initialise(helper.getClusteringProblem(), helper.getDataSetBuilder()); + this.centroidsDiversificationStrategy.initialise(this.centroids); } /** @@ -104,65 +116,44 @@ public class KMeans extends SingularAlgorithm { */ @Override public void algorithmIteration() { - calculator.getFitness(centroids, true); + calculator.getFitness(ClusteringUtils.assembleCentroids(this.centroids), true); - // the fitness calculation step already arranged the clusters and centroids for us + // the fitness calculation step already arranged the clusters and centroids with the help of ClusteringUtils ClusteringUtils helper = ClusteringUtils.get(); ArrayList<Hashtable<Integer, Pattern>> clusters = helper.getOriginalClusters(); for (int i = 0; i < clusters.size(); i++) { Hashtable<Integer, Pattern> cluster = clusters.get(i); - // get the i'th centroid; only used to determine the dimension of a single centroid - Vector centroid = helper.getOriginalCentroids().get(i); + Vector centroid = null; - // TODO: I don't know if this is part of the original KMeans algorithm - if (cluster.isEmpty()) { // reinitialise the centroid if no patterns "belong" to it - centroid = reinitialiseCentroid(centroid); + // TODO: I don't know if this if-else is part of the original KMeans algorithm + if (cluster.isEmpty()) { + // reinitialise the centroid if no patterns "belong" to it + ArrayList<Vector> tmp = this.centroidsInitialisationStrategy.initialise(helper.getClusteringProblem(), helper.getDataSetBuilder()); + centroid = tmp.get(tmp.size() - 1); // use the last centroid that was generated; might return an unbounded Vector } - else { // the centroid becomes the mean of cluster i - centroid = StatUtils.meanVector(cluster.values()); + else { + // the centroid becomes the mean of cluster i + centroid = StatUtils.meanVector(cluster.values()); // returns unbounded Vector } - updateCentroid(centroid, i); - } - } - /** - * Update the correct centroid inside the {@link #centroids} {@link Vector} with the - * contents of the new provided position. - * @param newPosition a {@link Vector} representing the new position of the centroid - * @param cluster the cluster number that is used to determine the correct position in - * the {@link #centroids} {@link Vector} - */ - private void updateCentroid(Vector newPosition, int cluster) { - int dimension = newPosition.getDimension(); + // we need to set the bounds of the centroid, because some centroids might be unbounded Vectors + Vector builtRepresentation = (Vector) helper.getClusteringProblem().getBehaviouralDomain().getBuiltRepresenation(); - for (int i = 0; i < dimension; i++) { - centroids.set(cluster * dimension + i, newPosition.get(i)); + centroid = VectorUtils.setBounds(centroid, VectorUtils.createLowerBoundVector(builtRepresentation), VectorUtils.createUpperBoundVector(builtRepresentation)); + this.centroids.set(i, centroid); + this.centroidsDiversificationStrategy.diversify(centroids, i); } } /** - * Reinitialise the centroid based on the chosen {@link CentroidsInitialisationStrategy}. - * The {@link CentroidsInitialisationStrategy} returns an entire centroids {@link Vector}, - * but we only need a single centroid. The given parameter is only used to determine the - * size of a single centroid. - * @param centroid the centroid that should be reinitialised - * @return a {@link Vector} representing a new (reinitialised) centroid - */ - private Vector reinitialiseCentroid(Vector centroid) { - ClusteringUtils helper = ClusteringUtils.get(); - Vector tmp = centroidsInitialisationStrategy.initialise(helper.getClusteringProblem(), helper.getDataSetBuilder()); - - // this first centroid will do - return tmp.subList(0, centroid.getDimension() - 1); - } - - /** * {@inheritDoc} */ @Override public OptimisationSolution getBestSolution() { - return new OptimisationSolution(centroids.getClone(), getOptimisationProblem().getFitness(centroids, false)); + Vector assembled = ClusteringUtils.assembleCentroids(centroids); + + return new OptimisationSolution(assembled, this.getOptimisationProblem().getFitness(assembled, false)); } /** @@ -174,18 +165,34 @@ public class KMeans extends SingularAlgorithm { } /** - * Get the centroid initialisation strategy. + * Get the current centroids initialisation strategy. * @return The current {@linkplain CentroidsInitialisationStrategy}. */ public CentroidsInitialisationStrategy getCentroidsInitialisationStrategy() { - return centroidsInitialisationStrategy; + return this.centroidsInitialisationStrategy; + } + + /** + * Set the current centroids initialisation strategy. + * @param cis The {@linkplain CentroidsInitialisationStrategy} to use. + */ + public void setCentroidsInitialisationStrategy(CentroidsInitialisationStrategy cis) { + this.centroidsInitialisationStrategy = cis; + } + + /** + * Get the current centroids diversification strategy. + * @return The current {@linkplain CentroidsInitialisationStrategy}. + */ + public CentroidsDiversificationStrategy getCentroidsDiversificationStrategy() { + return this.centroidsDiversificationStrategy; } /** - * Set the current {@linkplain CentroidsInitialisationStrategy}. - * @param centroidsInitialisationStrategy The value to set. + * Set the current centroids diversification strategy. + * @param cds The {@link CentroidsDiversificationStrategy} to use. */ - public void setCentroidsInitialisationStrategy(CentroidsInitialisationStrategy centroidsInitialisationStrategy) { - this.centroidsInitialisationStrategy = centroidsInitialisationStrategy; + public void setCentroidsDiversificationStrategy(CentroidsDiversificationStrategy cds) { + this.centroidsDiversificationStrategy = cds; } } diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeansPlusPlusCentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeansPlusPlusCentroidsInitialisationStrategy.java new file mode 100644 index 0000000..c8b1e43 --- /dev/null +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeansPlusPlusCentroidsInitialisationStrategy.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2003 - 2008 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package net.sourceforge.cilib.clustering.kmeans; + +import java.util.ArrayList; +import net.sourceforge.cilib.math.random.generator.MersenneTwister; +import net.sourceforge.cilib.math.random.generator.Random; +import net.sourceforge.cilib.problem.ClusteringProblem; +import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; +import net.sourceforge.cilib.type.types.container.Vector; +import net.sourceforge.cilib.util.DistanceMeasure; + +/** + * Initialises each centroid with probability proportional to its contribution to the overall potential. + * Note that no parameter tuning is needed. + * + * @InProceedings{ 2007.Arthur.jan, title = "k-means++: The Advantages of Careful Seeding", + * booktitle = "In Proceedings of the eighteenth annual ACM-SIAM symposium on Discrete Algorithms", + * series = "Symposium on Discrete Algorithms", author = "David Arthur and Sergei Vassilvitskii", + * publisher = "Society for Industrial and Applied Mathematics", location = "New Orleans, Louisiana", + * address = "Philadelphia, PA, USA", pages = "1027--1035", month = jan, year = "2007", + * isbn = "978-0-898716-24-5"} + * + * @author Theuns Cloete + */ +public class KMeansPlusPlusCentroidsInitialisationStrategy implements CentroidsInitialisationStrategy { + private ArrayList<Pattern> patterns; + private DistanceMeasure distanceMeasure; + private ArrayList<Vector> chosenCentroids; + + public KMeansPlusPlusCentroidsInitialisationStrategy() { + patterns = null; + distanceMeasure = null; + chosenCentroids = null; + } + + /** + * {@inheritDoc} + */ + @Override + public KMeansPlusPlusCentroidsInitialisationStrategy getClone() { + return new KMeansPlusPlusCentroidsInitialisationStrategy(); + } + + /** + * Initialise the centroids as explained in Section 2.2 of the referenced article. + * {@inheritDoc} + */ + @Override + public ArrayList<Vector> initialise(ClusteringProblem problem, StaticDataSetBuilder dataset) { + Random randomPattern = new MersenneTwister(); + Random randomProbability = new MersenneTwister(); + int numberOfClusters = problem.getNumberOfClusters(); + int centroidsChosen = 0; + + this.patterns = dataset.getPatterns(); + this.distanceMeasure = problem.getDistanceMeasure(); + this.chosenCentroids = new ArrayList<Vector>(); + + while (centroidsChosen < numberOfClusters) { + Vector candidateCentroid = patterns.get(Math.round(randomPattern.nextInt(patterns.size()))).data.getClone(); + + if (centroidsChosen > 0) { + double probability = calculateProbability(candidateCentroid); + + if (randomProbability.nextDouble() >= probability) { + continue; + } + } + this.chosenCentroids.add(candidateCentroid); + ++centroidsChosen; + } + return this.chosenCentroids; + } + + private double calculateProbability(Vector candidateCentroid) { + double probability = 0.0; + double numerator = Double.MAX_VALUE; + + for (Vector chosenCentroid : chosenCentroids) { + numerator = Math.min(numerator, this.distanceMeasure.distance(candidateCentroid, chosenCentroid)); + } + + for (Pattern pattern : this.patterns) { + double denominator = Double.MAX_VALUE; + + for (Vector chosenCentroid : chosenCentroids) { + denominator = Math.min(denominator, this.distanceMeasure.distance(chosenCentroid, pattern.data)); + } + probability += denominator; + } + return numerator / probability; + } +} diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/NullCentroidsDiversificationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/NullCentroidsDiversificationStrategy.java new file mode 100644 index 0000000..3aa0981 --- /dev/null +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/NullCentroidsDiversificationStrategy.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2003 - 2008 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package net.sourceforge.cilib.clustering.kmeans; + +import java.util.ArrayList; +import net.sourceforge.cilib.type.types.container.Vector; + +/** + * This strategy is needed so that {@link KMeans} can behave as defined in the original article. + * All the methods are empty, because nothing needs to be done. + * + * @author Theuns Cloete + */ +public class NullCentroidsDiversificationStrategy implements CentroidsDiversificationStrategy { + /** + * {@inheritDoc} + */ + @Override + public CentroidsDiversificationStrategy getClone() { + return this; + } + + /** + * No initialisation is needed, because nothing needs to be done. This is an empty method. + */ + @Override + public void initialise(ArrayList<Vector> centroids) { + } + + /** + * No diversification is needed, because nothing needs to be done. This is an empty method. + */ + @Override + public void diversify(ArrayList<Vector> centroids, int which) { + } +} diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/RandomCentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/RandomCentroidsInitialisationStrategy.java index 8cf1292..d2abd86 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/RandomCentroidsInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/RandomCentroidsInitialisationStrategy.java @@ -21,6 +21,7 @@ */ package net.sourceforge.cilib.clustering.kmeans; +import java.util.ArrayList; import net.sourceforge.cilib.problem.ClusteringProblem; import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; import net.sourceforge.cilib.type.types.container.Vector; @@ -44,18 +45,24 @@ public class RandomCentroidsInitialisationStrategy implements CentroidsInitialis /** * Initialize the centroid vectors for a clustering to random positions in the search - * space. The built-representation of the domain of the given problem is used to build a + * space. The built-representation of the behavioural domain of the given {@link ClusteringProblem} is used to build a * {@link Vector} that will house the centroids. * * @param problem the {@link ClusteringProblem} currently being optimized * @param dataset the {@link StaticDataSetBuilder} currently being clustered - * @return a {@link Vector} that represents all the centroids + * @return an {@link ArrayList} of {@link Vector}s that represents all the centroids */ @Override - public Vector initialise(ClusteringProblem problem, StaticDataSetBuilder dataset) { - Vector centroids = (Vector) problem.getDomain().getBuiltRepresenation().getClone(); + public ArrayList<Vector> initialise(ClusteringProblem problem, StaticDataSetBuilder dataset) { + int numberOfCentroids = problem.getNumberOfClusters(); + ArrayList<Vector> centroids = new ArrayList<Vector>(numberOfCentroids); - centroids.randomize(); + for (int i = 0; i < numberOfCentroids; ++i) { + Vector centroid = (Vector) problem.getBehaviouralDomain().getBuiltRepresenation().getClone(); + + centroid.randomize(); + centroids.add(centroid); + } return centroids; } } diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/StandardCentroidsDiversificationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/StandardCentroidsDiversificationStrategy.java new file mode 100644 index 0000000..0d75c23 --- /dev/null +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/StandardCentroidsDiversificationStrategy.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2003 - 2008 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package net.sourceforge.cilib.clustering.kmeans; + +import java.util.ArrayList; +import java.util.Collections; +import net.sourceforge.cilib.type.types.container.Vector; +import net.sourceforge.cilib.util.VectorUtils; + +/** + * Monitor the {@link #previousCentroids centroids} for moments of stagnation and add diversity + * ({@link VectorUtils#jitter(vector, ratio) jitter}) to each individual centroid when the specific centroid has not + * changed for {@link #interval} number of iterations. The amount of diversity added is + * calculated by the {@link VectorUtils#jitter(net.sourceforge.cilib.type.types.container.Vector, double)} method. + * + * @author theuns.cloete + */ +public class StandardCentroidsDiversificationStrategy implements CentroidsDiversificationStrategy { + private ArrayList<Vector> previousCentroids; + private ArrayList<Integer> unchangedIterations; + private double diversifyRatio; + private int interval; + + /** + * Construct the diversification strategy. The default {@link #diversifyRatio} is 0.1 and the default + * {@link #interval} is 10 iterations. + */ + public StandardCentroidsDiversificationStrategy() { + this.diversifyRatio = 0.1; + this.interval = 10; + } + + public StandardCentroidsDiversificationStrategy(StandardCentroidsDiversificationStrategy rhs) { + this.previousCentroids = new ArrayList<Vector>(); + + for (Vector previousCentroid : rhs.previousCentroids) { + this.previousCentroids.add(previousCentroid.getClone()); + } + + this.unchangedIterations = new ArrayList<Integer>(); + this.unchangedIterations.addAll(rhs.unchangedIterations); + this.diversifyRatio = rhs.diversifyRatio; + this.interval = rhs.interval; + } + + /** + * {@inheritDoc} + */ + @Override + public StandardCentroidsDiversificationStrategy getClone() { + return new StandardCentroidsDiversificationStrategy(this); + } + + /** + * {@inheritDoc} + */ + @Override + public void initialise(ArrayList<Vector> centroids) { + this.previousCentroids = new ArrayList<Vector>(centroids.size()); + + for (Vector centroid : centroids) { + this.previousCentroids.add(centroid.getClone()); + } + + this.unchangedIterations = new ArrayList<Integer>(centroids.size()); + this.unchangedIterations.addAll(Collections.nCopies(centroids.size(), 0)); + } + + /** + * {@inheritDoc} + */ + @Override + public void diversify(ArrayList<Vector> currentCentroids, int which) { + Vector currentCentroid = currentCentroids.get(which); + Vector previousCentroid = this.previousCentroids.get(which); + int unchanged = this.unchangedIterations.get(which); + + if (currentCentroid.equals(previousCentroid)) { + this.unchangedIterations.set(which, ++unchanged); + } + else { + this.previousCentroids.set(which, currentCentroid.getClone()); + this.unchangedIterations.set(which, 0); + } + + if (unchanged >= this.interval) { + currentCentroid = VectorUtils.jitter(currentCentroid, this.diversifyRatio); + currentCentroids.set(which, currentCentroid); + this.previousCentroids.set(which, currentCentroid.getClone()); + this.unchangedIterations.set(which, 0); + } + } + + /** + * Get the current diversify ratio. + * @return The current {@link #diversifyRatio}. + */ + public double getDiversifyRatio() { + return this.diversifyRatio; + } + + /** + * Set the current diversify ratio. + * @param dr The {@link #diversifyRatio} to use. + */ + public void setDiversifyRatio(double dr) { + this.diversifyRatio = dr; + } + + /** + * Get the current interval. + * @return The current {@link #interval}. + */ + public int getInterval() { + return this.interval; + } + + /** + * Set the current interval. + * @param i The {@link #interval} to use. + */ + public void setInterval(int i) { + this.interval = i; + } +} diff --git a/src/main/java/net/sourceforge/cilib/math/MathUtil.java b/src/main/java/net/sourceforge/cilib/math/MathUtil.java index 71a9216..8e08c1e 100644 --- a/src/main/java/net/sourceforge/cilib/math/MathUtil.java +++ b/src/main/java/net/sourceforge/cilib/math/MathUtil.java @@ -125,6 +125,10 @@ public final class MathUtil { return 0; } + public static double scale(double value, double fromMin, double fromMax, double toMin, double toMax) { + return toMin + (value / ((fromMax - fromMin) / (toMax - toMin))); + } + /** * Determine the log of the specified <code>value</code> with the provided <code>base</code>. * @param base The base of the log operation. diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java b/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java index 480758e..2cbd70e 100644 --- a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java +++ b/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java @@ -21,13 +21,9 @@ */ package net.sourceforge.cilib.measurement.single; -import java.util.ArrayList; -import java.util.Hashtable; - import net.sourceforge.cilib.algorithm.Algorithm; import net.sourceforge.cilib.measurement.Measurement; import net.sourceforge.cilib.problem.dataset.DataSetBuilder; -import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; import net.sourceforge.cilib.type.types.Int; import net.sourceforge.cilib.type.types.Type; @@ -52,15 +48,9 @@ import net.sourceforge.cilib.util.ClusteringUtils; public class NumberOfClustersFormed implements Measurement { private static final long serialVersionUID = 2174807313995885918L; - public NumberOfClustersFormed() { - } - - public NumberOfClustersFormed(NumberOfClustersFormed rhs) { - } - @Override public NumberOfClustersFormed getClone() { - return new NumberOfClustersFormed(this); + return this; } @Override @@ -72,42 +62,8 @@ public class NumberOfClustersFormed implements Measurement { public Type getValue(Algorithm algorithm) { ClusteringUtils helper = ClusteringUtils.get(); Vector centroids = (Vector) algorithm.getBestSolution().getPosition(); + helper.arrangeClustersAndCentroids(centroids); -// plotClustersAndCentroids(); return new Int(helper.getArrangedCentroids().size()); } - - private void plotClustersAndCentroids() { -// System.out.println("reset"); -// System.out.println("set term jpeg medium"); -// System.out.println("set output \"iteration." + String.format("%04d", Algorithm.get().getIterations()) + ".jpg\""); -// System.out.print("plot [-0.5:10][-5:5] sin(x) - 0.5, 0.5 - sin(x), "); - System.out.print("plot "); - - ArrayList<Hashtable<Integer, Pattern>> arrangedClusters = ClusteringUtils.get().getArrangedClusters(); - ArrayList<Vector> arrangedCentroids = ClusteringUtils.get().getArrangedCentroids(); - for (int i = 0; i < arrangedClusters.size(); ++i) { - System.out.print("'-' title 'cluster" + i + "', "); - } - - for (int i = 0; i < arrangedCentroids.size(); ++i) { - System.out.print("'-' title 'centroid" + i + "'"); - if (i < arrangedCentroids.size() - 1) { - System.out.print(", "); - } - } - System.out.println(); - - for (Hashtable<Integer, Pattern> cluster : arrangedClusters) { - for (Pattern pattern : cluster.values()) { - System.out.println(pattern); - } - System.out.println('e'); - } - - for (Vector centroid : arrangedCentroids) { - System.out.println(centroid.toString('\0', '\0', '\t')); - System.out.println('e'); - } - } } diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/PlotClustersAndCentroids.java b/src/main/java/net/sourceforge/cilib/measurement/single/PlotClustersAndCentroids.java new file mode 100644 index 0000000..f55e5d9 --- /dev/null +++ b/src/main/java/net/sourceforge/cilib/measurement/single/PlotClustersAndCentroids.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2003 - 2008 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package net.sourceforge.cilib.measurement.single; + +import java.util.ArrayList; +import java.util.Hashtable; +import net.sourceforge.cilib.algorithm.Algorithm; +import net.sourceforge.cilib.measurement.Measurement; +import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.type.types.Int; +import net.sourceforge.cilib.type.types.Type; +import net.sourceforge.cilib.type.types.container.Vector; +import net.sourceforge.cilib.util.ClusteringUtils; + +/** + * This measurement is handy when debugging a clustering in R^2 space using GNUplot. Logging should be disabled and no + * other output should be written to standard out. To try it, start GNUplot, execute:<br/> + * load "<./simulator.sh path/to/your/cilib.config.file.xml"<br/> + * and enjoy. + * + * @author theuns.cloete + */ +public class PlotClustersAndCentroids implements Measurement { + @Override + public Measurement getClone() { + return this; + } + + @Override + public String getDomain() { + return "Z"; + } + + @Override + public Type getValue(Algorithm algorithm) { + ClusteringUtils helper = ClusteringUtils.get(); + Vector centroids = (Vector) algorithm.getBestSolution().getPosition(); + helper.arrangeClustersAndCentroids(centroids); + +// System.out.println("reset"); +// System.out.println("set term jpeg medium"); +// System.out.println("set output \"iteration." + String.format("%04d", Algorithm.get().getIterations()) + ".jpg\""); +// System.out.print("plot [-0.5:10][-5:5] sin(x) - 0.5, 0.5 - sin(x), "); + System.out.print("plot "); + + ArrayList<Hashtable<Integer, Pattern>> arrangedClusters = helper.getArrangedClusters(); + ArrayList<Vector> arrangedCentroids = helper.getArrangedCentroids(); + for (int i = 0; i < arrangedClusters.size(); ++i) { + System.out.print("'-' title 'cluster" + i + "', "); + } + + for (int i = 0; i < arrangedCentroids.size(); ++i) { + System.out.print("'-' title 'centroid" + i + "'"); + if (i < arrangedCentroids.size() - 1) { + System.out.print(", "); + } + } + System.out.println(); + + for (Hashtable<Integer, Pattern> cluster : arrangedClusters) { + for (Pattern pattern : cluster.values()) { + System.out.println(pattern); + } + System.out.println('e'); + } + + for (Vector centroid : arrangedCentroids) { + System.out.println(centroid.toString('\0', '\0', '\t')); + System.out.println('e'); + } + return new Int(0, 0); + } +} diff --git a/src/main/java/net/sourceforge/cilib/pso/particle/initialisation/DataSetBasedPositionInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/pso/particle/initialisation/DataSetBasedPositionInitialisationStrategy.java index b8690ec..beadb19 100644 --- a/src/main/java/net/sourceforge/cilib/pso/particle/initialisation/DataSetBasedPositionInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/particle/initialisation/DataSetBasedPositionInitialisationStrategy.java @@ -26,23 +26,22 @@ import net.sourceforge.cilib.clustering.kmeans.DataSetBasedCentroidsInitialisati import net.sourceforge.cilib.entity.EntityType; import net.sourceforge.cilib.entity.Particle; import net.sourceforge.cilib.problem.OptimisationProblem; +import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.ClusteringUtils; /** * This strategy initializes the position as well as the best position of a {@link Particle} - * using the {@link DataSetBasedCentroidsInitialisationStrategy}. The particle is therefore - * initialized from the current dataset. The {@link ClusterableDataSet dataset} is found + * using the selected {@link CentroidsInitialisationStrategy}. The default is the {@link DataSetBasedCentroidsInitialisationStrategy}. + * The particle is therefore initialized from the current dataset. The {@link StaticDataSetBuilder dataset} is found * using the {@link ClusteringUtils#getDataSetBuilder()} method. The - * {@link ClusteringProblem} is also found using the - * {@link ClusteringUtils#getClusteringProblem()} method. + * {@link ClusteringProblem} is also found using the {@link ClusteringUtils#getClusteringProblem()} method. * * @author Theuns Cloete */ public class DataSetBasedPositionInitialisationStrategy implements PositionInitialisationStrategy { private static final long serialVersionUID = 1341622520702058537L; - - private CentroidsInitialisationStrategy centroidsInitialisationStrategy = null; + private CentroidsInitialisationStrategy centroidsInitialisationStrategy; public DataSetBasedPositionInitialisationStrategy() { centroidsInitialisationStrategy = new DataSetBasedCentroidsInitialisationStrategy(); @@ -55,7 +54,7 @@ public class DataSetBasedPositionInitialisationStrategy implements PositionIniti /** * Initialize the position and best position of the given {@link Particle} from the - * current dataset using the {@link DataSetBasedCentroidsInitialisationStrategy}. + * current dataset using the selected {@link CentroidsInitialisationStrategy}. * * @param particle the {@link Particle} that should be initialized * @param problem the {@link OptimisationProblem} that is currently being optimized. This @@ -65,9 +64,13 @@ public class DataSetBasedPositionInitialisationStrategy implements PositionIniti @Override public void initialise(Particle particle, OptimisationProblem problem) { ClusteringUtils helper = ClusteringUtils.get(); - Vector centroids = centroidsInitialisationStrategy.initialise(helper.getClusteringProblem(), helper.getDataSetBuilder()); + Vector centroids = ClusteringUtils.assembleCentroids(centroidsInitialisationStrategy.initialise(helper.getClusteringProblem(), helper.getDataSetBuilder())); particle.setCandidateSolution(centroids); particle.getProperties().put(EntityType.Particle.BEST_POSITION, centroids.getClone()); } + + public void setCentroidsInitialisationStrategy(CentroidsInitialisationStrategy cis) { + this.centroidsInitialisationStrategy = cis; + } } diff --git a/src/main/java/net/sourceforge/cilib/util/ClusteringUtils.java b/src/main/java/net/sourceforge/cilib/util/ClusteringUtils.java index 32cba95..d8c2972 100644 --- a/src/main/java/net/sourceforge/cilib/util/ClusteringUtils.java +++ b/src/main/java/net/sourceforge/cilib/util/ClusteringUtils.java @@ -225,6 +225,25 @@ public final class ClusteringUtils { } } + public static Vector assembleCentroids(ArrayList<Vector> separateCentroids) { + Vector centroids = new Vector(); + + for (Vector centroid : separateCentroids) { + centroids.append(centroid); + } + return centroids; + } + + public static ArrayList<Vector> disassembleCentroids(Vector combinedCentroids, int numberOfClusters) { + ArrayList<Vector> centroids = new ArrayList<Vector>(); + int dimension = combinedCentroids.size() / numberOfClusters; + + for (int i = 0; i < numberOfClusters; ++i) { + centroids.add(combinedCentroids.subList(i * dimension, (i * dimension) + dimension - 1)); + } + return centroids; + } + /** * Assign all patterns to their closest centroid, building up an {@link ArrayList} that * contains {@link Hashtable}s that link a {@link Pattern} to its index in the DataSet. diff --git a/src/main/java/net/sourceforge/cilib/util/VectorUtils.java b/src/main/java/net/sourceforge/cilib/util/VectorUtils.java index 1689497..faab2f5 100644 --- a/src/main/java/net/sourceforge/cilib/util/VectorUtils.java +++ b/src/main/java/net/sourceforge/cilib/util/VectorUtils.java @@ -21,6 +21,7 @@ */ package net.sourceforge.cilib.util; +import net.sourceforge.cilib.math.MathUtil; import net.sourceforge.cilib.type.types.Numeric; import net.sourceforge.cilib.type.types.Real; import net.sourceforge.cilib.type.types.container.Vector; @@ -81,8 +82,8 @@ public final class VectorUtils { * * @param distanceMeasure the {@link net.sourceforge.cilib.util.DistanceMeasure} that * should be used to calculate the <code>zMax</code> - * @param domain the {@link net.sourceforge.cilib.type.types.container.Vector} - * representing the domain + * @param domain the {@link net.sourceforge.cilib.type.types.container.Vector} whose upper and lower bounds represent + * the domain * @return the <code>zMax</code> for the given domain */ public static double zMax(DistanceMeasure distanceMeasure, Vector domain) { @@ -107,4 +108,45 @@ public final class VectorUtils { return vector; } + /** + * Add an amount of noise (jitter) to the given {@link Vector}. Noise is calculated for each element of + * the vector and then added to that element. The random amount of noise is a function of the given ratio of the + * range (bounds) of the given vector. An example for a single element in the vector follows: + * + * Assume value := 0.3, ratio := 0.1, range := [-1, 1], random := [0, 1), then: + * value + ((random - 0.5) * ratio * ((rangeMax - rangeMin) / 2) = 0.26 is the new value for the element. + * If the ratio is 0.0, then no noise is added, i.e. the value remains the same. + * If the ratio is 1.0, then the noise can be any value within the range [-range/2, range/2). + * The random number determines what value within this range is used. Note how the random value is scaled (by + * subtracting 0.5) so that negative numbers can also be generated. + * + * @param vector the {@Vector} to which noise should be added. + * @param ratio the amount of noise that should be added. + * @throws {@link UnsupportedOperationException} when an element in the is not a {@link Numeric} + * @return a new {@link Vector} with added noise. + */ + public static Vector jitter(Vector vector, double ratio) { + Vector jittered = vector.getClone(); + + for (Numeric element : jittered) { + element.set(element.getReal() + (MathUtil.random() - 0.5) * ratio * ((element.getBounds().getUpperBound() - element.getBounds().getLowerBound()) / 2.0)); + } + return jittered; + } + + /** + * Some {@link Numeric} elements within a {@link Vector} might not always have a defined range. This method sets the + * upper and lower bounds of the given vector accordingly. + * @param vector The {@link Vector} whose bounds should be modified. + * @param lowerBounds A {@link Vector} containing the lower bounds as its values. + * @param upperBounds A {@link Vector} containing the upper bounds as its values. + */ + public static Vector setBounds(Vector vector, Vector lowerBounds, Vector upperBounds) { + Vector bounded = vector.getClone(); + + for (int i = 0; i < bounded.size(); ++i) { + bounded.get(i).setBounds(lowerBounds.getReal(i), upperBounds.getReal(i)); + } + return bounded; + } } -- 1.6.0.6 |
From: Theuns C. <the...@gm...> - 2009-06-10 06:42:12
|
--- .../clustering/ClusteringFitnessFunction.java | 7 +-- .../clustering/KHarmonicMeansFunction.java | 1 - .../NonParametricClusteringFunction.java | 1 - .../clustering/QuantisationErrorFunction.java | 1 - .../validityindices/DaviesBouldinIndex.java | 1 - .../clustering/validityindices/DunnIndex.java | 1 - .../clustering/validityindices/DunnIndex33.java | 1 - .../clustering/validityindices/DunnIndex53.java | 1 - .../validityindices/GeneralisedDunnIndex.java | 1 - .../validityindices/HalkidiVazirgiannisIndex.java | 1 - .../validityindices/MaulikBandyopadhyayIndex.java | 3 +- .../clustering/validityindices/TuriIndex.java | 5 +- .../VeenmanReindersBackerIndex.java | 1 - .../measurement/single/NumberOfClustersFormed.java | 19 +++++--- .../cilib/problem/ClusteringProblem.java | 2 - .../problem/dataset/StaticDataSetBuilder.java | 11 ++++- xml/kmeans.xml | 47 +++++--------------- 17 files changed, 39 insertions(+), 65 deletions(-) diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java b/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java index 94243e6..3956d34 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java @@ -51,7 +51,7 @@ import net.sourceforge.cilib.util.ClusteringUtils; public abstract class ClusteringFitnessFunction extends ContinuousFunction { private static final long serialVersionUID = 4834673666638644106L; - private static Logger log = LoggerFactory.getLogger(ClusteringFitnessFunction.class); + protected Logger logger = LoggerFactory.getLogger(this.getClass()); protected ClusteringUtils helper = null; protected ClusterCenterStrategy clusterCenterStrategy = null; protected ArrayList<Hashtable<Integer, Pattern>> arrangedClusters = null; @@ -64,7 +64,6 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { * domain is not set, because it should be specified on the {@link ClusteringProblem}. */ public ClusteringFitnessFunction() { - super(); clusterCenterStrategy = new ClusterCentroidStrategy(); } @@ -391,8 +390,8 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { */ protected double validateFitness(double fitness) { if (fitness < 0.0) { - log.error(this.getClass().getSimpleName() + " fitness < 0.0 : " + fitness); - log.error("Number of clusters formed = " + clustersFormed); + logger.error(this.getClass().getSimpleName() + " fitness < 0.0 : " + fitness); + logger.error("Number of clusters formed = " + clustersFormed); } return fitness; } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/KHarmonicMeansFunction.java b/src/main/java/net/sourceforge/cilib/functions/clustering/KHarmonicMeansFunction.java index cf38491..e963b61 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/KHarmonicMeansFunction.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/KHarmonicMeansFunction.java @@ -32,7 +32,6 @@ public class KHarmonicMeansFunction extends ClusteringFitnessFunction { private static final long serialVersionUID = 2680037315045146954L; public KHarmonicMeansFunction() { - super(); } @Override diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/NonParametricClusteringFunction.java b/src/main/java/net/sourceforge/cilib/functions/clustering/NonParametricClusteringFunction.java index 825ef95..def6093 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/NonParametricClusteringFunction.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/NonParametricClusteringFunction.java @@ -36,7 +36,6 @@ public class NonParametricClusteringFunction extends ClusteringFitnessFunction { private static final long serialVersionUID = 5712216719378084294L; public NonParametricClusteringFunction() { - super(); } @Override diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/QuantisationErrorFunction.java b/src/main/java/net/sourceforge/cilib/functions/clustering/QuantisationErrorFunction.java index 1275689..5b657d2 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/QuantisationErrorFunction.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/QuantisationErrorFunction.java @@ -36,7 +36,6 @@ public class QuantisationErrorFunction extends ClusteringFitnessFunction { private static final long serialVersionUID = -7008338250315442786L; public QuantisationErrorFunction() { - super(); } @Override diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DaviesBouldinIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DaviesBouldinIndex.java index c880f0c..de48927 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DaviesBouldinIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DaviesBouldinIndex.java @@ -41,7 +41,6 @@ public class DaviesBouldinIndex extends ScatterSeperationRatio { private static final long serialVersionUID = -5167494843653998358L; public DaviesBouldinIndex() { - super(); } @Override diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex.java index 4831647..22d1ea5 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex.java @@ -38,7 +38,6 @@ public class DunnIndex extends GeneralisedDunnIndex { * Create an instance of this index. */ public DunnIndex() { - super(); } /** diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex33.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex33.java index ee0992f..2eb95dd 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex33.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex33.java @@ -42,7 +42,6 @@ public class DunnIndex33 extends GeneralisedDunnIndex { private static final long serialVersionUID = -3307601269742583865L; public DunnIndex33() { - super(); clusterCenterStrategy = new ClusterMeanStrategy(); } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex53.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex53.java index 0ac0f32..c238c40 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex53.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex53.java @@ -41,7 +41,6 @@ public class DunnIndex53 extends DunnIndex33 { private static final long serialVersionUID = -5986491658596276019L; public DunnIndex53() { - super(); } /** diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/GeneralisedDunnIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/GeneralisedDunnIndex.java index f2ec037..0765962 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/GeneralisedDunnIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/GeneralisedDunnIndex.java @@ -37,7 +37,6 @@ public abstract class GeneralisedDunnIndex extends ScatterSeperationRatio { private static final long serialVersionUID = -2232760005736588472L; public GeneralisedDunnIndex() { - super(); } /** diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/HalkidiVazirgiannisIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/HalkidiVazirgiannisIndex.java index c327c66..6de0316 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/HalkidiVazirgiannisIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/HalkidiVazirgiannisIndex.java @@ -45,7 +45,6 @@ public class HalkidiVazirgiannisIndex extends ClusteringFitnessFunction { * Create a new instance of {@linkplain HalkidiVazirgiannisIndex}. */ public HalkidiVazirgiannisIndex() { - super(); } /** diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/MaulikBandyopadhyayIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/MaulikBandyopadhyayIndex.java index 0d59a61..979b030 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/MaulikBandyopadhyayIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/MaulikBandyopadhyayIndex.java @@ -42,7 +42,6 @@ public class MaulikBandyopadhyayIndex extends ClusteringFitnessFunction { private int p = 1; public MaulikBandyopadhyayIndex() { - super(); p = 1; } @@ -77,7 +76,7 @@ public class MaulikBandyopadhyayIndex extends ClusteringFitnessFunction { public void setP(int pu) { if (pu < 1) - throw new IllegalArgumentException("The p-value cannot be <= 0"); + throw new IllegalArgumentException("The p-value cannot be < 1"); p = pu; } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/TuriIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/TuriIndex.java index c7a1a53..ffa0a97 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/TuriIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/TuriIndex.java @@ -39,9 +39,8 @@ public class TuriIndex extends ClusteringFitnessFunction { // private double gaussian = 0.0; public TuriIndex() { - super(); -// random = new RandomNumber(); -// gaussian = random.getGaussian(2, 1); +// random = new RandomNumber(); +// gaussian = random.getGaussian(2, 1); } @Override diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/VeenmanReindersBackerIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/VeenmanReindersBackerIndex.java index d0d13d4..36eff1f 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/VeenmanReindersBackerIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/VeenmanReindersBackerIndex.java @@ -51,7 +51,6 @@ public class VeenmanReindersBackerIndex extends ClusteringFitnessFunction { private ControlParameter maximumVariance = null; public VeenmanReindersBackerIndex() { - super(); clusterCenterStrategy = new ClusterMeanStrategy(); maximumVariance = new ConstantControlParameter(1.0); // default variance limit is 1.0 } diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java b/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java index dfb0f3e..835bd5c 100644 --- a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java +++ b/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java @@ -78,16 +78,21 @@ public class NumberOfClustersFormed implements Measurement { } private void plotClusters() { - System.out.println("reset"); - System.out.println("set term jpeg medium"); - System.out.println("set output \"iteration." + String.format("%04d", Algorithm.get().getIterations()) + ".jpg\""); - System.out.print("plot [-0.5:10][-5:5] sin(x) - 0.5, 0.5 - sin(x), "); +// System.out.println("reset"); +// System.out.println("set term jpeg medium"); +// System.out.println("set output \"iteration." + String.format("%04d", Algorithm.get().getIterations()) + ".jpg\""); +// System.out.print("plot [-0.5:10][-5:5] sin(x) - 0.5, 0.5 - sin(x), "); + System.out.print("plot "); ArrayList<Hashtable<Integer, Pattern>> arrangedClusters = ClusteringUtils.get().getArrangedClusters(); ArrayList<Vector> arrangedCentroids = ClusteringUtils.get().getArrangedCentroids(); - for (int i = 0; i < arrangedClusters.size() * 2; i++) { - System.out.print("'-'"); - if (i < arrangedClusters.size() * 2 - 1) { + for (int i = 0; i < arrangedClusters.size(); ++i) { + System.out.print("'-' title 'cluster" + i + "', "); + } + + for (int i = 0; i < arrangedCentroids.size(); ++i) { + System.out.print("'-' title 'centroid" + i + "'"); + if (i < arrangedCentroids.size() - 1) { System.out.print(", "); } } diff --git a/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java b/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java index 082dd18..b8c8804 100644 --- a/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java +++ b/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java @@ -95,7 +95,6 @@ public class ClusteringProblem extends OptimisationProblemAdapter { private static final int UNINITIALISED = -1; public ClusteringProblem() { - super(); innerProblem = null; numberOfClusters = UNINITIALISED; domainRegistry = new StringBasedDomainRegistry(); @@ -303,5 +302,4 @@ public class ClusteringProblem extends OptimisationProblemAdapter { protected Fitness calculateFitness(Type solution) { return innerProblem.calculateFitness(solution); } - } diff --git a/src/main/java/net/sourceforge/cilib/problem/dataset/StaticDataSetBuilder.java b/src/main/java/net/sourceforge/cilib/problem/dataset/StaticDataSetBuilder.java index f7e53b8..a673f58 100644 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/StaticDataSetBuilder.java +++ b/src/main/java/net/sourceforge/cilib/problem/dataset/StaticDataSetBuilder.java @@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory; public class StaticDataSetBuilder extends DataSetBuilder { private static final long serialVersionUID = -7035524554252462144L; private static Logger logger = LoggerFactory.getLogger(StaticDataSetBuilder.class); + protected ArrayList<Pattern> patterns = null; protected Vector cachedMean = null; protected double cachedVariance = 0.0; @@ -61,7 +62,6 @@ public class StaticDataSetBuilder extends DataSetBuilder { public StaticDataSetBuilder(StaticDataSetBuilder rhs) { super(rhs); patterns = new ArrayList<Pattern>(); - for (Pattern pattern : rhs.patterns) { patterns.add(pattern.getClone()); } @@ -126,7 +126,9 @@ public class StaticDataSetBuilder extends DataSetBuilder { private void cacheMeanAndVariance() { logger.info("Caching dataset mean and variance"); cachedMean = StatUtils.meanVector(patterns); + logger.info("Cached mean: " + cachedMean); cachedVariance = StatUtils.variance(patterns, cachedMean); + logger.info("Cached variance: " + cachedVariance); } /** @@ -168,6 +170,7 @@ public class StaticDataSetBuilder extends DataSetBuilder { int cacheSize = (numPatterns * (numPatterns - 1)) / 2; distanceCache = new double[cacheSize]; int index = 0; + int jump = 0; for (int y = 0; y < numPatterns - 1; y++) { Vector rhs = patterns.get(y).data; @@ -176,6 +179,12 @@ public class StaticDataSetBuilder extends DataSetBuilder { index = x + (numPatterns * y) - (((y + 1) * (y + 2)) / 2); distanceCache[index] = helper.calculateDistance(lhs, rhs); } + + int percentageComplete = 100 * index / cacheSize; + if (percentageComplete == jump) { + logger.info(percentageComplete + "% of distances cached"); + jump += 10; + } } } diff --git a/xml/kmeans.xml b/xml/kmeans.xml index e1c2427..31ae178 100644 --- a/xml/kmeans.xml +++ b/xml/kmeans.xml @@ -70,26 +70,17 @@ </dataSetBuilder> </problem> --> - <problem id="artificial.combined" class="problem.ClusteringProblem"> - <domain>R(-1.0,1.0),R(-1.0,1.0)</domain> + <problem id="artificial.combined" class="problem.ClusteringProblem" domain="R(-1.0,1.0),R(-1.0,1.0)"> <innerProblem class="problem.FunctionMinimisationProblem"> <function class="functions.clustering.QuantisationErrorFunction" /> </innerProblem> <dataSetBuilder class="problem.dataset.StaticDataSetBuilder"> - <addDataSet class="problem.dataset.LocalDataSet"> - <identifier>../MSc/datasets/generated/artificial2/artificial.txt</identifier> - <delimiter>,</delimiter> - <beginIndex>0</beginIndex> - <endIndex>1</endIndex> - <classIndex>2</classIndex> - </addDataSet> + <addDataSet class="problem.dataset.LocalDataSet" identifier="../../datasets/generated/artificial2/artificial.txt" delimiter="," beginIndex="0" endIndex="1" classIndex="2" /> </dataSetBuilder> </problem> </problems> - <measurements id="measurements" class="simulator.MeasurementSuite"> - <resolution>1</resolution> - <samples>1</samples> + <measurements id="measurements" class="simulator.MeasurementSuite" resolution="1" samples="1"> <addMeasurement class="measurement.single.Fitness" /> <!-- <addMeasurement class="measurement.single.GenericFunctionMeasurement"> <function class="functions.clustering.InterClusterDistance" /> @@ -104,42 +95,26 @@ <simulations> <simulation> <algorithm idref="kmeans.random"/> - <problem idref="artificial.combined"> - <numberOfClusters>4</numberOfClusters> - </problem> - <measurements idref="measurements"> - <file>measurements/kmeans.random.artificial.4.txt</file> - </measurements> + <problem idref="artificial.combined" numberOfClusters="4" /> + <measurements idref="measurements" file="measurements/kmeans.random.artificial.4.txt" /> </simulation> <simulation> <algorithm idref="pso.random"/> - <problem idref="artificial.combined"> - <numberOfClusters>4</numberOfClusters> - </problem> - <measurements idref="measurements"> - <file>measurements/pso.random.artificial.4.txt</file> - </measurements> + <problem idref="artificial.combined" numberOfClusters="4" /> + <measurements idref="measurements" file="measurements/pso.random.artificial.4.txt" /> </simulation> <simulation> <algorithm idref="kmeans.biased"/> - <problem idref="artificial.combined"> - <numberOfClusters>4</numberOfClusters> - </problem> - <measurements idref="measurements"> - <file>measurements/kmeans.biased.artificial.4.txt</file> - </measurements> + <problem idref="artificial.combined" numberOfClusters="4" /> + <measurements idref="measurements" file="measurements/kmeans.biased.artificial.4.txt" /> </simulation> <simulation> <algorithm idref="pso.biased"/> - <problem idref="artificial.combined"> - <numberOfClusters>4</numberOfClusters> - </problem> - <measurements idref="measurements"> - <file>measurements/pso.biased.artificial.4.txt</file> - </measurements> + <problem idref="artificial.combined" numberOfClusters="4" /> + <measurements idref="measurements" file="measurements/pso.biased.artificial.4.txt" /> </simulation> </simulations> </simulator> -- 1.6.0.6 |
From: Theuns C. <the...@gm...> - 2009-06-10 06:42:09
|
--- .../pso/dynamic/DynamicIterationStrategy.java | 26 ++-- .../RandomSentryDetectionStrategy.java | 128 -------------------- ... => RandomSentryEntitiesDetectionStrategy.java} | 10 +- .../RandomSentryPointsDetectionStrategy.java | 2 +- xml/dynamic-vepso.xml | 2 +- 5 files changed, 20 insertions(+), 148 deletions(-) delete mode 100644 src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryDetectionStrategy.java rename src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/{RandomSentriesDetectionStrategy.java => RandomSentryEntitiesDetectionStrategy.java} (91%) diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/DynamicIterationStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/DynamicIterationStrategy.java index 5ead1c9..2081e69 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/DynamicIterationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/DynamicIterationStrategy.java @@ -24,7 +24,7 @@ package net.sourceforge.cilib.pso.dynamic; import net.sourceforge.cilib.algorithm.population.IterationStrategy; import net.sourceforge.cilib.algorithm.population.PopulationBasedAlgorithm; import net.sourceforge.cilib.pso.dynamic.detectionstrategies.EnvironmentChangeDetectionStrategy; -import net.sourceforge.cilib.pso.dynamic.detectionstrategies.RandomSentriesDetectionStrategy; +import net.sourceforge.cilib.pso.dynamic.detectionstrategies.RandomSentryEntitiesDetectionStrategy; import net.sourceforge.cilib.pso.dynamic.responsestrategies.EnvironmentChangeResponseStrategy; import net.sourceforge.cilib.pso.dynamic.responsestrategies.ReinitializationReactionStrategy; @@ -41,17 +41,17 @@ import net.sourceforge.cilib.pso.dynamic.responsestrategies.ReinitializationReac public class DynamicIterationStrategy<E extends PopulationBasedAlgorithm> implements IterationStrategy<E> { private static final long serialVersionUID = -4441422301948289718L; - private IterationStrategy<PopulationBasedAlgorithm> iterationStrategy; - private EnvironmentChangeDetectionStrategy<PopulationBasedAlgorithm> detectionStrategy; - private EnvironmentChangeResponseStrategy<PopulationBasedAlgorithm> responseStrategy; + private IterationStrategy<E> iterationStrategy; + private EnvironmentChangeDetectionStrategy<E> detectionStrategy; + private EnvironmentChangeResponseStrategy<E> responseStrategy; /** - * Create a new instance. + * Create a new instance of {@linkplain DynamicIterationStrategy}. */ public DynamicIterationStrategy() { //this.iterationStrategy = new SynchronousIterationStrategy(); - this.detectionStrategy = new RandomSentriesDetectionStrategy<PopulationBasedAlgorithm>(); - this.responseStrategy = new ReinitializationReactionStrategy<PopulationBasedAlgorithm>(); + this.detectionStrategy = new RandomSentryEntitiesDetectionStrategy<E>(); + this.responseStrategy = new ReinitializationReactionStrategy<E>(); } /** @@ -101,7 +101,7 @@ public class DynamicIterationStrategy<E extends PopulationBasedAlgorithm> implem * Get the current {@linkplain IterationStrategy}. * @return The current {@linkplain IterationStrategy}. */ - public IterationStrategy<PopulationBasedAlgorithm> getIterationStrategy() { + public IterationStrategy<E> getIterationStrategy() { return iterationStrategy; } @@ -109,7 +109,7 @@ public class DynamicIterationStrategy<E extends PopulationBasedAlgorithm> implem * Set the {@linkplain IterationStrategy} to be used. * @param iterationStrategy The value to set. */ - public void setIterationStrategy(IterationStrategy<PopulationBasedAlgorithm> iterationStrategy) { + public void setIterationStrategy(IterationStrategy<E> iterationStrategy) { this.iterationStrategy = iterationStrategy; } @@ -117,7 +117,7 @@ public class DynamicIterationStrategy<E extends PopulationBasedAlgorithm> implem * Get the currently defined {@linkplain EnvironmentChangeDetectionStrategy}. * @return The current {@linkplain EnvironmentChangeDetectionStrategy}. */ - public EnvironmentChangeDetectionStrategy<PopulationBasedAlgorithm> getDetectionStrategy() { + public EnvironmentChangeDetectionStrategy<E> getDetectionStrategy() { return detectionStrategy; } @@ -125,7 +125,7 @@ public class DynamicIterationStrategy<E extends PopulationBasedAlgorithm> implem * Set the {@linkplain EnvironmentChangeDetectionStrategy} to be used. * @param detectionStrategy The {@linkplain EnvironmentChangeDetectionStrategy} to set. */ - public void setDetectionStrategy(EnvironmentChangeDetectionStrategy<PopulationBasedAlgorithm> detectionStrategy) { + public void setDetectionStrategy(EnvironmentChangeDetectionStrategy<E> detectionStrategy) { this.detectionStrategy = detectionStrategy; } @@ -133,7 +133,7 @@ public class DynamicIterationStrategy<E extends PopulationBasedAlgorithm> implem * Get the currently defined {@linkplain EnvironmentChangeResponseStrategy}, * @return The current {@linkplain EnvironmentChangeResponseStrategy}. */ - public EnvironmentChangeResponseStrategy<PopulationBasedAlgorithm> getResponseStrategy() { + public EnvironmentChangeResponseStrategy<E> getResponseStrategy() { return responseStrategy; } @@ -141,7 +141,7 @@ public class DynamicIterationStrategy<E extends PopulationBasedAlgorithm> implem * Set the current {@linkplain EnvironmentChangeResponseStrategy} to use. * @param responseStrategy The {@linkplain EnvironmentChangeResponseStrategy} to set. */ - public void setResponseStrategy(EnvironmentChangeResponseStrategy<PopulationBasedAlgorithm> responseStrategy) { + public void setResponseStrategy(EnvironmentChangeResponseStrategy<E> responseStrategy) { this.responseStrategy = responseStrategy; } } diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryDetectionStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryDetectionStrategy.java deleted file mode 100644 index 1800c7c..0000000 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryDetectionStrategy.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2003 - 2008 - * Computational Intelligence Research Group (CIRG@UP) - * Department of Computer Science - * University of Pretoria - * South Africa - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package net.sourceforge.cilib.pso.dynamic.detectionstrategies; - -import java.util.ArrayList; - -import net.sourceforge.cilib.algorithm.Algorithm; -import net.sourceforge.cilib.algorithm.population.PopulationBasedAlgorithm; -import net.sourceforge.cilib.entity.Entity; -import net.sourceforge.cilib.entity.Topology; -import net.sourceforge.cilib.math.random.generator.MersenneTwister; -import net.sourceforge.cilib.math.random.generator.Random; - -/** - * This class defines a detection strategy that uses a user-specified - * {@link #numberOfSentries number of} sentry entities and an {@local #epsilon} value to - * detect whether a change has occured in the environment. - * - * @TechReport{ title = "Tracking Changing Extrema with Particle Swarm Optimizer", author = - * "Anthony Jack Carlisle and Gerry V. Dozier", institution = "Huntingdon - * College", year = "2001", number = "CSSE01-08" } - * @param <E> some {@link PopulationBasedAlgorithm population based algorithm} - * @author Anna Rakitianskaia - * @author Theuns Cloete - */ -//TODO: Rename to RandomSentryEntitiesDetectionStrategy -public class RandomSentryDetectionStrategy<E extends PopulationBasedAlgorithm> extends EnvironmentChangeDetectionStrategy<E> { - private static final long serialVersionUID = -7299802900616282412L; - protected int numberOfSentries = 0; - protected Random randomGenerator = null; - - public RandomSentryDetectionStrategy() { - numberOfSentries = 1; - randomGenerator = new MersenneTwister(); - } - - public RandomSentryDetectionStrategy(RandomSentryDetectionStrategy<E> rhs) { - super(rhs); - numberOfSentries = rhs.numberOfSentries; - randomGenerator = rhs.randomGenerator.getClone(); - } - - @Override - public RandomSentryDetectionStrategy<E> getClone() { - return new RandomSentryDetectionStrategy<E>(this); - } - - /** - * After every {@link #interval} iterations, pick - * {@link #numberOfSentries a number of} random entities from the given - * {@link Algorithm algorithm's} topology and compare their previous fitness values with - * their current fitness values. An environment change is detected when the difference - * between the previous and current fitness values are >= the specified - * {@link #epsilon} value. - * - * @param algorithm used to get hold of topology of entities and number of iterations - * @return true if a change has been detected, false otherwise - */ - @Override - public boolean detect(E algorithm) { - if (algorithm.getIterations() % interval == 0) { - ArrayList<Entity> sentries = new ArrayList<Entity>(numberOfSentries); - Topology<? extends Entity> topology = algorithm.getTopology(); - ArrayList<Entity> all = new ArrayList<Entity>(topology.size()); - - all.addAll(topology.asList()); - - // Populate the sentries list with randomly chosen elements from the all list - // AND remove the selected element from the all list so that it won't be selected again - for (int i = 0; i < numberOfSentries; i++) { - int random = randomGenerator.nextInt(all.size()); - sentries.add(all.get(random)); - all.remove(random); - } - - // iterate through randomly selected entities and check for changes - for (Entity sentry : sentries) { - double previousFitness = sentry.getFitness().getValue(); - sentry.calculateFitness(false); - double currentFitness = sentry.getFitness().getValue(); - - if (Math.abs(previousFitness - currentFitness) >= epsilon) { - return true; - } - } - } - return false; - } - - public void setNumberOfSentries(int nos) { - if (nos <= 0) { - throw new IllegalArgumentException("It doesn't make sense to have <= 0 sentry points"); - } - - numberOfSentries = nos; - } - - public int getNumberOfSentries() { - return numberOfSentries; - } - - public void setRandomNumberGenerator(Random rng) { - randomGenerator = rng; - } - - public Random getRandomNumberGenerator() { - return randomGenerator; - } -} diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentriesDetectionStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryEntitiesDetectionStrategy.java similarity index 91% rename from src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentriesDetectionStrategy.java rename to src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryEntitiesDetectionStrategy.java index 8273841..0b3551f 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentriesDetectionStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryEntitiesDetectionStrategy.java @@ -42,26 +42,26 @@ import net.sourceforge.cilib.math.random.generator.Random; * @param <E> some {@link PopulationBasedAlgorithm population based algorithm} * @author Theuns Cloete */ -public class RandomSentriesDetectionStrategy<E extends PopulationBasedAlgorithm> extends EnvironmentChangeDetectionStrategy<E> { +public class RandomSentryEntitiesDetectionStrategy<E extends PopulationBasedAlgorithm> extends EnvironmentChangeDetectionStrategy<E> { private static final long serialVersionUID = -7299802900616282412L; protected ControlParameter numberOfSentries; protected Random randomGenerator = null; - public RandomSentriesDetectionStrategy() { + public RandomSentryEntitiesDetectionStrategy() { // super() is automatically called numberOfSentries = new ConstantControlParameter(1.0); randomGenerator = new MersenneTwister(); } - public RandomSentriesDetectionStrategy(RandomSentriesDetectionStrategy<E> rhs) { + public RandomSentryEntitiesDetectionStrategy(RandomSentryEntitiesDetectionStrategy<E> rhs) { super(rhs); numberOfSentries = rhs.numberOfSentries.getClone(); randomGenerator = rhs.randomGenerator.getClone(); } - public RandomSentriesDetectionStrategy<E> getClone() { - return new RandomSentriesDetectionStrategy<E>(this); + public RandomSentryEntitiesDetectionStrategy<E> getClone() { + return new RandomSentryEntitiesDetectionStrategy<E>(this); } /** diff --git a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryPointsDetectionStrategy.java b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryPointsDetectionStrategy.java index 421a08c..92a1bb8 100644 --- a/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryPointsDetectionStrategy.java +++ b/src/main/java/net/sourceforge/cilib/pso/dynamic/detectionstrategies/RandomSentryPointsDetectionStrategy.java @@ -41,7 +41,7 @@ import net.sourceforge.cilib.entity.Topology; * @param <E> some {@link PopulationBasedAlgorithm population based algorithm} * @author Theuns Cloete */ -public class RandomSentryPointsDetectionStrategy<E extends PopulationBasedAlgorithm> extends RandomSentriesDetectionStrategy<E> { +public class RandomSentryPointsDetectionStrategy<E extends PopulationBasedAlgorithm> extends RandomSentryEntitiesDetectionStrategy<E> { private static final long serialVersionUID = -7908355064341601839L; protected ArrayList<Entity> sentries = null; diff --git a/xml/dynamic-vepso.xml b/xml/dynamic-vepso.xml index 0fc7941..cc51060 100644 --- a/xml/dynamic-vepso.xml +++ b/xml/dynamic-vepso.xml @@ -32,7 +32,7 @@ <iterationStrategy class="pso.iterationstrategies.SynchronousIterationStrategy"> <boundaryConstraint class="problem.boundaryconstraint.ClampingBoundaryConstraint"/> </iterationStrategy> - <detectionStrategy class="pso.dynamic.detectionstrategies.RandomSentriesDetectionStrategy"> + <detectionStrategy class="pso.dynamic.detectionstrategies.RandomSentryEntitiesDetectionStrategy"> <iterationsModulus value="1"/> <numberOfSentries class="controlparameter.ConstantControlParameter" parameter="2"/> </detectionStrategy> -- 1.6.0.6 |
From: Theuns C. <the...@gm...> - 2009-06-10 06:42:06
|
I have a Subversion checkout that had these changes. I then created a patch with svn diff >changes.patch and applied it now into my Git checkout with patch -p0 changes.patch --- .../kmeans/CentroidsInitialisationStrategy.java | 6 +- ...ataSetBasedCentroidsInitialisationStrategy.java | 10 +- .../cilib/clustering/kmeans/KMeans.java | 11 +- .../RandomCentroidsInitialisationStrategy.java | 8 +- .../cooperative/SplitCooperativeAlgorithm.java | 26 +- .../StandardContributionUpdateStrategy.java | 4 +- .../FitnessUpdateStrategy.java | 13 +- .../StandardFitnessUpdateStrategy.java | 4 +- .../net/sourceforge/cilib/entity/EntityType.java | 3 +- .../net/sourceforge/cilib/entity/Topology.java | 12 + .../cilib/entity/topologies/GBestTopology.java | 18 + .../cilib/entity/topologies/LBestTopology.java | 25 + .../entity/topologies/VonNeumannTopology.java | 35 + .../clustering/ClusteringFitnessFunction.java | 5 +- .../clustering/KHarmonicMeansFunction.java | 2 +- .../ClusterMeanStrategy.java | 2 +- .../validityindices/DaviesBouldinIndex.java | 2 +- .../clustering/validityindices/DunnIndex33.java | 2 +- .../clustering/validityindices/DunnIndex53.java | 2 +- .../validityindices/HalkidiVazirgiannisIndex.java | 2 +- .../validityindices/MaulikBandyopadhyayIndex.java | 2 +- .../VeenmanReindersBackerIndex.java | 2 +- .../java/net/sourceforge/cilib/math/StatUtils.java | 2 +- .../measurement/single/NumberOfClustersFormed.java | 53 +- .../cilib/problem/ClusteringProblem.java | 21 +- .../cilib/problem/dataset/ClusterableDataSet.java | 71 - .../sourceforge/cilib/problem/dataset/DataSet.java | 36 +- .../cilib/problem/dataset/DataSetManager.java | 32 +- .../problem/dataset/DynamicCirclesDataSet.java | 131 + .../cilib/problem/dataset/DynamicDataSet.java | 94 + .../problem/dataset/DynamicDataSetBuilder.java} | 46 +- .../dataset/DynamicHelixSpheresDataSet.java} | 43 +- .../cilib/problem/dataset/LocalDataSet.java | 41 +- .../cilib/problem/dataset/Pattern.java} | 45 +- ...taSetBuilder.java => StaticDataSetBuilder.java} | 105 +- .../cilib/pso/dynamic/ChargedParticle.java | 7 +- .../ChargedParticleInitialisationStrategy.java | 5 + .../ChargedSwarmInitialisationStrategy.java | 130 + .../pso/dynamic/ChargedVelocityUpdateStrategy.java | 155 +- .../pso/dynamic/DynamicIterationStrategy.java | 47 +- ...ndardChargedParticleInitialisationStrategy.java | 5 +- .../EnvironmentChangeDetectionStrategy.java | 83 +- .../RandomSentriesDetectionStrategy.java | 4 +- .../RandomSentryDetectionStrategy.java | 149 +- .../RandomSentryPointsDetectionStrategy.java | 4 +- .../TopologyBestSentryDetectionStrategy.java | 3 +- .../responsestrategies/DualReactionStrategy.java | 2 - .../EnvironmentChangeResponseStrategy.java | 8 +- .../PartialReinitialisationResponseStrategy.java | 11 +- .../ParticleReevaluationResponseStrategy.java | 16 +- .../cilib/pso/particle/AbstractParticle.java | 17 +- .../cilib/pso/particle/StandardParticle.java | 2 - ...DataSetBasedPositionInitialisationStrategy.java | 6 +- .../sourceforge/cilib/util/ClusteringUtils.java | 92 +- .../net/sourceforge/cilib/util/VectorUtils.java | 54 +- .../clustering/ClusteringFitnessFunctionTest.java | 8 +- .../net/sourceforge/cilib/math/StatUtilsTest.java | 2 +- .../cilib/problem/dataset/MockStringDataSet.java | 6 + ...lderTest.java => StaticDataSetBuilderTest.java} | 14 +- .../cilib/util/ClusteringUtilsTest.java | 14 +- xml/charged.pso.xml | 71 + xml/clustering-gbest-pso.xml | 4191 ++++++++++++++++++++ xml/clustering.dynamic.circles.xml | 60 + xml/kmeans.xml | 145 + xml/predatorPreyCoevolution.xml | 18 +- 65 files changed, 5567 insertions(+), 678 deletions(-) delete mode 100644 src/main/java/net/sourceforge/cilib/problem/dataset/ClusterableDataSet.java create mode 100644 src/main/java/net/sourceforge/cilib/problem/dataset/DynamicCirclesDataSet.java create mode 100644 src/main/java/net/sourceforge/cilib/problem/dataset/DynamicDataSet.java copy src/{test/java/net/sourceforge/cilib/problem/dataset/AssociatedPairDataSetBuilderTest.java => main/java/net/sourceforge/cilib/problem/dataset/DynamicDataSetBuilder.java} (53%) copy src/{test/java/net/sourceforge/cilib/problem/dataset/AssociatedPairDataSetBuilderTest.java => main/java/net/sourceforge/cilib/problem/dataset/DynamicHelixSpheresDataSet.java} (54%) copy src/{test/java/net/sourceforge/cilib/problem/dataset/AssociatedPairDataSetBuilderTest.java => main/java/net/sourceforge/cilib/problem/dataset/Pattern.java} (54%) rename src/main/java/net/sourceforge/cilib/problem/dataset/{AssociatedPairDataSetBuilder.java => StaticDataSetBuilder.java} (69%) create mode 100644 src/main/java/net/sourceforge/cilib/pso/dynamic/ChargedSwarmInitialisationStrategy.java rename src/test/java/net/sourceforge/cilib/problem/dataset/{AssociatedPairDataSetBuilderTest.java => StaticDataSetBuilderTest.java} (88%) create mode 100644 xml/charged.pso.xml create mode 100644 xml/clustering-gbest-pso.xml create mode 100644 xml/clustering.dynamic.circles.xml create mode 100644 xml/kmeans.xml diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsInitialisationStrategy.java index 205ffaa..5a9fa3d 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/CentroidsInitialisationStrategy.java @@ -24,7 +24,7 @@ package net.sourceforge.cilib.clustering.kmeans; import java.io.Serializable; import net.sourceforge.cilib.problem.ClusteringProblem; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet; +import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.Cloneable; @@ -48,9 +48,9 @@ public interface CentroidsInitialisationStrategy extends Serializable, Cloneable * centroids. * * @param problem the {@link ClusteringProblem} currently being optimized - * @param dataset the {@link ClusterableDataSet} currently being clustered + * @param dataset the {@link StaticDataSetBuilder} currently being clustered * @return a {@link Vector} that represents all the centroids */ - public Vector initialise(ClusteringProblem problem, ClusterableDataSet dataset); + public Vector initialise(ClusteringProblem problem, StaticDataSetBuilder dataset); } diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java index 4b35102..ef8b1d7 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/DataSetBasedCentroidsInitialisationStrategy.java @@ -26,8 +26,8 @@ import java.util.ArrayList; import net.sourceforge.cilib.math.random.generator.MersenneTwister; import net.sourceforge.cilib.math.random.generator.Random; import net.sourceforge.cilib.problem.ClusteringProblem; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; +import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; import net.sourceforge.cilib.type.types.container.Vector; /** @@ -51,6 +51,7 @@ public class DataSetBasedCentroidsInitialisationStrategy implements CentroidsIni /** * {@inheritDoc} */ + @Override public DataSetBasedCentroidsInitialisationStrategy getClone() { return new DataSetBasedCentroidsInitialisationStrategy(); } @@ -60,10 +61,11 @@ public class DataSetBasedCentroidsInitialisationStrategy implements CentroidsIni * given dataset. * * @param problem the {@link ClusteringProblem} currently being optimized - * @param dataset the {@link ClusterableDataSet} currently being clustered + * @param dataset the {@link StaticDataSetBuilder} currently being clustered * @return a {@link Vector} that represents all the centroids */ - public Vector initialise(ClusteringProblem problem, ClusterableDataSet dataset) { + @Override + public Vector initialise(ClusteringProblem problem, StaticDataSetBuilder dataset) { ArrayList<Pattern> patterns = dataset.getPatterns(); int numberOfCentroids = problem.getNumberOfClusters(); Vector centroids = new Vector(problem.getDomain().getDimension()); diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java index beba140..62d532f 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/KMeans.java @@ -30,16 +30,15 @@ import net.sourceforge.cilib.algorithm.Algorithm; import net.sourceforge.cilib.algorithm.SingularAlgorithm; import net.sourceforge.cilib.math.StatUtils; import net.sourceforge.cilib.problem.OptimisationSolution; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; +import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.ClusteringUtils; import net.sourceforge.cilib.util.calculator.FitnessCalculator; import net.sourceforge.cilib.util.calculator.StructuredTypeFitnessCalculator; /** - * This algorithm is an implementation of the KMeans Clustering algorithm. - * <p> - * This is the implementation as described in Section 2 of: + * This algorithm is an implementation of the KMeans Clustering algorithm. This is the implementation as described in + * Section 2 of: * * @inproceedings{ 2000.Ray.jul, title = "Determination of Number of Clusters in * K-Means Clustering and Application in Colour Image @@ -97,7 +96,7 @@ public class KMeans extends SingularAlgorithm { public void performInitialisation() { ClusteringUtils helper = ClusteringUtils.get(); - centroids = centroidsInitialisationStrategy.initialise(helper.getClusteringProblem(), helper.getClusterableDataSet()); + centroids = centroidsInitialisationStrategy.initialise(helper.getClusteringProblem(), helper.getDataSetBuilder()); } /** @@ -152,7 +151,7 @@ public class KMeans extends SingularAlgorithm { */ private Vector reinitialiseCentroid(Vector centroid) { ClusteringUtils helper = ClusteringUtils.get(); - Vector tmp = centroidsInitialisationStrategy.initialise(helper.getClusteringProblem(), helper.getClusterableDataSet()); + Vector tmp = centroidsInitialisationStrategy.initialise(helper.getClusteringProblem(), helper.getDataSetBuilder()); // this first centroid will do return tmp.subList(0, centroid.getDimension() - 1); diff --git a/src/main/java/net/sourceforge/cilib/clustering/kmeans/RandomCentroidsInitialisationStrategy.java b/src/main/java/net/sourceforge/cilib/clustering/kmeans/RandomCentroidsInitialisationStrategy.java index f72d3cc..8cf1292 100644 --- a/src/main/java/net/sourceforge/cilib/clustering/kmeans/RandomCentroidsInitialisationStrategy.java +++ b/src/main/java/net/sourceforge/cilib/clustering/kmeans/RandomCentroidsInitialisationStrategy.java @@ -22,7 +22,7 @@ package net.sourceforge.cilib.clustering.kmeans; import net.sourceforge.cilib.problem.ClusteringProblem; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet; +import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; import net.sourceforge.cilib.type.types.container.Vector; /** @@ -37,6 +37,7 @@ public class RandomCentroidsInitialisationStrategy implements CentroidsInitialis /** * {@inheritDoc} */ + @Override public RandomCentroidsInitialisationStrategy getClone() { return new RandomCentroidsInitialisationStrategy(); } @@ -47,10 +48,11 @@ public class RandomCentroidsInitialisationStrategy implements CentroidsInitialis * {@link Vector} that will house the centroids. * * @param problem the {@link ClusteringProblem} currently being optimized - * @param dataset the {@link ClusterableDataSet} currently being clustered + * @param dataset the {@link StaticDataSetBuilder} currently being clustered * @return a {@link Vector} that represents all the centroids */ - public Vector initialise(ClusteringProblem problem, ClusterableDataSet dataset) { + @Override + public Vector initialise(ClusteringProblem problem, StaticDataSetBuilder dataset) { Vector centroids = (Vector) problem.getDomain().getBuiltRepresenation().getClone(); centroids.randomize(); diff --git a/src/main/java/net/sourceforge/cilib/cooperative/SplitCooperativeAlgorithm.java b/src/main/java/net/sourceforge/cilib/cooperative/SplitCooperativeAlgorithm.java index e0cce2d..659e45a 100644 --- a/src/main/java/net/sourceforge/cilib/cooperative/SplitCooperativeAlgorithm.java +++ b/src/main/java/net/sourceforge/cilib/cooperative/SplitCooperativeAlgorithm.java @@ -133,10 +133,12 @@ public class SplitCooperativeAlgorithm extends MultiPopulationBasedAlgorithm imp contributionUpdateStrategy = contributionUpdate; } + @Override public Entity getContribution() { return context; } + @Override public Fitness getContributionFitness() { return context.getFitness(); } @@ -146,27 +148,11 @@ public class SplitCooperativeAlgorithm extends MultiPopulationBasedAlgorithm imp * method sets the fitness for the context of the cooperating algorithm, i.e. the fitness for all * cooperating algorithms as a whole. */ + @Override public void updateContributionFitness(Fitness fitness) { context.setFitness(fitness); } -/* public Iterator<Algorithm> iterator() { - if(populationIterator == null) - throw new InitialisationException("The PopulationIterator has not been initialised yet."); - return populationIterator.clone(); - } - - public Iterator getPopulationtIterator() { - return populationIterator; - } - - public void setPopulationIterator(PopulationIterator iterator) { - if(subPopulationsAlgorithms == null) - throw new InitialisationException("The populations (ArrayList<Algorithms>) have not been initialised yet."); - populationIterator = iterator; - populationIterator.setPopulations(subPopulationsAlgorithms); - } -*/ public FitnessUpdateStrategy getFitnessUpdateStrategy() { return fitnessUpdateStrategy; } @@ -175,9 +161,6 @@ public class SplitCooperativeAlgorithm extends MultiPopulationBasedAlgorithm imp this.fitnessUpdateStrategy = fitnessUpdate; } - // @Initialiser - // QUESTION are initialisations (or initialisers) still deprecated? Should we use @Initialiser - // here instead? @Override public void performInitialisation() { context.setCandidateSolution(optimisationProblem.getDomain().getBuiltRepresenation().getClone()); @@ -204,7 +187,8 @@ public class SplitCooperativeAlgorithm extends MultiPopulationBasedAlgorithm imp participantProblem.updateContext(context); ParticipatingAlgorithm participantAlgorithm = (ParticipatingAlgorithm) population; contributionUpdateStrategy.updateContribution(participantAlgorithm.getContribution(), 0, context, participantProblem.getOffset(), participantProblem.getDimension()); - fitnessUpdateStrategy.updateFitness(optimisationProblem, context); + //TODO: The following statement might move out of this for-loop when I start clustering using the algorithm + fitnessUpdateStrategy.updateFitness(context); } } diff --git a/src/main/java/net/sourceforge/cilib/cooperative/contributionupdatestrategies/StandardContributionUpdateStrategy.java b/src/main/java/net/sourceforge/cilib/cooperative/contributionupdatestrategies/StandardContributionUpdateStrategy.java index 133601d..51e618f 100644 --- a/src/main/java/net/sourceforge/cilib/cooperative/contributionupdatestrategies/StandardContributionUpdateStrategy.java +++ b/src/main/java/net/sourceforge/cilib/cooperative/contributionupdatestrategies/StandardContributionUpdateStrategy.java @@ -28,8 +28,10 @@ import net.sourceforge.cilib.entity.Entity; * TODO: Complete this javadoc. */ public class StandardContributionUpdateStrategy implements ContributionUpdateStrategy { + + @Override public void updateContribution(Entity src, int srcPos, CooperativeEntity dst, int dstPos, int length) { - //copy participant contribution to context only when the participant's fitness is better than the context's fitness + //always copy participant contribution to context dst.update(src, srcPos, dstPos, length); } } diff --git a/src/main/java/net/sourceforge/cilib/cooperative/fitnessupdatestrategies/FitnessUpdateStrategy.java b/src/main/java/net/sourceforge/cilib/cooperative/fitnessupdatestrategies/FitnessUpdateStrategy.java index bfda263..7baec6c 100644 --- a/src/main/java/net/sourceforge/cilib/cooperative/fitnessupdatestrategies/FitnessUpdateStrategy.java +++ b/src/main/java/net/sourceforge/cilib/cooperative/fitnessupdatestrategies/FitnessUpdateStrategy.java @@ -22,20 +22,17 @@ package net.sourceforge.cilib.cooperative.fitnessupdatestrategies; import net.sourceforge.cilib.entity.Entity; -import net.sourceforge.cilib.problem.OptimisationProblem; +import net.sourceforge.cilib.measurement.single.Fitness; /** - * Update the {@linkplain Fitness} for the current {@linkplain Entity} based on - * the provided {@linkplain OptimisationProblem}. + * Update the {@linkplain Fitness} for the current {@linkplain Entity}. */ public interface FitnessUpdateStrategy { /** - * Update the fitness of the provided {@linkplain Entity}, based on the current - * {@linkplain OptimisationProblem}. - * @param problem The {@linkplain OptimisationProblem} to base the fitness - * calculation on. + * Update the fitness of the provided {@linkplain Entity}. + * * @param context The {@linkplain Entity} to apply the fitness update on. */ - void updateFitness(OptimisationProblem problem, Entity context); + void updateFitness(Entity context); } diff --git a/src/main/java/net/sourceforge/cilib/cooperative/fitnessupdatestrategies/StandardFitnessUpdateStrategy.java b/src/main/java/net/sourceforge/cilib/cooperative/fitnessupdatestrategies/StandardFitnessUpdateStrategy.java index 983d20c..f5762f2 100644 --- a/src/main/java/net/sourceforge/cilib/cooperative/fitnessupdatestrategies/StandardFitnessUpdateStrategy.java +++ b/src/main/java/net/sourceforge/cilib/cooperative/fitnessupdatestrategies/StandardFitnessUpdateStrategy.java @@ -22,7 +22,6 @@ package net.sourceforge.cilib.cooperative.fitnessupdatestrategies; import net.sourceforge.cilib.entity.Entity; -import net.sourceforge.cilib.problem.OptimisationProblem; /** * TODO: Complete this javadoc. @@ -32,7 +31,8 @@ public class StandardFitnessUpdateStrategy implements FitnessUpdateStrategy { /** * {@inheritDoc} */ - public void updateFitness(OptimisationProblem problem, Entity context) { + @Override + public void updateFitness(Entity context) { //context.setFitness(problem.getFitness(context.get(), true)); context.calculateFitness(); } diff --git a/src/main/java/net/sourceforge/cilib/entity/EntityType.java b/src/main/java/net/sourceforge/cilib/entity/EntityType.java index 4b41624..115eeb2 100644 --- a/src/main/java/net/sourceforge/cilib/entity/EntityType.java +++ b/src/main/java/net/sourceforge/cilib/entity/EntityType.java @@ -34,7 +34,8 @@ public enum EntityType { public enum Particle { BEST_POSITION, BEST_FITNESS, - VELOCITY; + VELOCITY, + CHARGE; public enum Guide { LOCAL_GUIDE, diff --git a/src/main/java/net/sourceforge/cilib/entity/Topology.java b/src/main/java/net/sourceforge/cilib/entity/Topology.java index 63eba26..5d6e853 100644 --- a/src/main/java/net/sourceforge/cilib/entity/Topology.java +++ b/src/main/java/net/sourceforge/cilib/entity/Topology.java @@ -78,6 +78,18 @@ public interface Topology<E extends Entity> */ public boolean isEmpty(); + /** + * Returns an <code>iterator</code> over all entities in the neighbourhood of the given + * {@link net.sourceforge.cilib.entity.Entity}. + * + * @param entity the {@link net.sourceforge.cilib.entity.Entity} in this + * {@link net.sourceforge.cilib.entity.Topology} whose neighbourhood is desired + * @return An iterator over all the neighbours of the given + * {@link net.sourceforge.cilib.entity.Entity} + * @author Theuns Cloete + */ + public abstract Iterator<E> neighbourhood(E entity); + /** * Remove all the entities from the topology. * {@inheritDoc} diff --git a/src/main/java/net/sourceforge/cilib/entity/topologies/GBestTopology.java b/src/main/java/net/sourceforge/cilib/entity/topologies/GBestTopology.java index 3e81aae..7114665 100644 --- a/src/main/java/net/sourceforge/cilib/entity/topologies/GBestTopology.java +++ b/src/main/java/net/sourceforge/cilib/entity/topologies/GBestTopology.java @@ -80,6 +80,14 @@ public class GBestTopology<E extends Entity> extends AbstractTopology<E> { return new GBestTopologyIterator<E>(this); } + /** + * {@inheritDoc} + */ + @Override + public Iterator<E> neighbourhood(E entity) { + return new GBestTopologyIterator<E>(this, entity); + } + @Override public boolean add(E particle) { return entities.add(particle); @@ -239,6 +247,16 @@ public class GBestTopology<E extends Entity> extends AbstractTopology<E> { index = -1; } + /** + * Construct an iterator that can iterate over the given entity's neighbourhood. + * @param topology the topology in which the given entity resides + * @param entity the entity whos neighbourhood is desired + */ + public GBestTopologyIterator(GBestTopology<T> topology, T entity) { + this.topology = topology; + this.index = indexOf(entity); + } + @Override public int getIndex() { return index; diff --git a/src/main/java/net/sourceforge/cilib/entity/topologies/LBestTopology.java b/src/main/java/net/sourceforge/cilib/entity/topologies/LBestTopology.java index 9d3863a..15f2792 100644 --- a/src/main/java/net/sourceforge/cilib/entity/topologies/LBestTopology.java +++ b/src/main/java/net/sourceforge/cilib/entity/topologies/LBestTopology.java @@ -86,6 +86,16 @@ public class LBestTopology<E extends Entity> extends GBestTopology<E> { } /** + * {@inheritDoc} + * @author Theuns Cloete + */ + @Override + public Iterator<E> neighbourhood(E entity) { + this.neighbourhoodSize.updateParameter(); + return new LBestNeighbourhoodIterator<E>(this, entity); + } + + /** * Sets the {@linkplain ControlParameter} that should be used to determine the * number of particles in the neighbourhood of each particle. The default is a * {@linkplain ConstantControlParameter} with the parameter set to 3. @@ -127,6 +137,21 @@ public class LBestTopology<E extends Entity> extends GBestTopology<E> { count = 0; } + /** + * Construct an iterator that can iterate over the given entity's neighbourhood. + * @param topology the topology in which the given entity resides + * @param entity the entity whos neighbourhood is desired + */ + public LBestNeighbourhoodIterator(LBestTopology<T> topology, T entity) { + this.topology = topology; + this.index = indexOf(entity) - (this.topology.getNeighbourhoodSize() / 2) - 1; + + if (this.index < 0) { + this.index += this.topology.size(); + } + this.count = 0; + } + @Override public int getIndex() { return index; diff --git a/src/main/java/net/sourceforge/cilib/entity/topologies/VonNeumannTopology.java b/src/main/java/net/sourceforge/cilib/entity/topologies/VonNeumannTopology.java index 3d658a5..2b0f8cb 100644 --- a/src/main/java/net/sourceforge/cilib/entity/topologies/VonNeumannTopology.java +++ b/src/main/java/net/sourceforge/cilib/entity/topologies/VonNeumannTopology.java @@ -89,6 +89,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public VonNeumannTopology<E> getClone() { return new VonNeumannTopology<E>(this); } @@ -97,14 +98,21 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { * {@inheritDoc} */ @SuppressWarnings("unchecked") + @Override public Iterator<E> neighbourhood(Iterator<? extends Entity> iterator) { MatrixIterator<E> i = (MatrixIterator<E>) iterator; return new VonNeumannNeighbourhoodIterator<E>(this, i); } + @Override + public Iterator<E> neighbourhood(E entity) { + throw new UnsupportedOperationException("Not yet implemented"); + } + /** * {@inheritDoc} */ + @Override public Iterator<E> iterator() { return new VonNeumannTopologyIterator<E>(this); } @@ -112,6 +120,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public boolean add(E particle) { int min = entities.size(); ArrayList<E> shortest = null; @@ -136,6 +145,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public boolean addAll(Collection<? extends E> set) { this.entities.ensureCapacity(this.entities.size()+set.size()); Iterator<? extends E> i = set.iterator(); @@ -150,6 +160,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public int size() { // TODO: couldn't we just return entities.size()? int size = 0; @@ -193,6 +204,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public boolean hasNext() { return row != topology.lastRow || col != topology.lastCol; } @@ -200,6 +212,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public T next() { if (row == topology.lastRow && col == topology.lastCol) { throw new NoSuchElementException(); @@ -217,6 +230,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public void remove() { if (col == -1) { throw new IllegalStateException(); @@ -234,6 +248,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public int getRow() { return row; } @@ -241,6 +256,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public int getCol() { return col; } @@ -269,6 +285,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public boolean hasNext() { return (index != Direction.DONE); } @@ -276,6 +293,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public T next() { switch (index) { case CENTER: { @@ -342,6 +360,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public void remove() { topology.remove(row, col); if (index == Direction.CENTER) { @@ -352,6 +371,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public int getRow() { return row; } @@ -359,6 +379,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public int getCol() { return col; } @@ -368,6 +389,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public boolean remove(E indiv) { throw new UnsupportedOperationException("Method not supported in VonNeumannTopology"); } @@ -375,6 +397,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public E get(int index) { throw new UnsupportedOperationException("Method not supported in VonNeumannTopology"); } @@ -382,6 +405,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public E set(int index, E indiv) { throw new UnsupportedOperationException("Method not supported in VonNeumannTopology"); } @@ -389,6 +413,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public List<E> asList() { List<E> entityList = new ArrayList<E>(); for (ArrayList<E> i : entities){ @@ -400,6 +425,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public boolean isEmpty() { throw new UnsupportedOperationException("Method not supported in VonNeumannTopology"); } @@ -407,6 +433,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public void clear() { throw new UnsupportedOperationException("Method not supported in VonNeumannTopology"); } @@ -487,6 +514,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public boolean addAll(int index, Collection<? extends E> c) { throw new UnsupportedOperationException("Method not supported in VonNeumannTopology"); } @@ -494,6 +522,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public void add(int index, E element) { throw new UnsupportedOperationException("Method not supported in VonNeumannTopology"); } @@ -501,6 +530,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public E remove(int index) { throw new UnsupportedOperationException("Method not supported in VonNeumannTopology"); } @@ -508,6 +538,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public int indexOf(Object o) { throw new UnsupportedOperationException("Method not supported in VonNeumannTopology"); } @@ -515,6 +546,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public int lastIndexOf(Object o) { throw new UnsupportedOperationException("Method not supported in VonNeumannTopology"); } @@ -522,6 +554,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public ListIterator<E> listIterator() { throw new UnsupportedOperationException("Method not supported in VonNeumannTopology"); } @@ -529,6 +562,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public ListIterator<E> listIterator(int index) { throw new UnsupportedOperationException("Method not supported in VonNeumannTopology"); } @@ -536,6 +570,7 @@ public class VonNeumannTopology<E extends Entity> extends AbstractTopology<E> { /** * {@inheritDoc} */ + @Override public List<E> subList(int fromIndex, int toIndex) { throw new UnsupportedOperationException("Method not supported in VonNeumannTopology"); } diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java b/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java index f039027..94243e6 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/ClusteringFitnessFunction.java @@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory; import net.sourceforge.cilib.functions.ContinuousFunction; import net.sourceforge.cilib.functions.clustering.clustercenterstrategies.ClusterCenterStrategy; import net.sourceforge.cilib.functions.clustering.clustercenterstrategies.ClusterCentroidStrategy; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; +import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.ClusteringUtils; @@ -68,6 +68,7 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { clusterCenterStrategy = new ClusterCentroidStrategy(); } + @Override public abstract ClusteringFitnessFunction getClone(); /** @@ -97,7 +98,7 @@ public abstract class ClusteringFitnessFunction extends ContinuousFunction { */ @Override public double evaluate(Vector centroids) { - helper = ClusteringUtils.get(); //this statement should not be in a constructor + helper = ClusteringUtils.get(); //this statement should not be in a constructor helper.arrangeClustersAndCentroids(centroids); arrangedClusters = helper.getArrangedClusters(); arrangedCentroids = helper.getArrangedCentroids(); diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/KHarmonicMeansFunction.java b/src/main/java/net/sourceforge/cilib/functions/clustering/KHarmonicMeansFunction.java index c5e2044..cf38491 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/KHarmonicMeansFunction.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/KHarmonicMeansFunction.java @@ -21,7 +21,7 @@ */ package net.sourceforge.cilib.functions.clustering; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; +import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterMeanStrategy.java b/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterMeanStrategy.java index 38b21a1..575faa7 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterMeanStrategy.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/clustercenterstrategies/ClusterMeanStrategy.java @@ -24,7 +24,7 @@ package net.sourceforge.cilib.functions.clustering.clustercenterstrategies; import java.util.Collection; import net.sourceforge.cilib.math.StatUtils; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; +import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.ClusteringUtils; diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DaviesBouldinIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DaviesBouldinIndex.java index db17062..c880f0c 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DaviesBouldinIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DaviesBouldinIndex.java @@ -23,7 +23,7 @@ package net.sourceforge.cilib.functions.clustering.validityindices; import java.util.Collection; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; +import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex33.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex33.java index 3aa6708..ee0992f 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex33.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex33.java @@ -24,7 +24,7 @@ package net.sourceforge.cilib.functions.clustering.validityindices; import java.util.Collection; import net.sourceforge.cilib.functions.clustering.clustercenterstrategies.ClusterMeanStrategy; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; +import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex53.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex53.java index 79b4d98..0ac0f32 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex53.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/DunnIndex53.java @@ -23,7 +23,7 @@ package net.sourceforge.cilib.functions.clustering.validityindices; import java.util.Collection; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; +import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/HalkidiVazirgiannisIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/HalkidiVazirgiannisIndex.java index 11a6684..c327c66 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/HalkidiVazirgiannisIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/HalkidiVazirgiannisIndex.java @@ -23,7 +23,7 @@ package net.sourceforge.cilib.functions.clustering.validityindices; import net.sourceforge.cilib.functions.clustering.ClusteringFitnessFunction; import net.sourceforge.cilib.math.StatUtils; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; +import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/MaulikBandyopadhyayIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/MaulikBandyopadhyayIndex.java index 82624f9..0d59a61 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/MaulikBandyopadhyayIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/MaulikBandyopadhyayIndex.java @@ -22,7 +22,7 @@ package net.sourceforge.cilib.functions.clustering.validityindices; import net.sourceforge.cilib.functions.clustering.ClusteringFitnessFunction; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; +import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** diff --git a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/VeenmanReindersBackerIndex.java b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/VeenmanReindersBackerIndex.java index db39f5e..d0d13d4 100644 --- a/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/VeenmanReindersBackerIndex.java +++ b/src/main/java/net/sourceforge/cilib/functions/clustering/validityindices/VeenmanReindersBackerIndex.java @@ -29,7 +29,7 @@ import net.sourceforge.cilib.controlparameter.ControlParameter; import net.sourceforge.cilib.functions.clustering.ClusteringFitnessFunction; import net.sourceforge.cilib.functions.clustering.clustercenterstrategies.ClusterMeanStrategy; import net.sourceforge.cilib.math.StatUtils; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; +import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.container.Vector; /** diff --git a/src/main/java/net/sourceforge/cilib/math/StatUtils.java b/src/main/java/net/sourceforge/cilib/math/StatUtils.java index 792211c..6cc73d4 100644 --- a/src/main/java/net/sourceforge/cilib/math/StatUtils.java +++ b/src/main/java/net/sourceforge/cilib/math/StatUtils.java @@ -23,7 +23,7 @@ package net.sourceforge.cilib.math; import java.util.Collection; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; +import net.sourceforge.cilib.problem.dataset.Pattern; import net.sourceforge.cilib.type.types.Numeric; import net.sourceforge.cilib.type.types.container.Vector; diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java b/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java index 132160e..dfb0f3e 100644 --- a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java +++ b/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java @@ -21,8 +21,14 @@ */ package net.sourceforge.cilib.measurement.single; +import java.util.ArrayList; +import java.util.Hashtable; + import net.sourceforge.cilib.algorithm.Algorithm; import net.sourceforge.cilib.measurement.Measurement; +import net.sourceforge.cilib.problem.dataset.DataSetBuilder; +import net.sourceforge.cilib.problem.dataset.Pattern; +import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; import net.sourceforge.cilib.type.types.Int; import net.sourceforge.cilib.type.types.Type; import net.sourceforge.cilib.type.types.container.Vector; @@ -33,13 +39,13 @@ import net.sourceforge.cilib.util.ClusteringUtils; * For this measurement to work, the following is important: * <ol> * <li><tt>Algorithm.get()</tt> should not be <tt>null</tt>.</li> - * <li>The algorithm's best solution (best position) should return a {@linkplain Vector}.</li> - * <li>The algorithm's problem's {@linkplain DataSetBuilder} should be a - * {@linkplain ClusterableDataSet}.</li> - * <li>The <tt>arrangeClustersAndCentroids()</tt> method (defined in - * {@linkplain ClusterableDataSet}) should be implemented to remove <i>empty clusters</i>.</li> - * <li>The <tt>getArrangedClusters()</tt> method (defined in {@linkplain ClusterableDataSet}) - * should be implemented to return the list of non-empty clusters.</li> + * <li>The algorithm's best solution (best position) should return a {@link Vector}.</li> + * <li>The algorithm's problem's {@link DataSetBuilder} should be a + * {@link StaticDataSetBuilder}.</li> + * <li>The {@link ClusteringUtils#arrangeClustersAndCentroids(net.sourceforge.cilib.type.types.container.Vector)} method + * should be implemented to remove <i>empty clusters</i>.</li> + * <li>The {@link ClusteringUtils#getArrangedClusters()} method should be implemented to return the list of non-empty + * clusters.</li> * </ol> * @author Theuns Cloete */ @@ -52,18 +58,51 @@ public class NumberOfClustersFormed implements Measurement { public NumberOfClustersFormed(NumberOfClustersFormed rhs) { } + @Override public NumberOfClustersFormed getClone() { return new NumberOfClustersFormed(this); } + @Override public String getDomain() { return "Z"; } + @Override public Type getValue(Algorithm algorithm) { ClusteringUtils helper = ClusteringUtils.get(); Vector centroids = (Vector) algorithm.getBestSolution().getPosition(); helper.arrangeClustersAndCentroids(centroids); + plotClusters(); return new Int(helper.getArrangedCentroids().size()); } + + private void plotClusters() { + System.out.println("reset"); + System.out.println("set term jpeg medium"); + System.out.println("set output \"iteration." + String.format("%04d", Algorithm.get().getIterations()) + ".jpg\""); + System.out.print("plot [-0.5:10][-5:5] sin(x) - 0.5, 0.5 - sin(x), "); + + ArrayList<Hashtable<Integer, Pattern>> arrangedClusters = ClusteringUtils.get().getArrangedClusters(); + ArrayList<Vector> arrangedCentroids = ClusteringUtils.get().getArrangedCentroids(); + for (int i = 0; i < arrangedClusters.size() * 2; i++) { + System.out.print("'-'"); + if (i < arrangedClusters.size() * 2 - 1) { + System.out.print(", "); + } + } + System.out.println(); + + for (Hashtable<Integer, Pattern> cluster : arrangedClusters) { + for (Pattern pattern : cluster.values()) { + System.out.println(pattern); + } + System.out.println('e'); + } + + for (Vector centroid : arrangedCentroids) { + System.out.println(centroid.toString('\0', '\0', '\t')); + System.out.println('e'); + } + } } diff --git a/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java b/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java index 068b9c0..082dd18 100644 --- a/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java +++ b/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java @@ -24,8 +24,7 @@ package net.sourceforge.cilib.problem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import net.sourceforge.cilib.problem.dataset.AssociatedPairDataSetBuilder; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet; +import net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder; import net.sourceforge.cilib.problem.dataset.DataSetBuilder; import net.sourceforge.cilib.problem.dataset.DataSetManager; import net.sourceforge.cilib.type.DomainParser; @@ -40,7 +39,7 @@ import net.sourceforge.cilib.util.EuclideanDistanceMeasure; * <p> * This class is used to setup/configure a problem that is capable of clustering the data in * a dataset, more specifically the data contained in an - * {@link net.sourceforge.cilib.problem.dataset.AssociatedPairDataSetBuilder}. Clustering is an + * {@link net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder}. Clustering is an * {@link net.sourceforge.cilib.problem.OptimisationProblemAdapter optimisation} problem. The process of optimising a * clustering is driven by a fitness function that determines the fitness of a specific * clustering. This class therefore wraps a {@link net.sourceforge.cilib.problem.FunctionOptimisationProblem} (called the @@ -217,6 +216,7 @@ public class ClusteringProblem extends OptimisationProblemAdapter { * * @return the {@link #domainRegistry} of this clustering problem */ + @Override public DomainRegistry getBehaviouralDomain() { return domainRegistry; } @@ -245,6 +245,7 @@ public class ClusteringProblem extends OptimisationProblemAdapter { * @return the {@link #innerProblem}'s {@linkplain net.sourceforge.cilib.problem.FunctionOptimisationProblem#function function's} * domain registry */ + @Override public DomainRegistry getDomain() { return innerProblem.getFunction().getDomainRegistry(); } @@ -254,21 +255,21 @@ public class ClusteringProblem extends OptimisationProblemAdapter { * {@link DataSetBuilder}. Then use the {@link ClusteringUtils} per-thread singleton to * set the {@link DataSetBuilder} as the current dataset for this clustering. * - * @throws IllegalArgumentException when the given {@link net.sourceforge.cilib.problem.dataset.DataSetBuilder} is not an - * {@link net.sourceforge.cilib.problem.dataset.AssociatedPairDataSetBuilder}. This is only temporary, because I + * @throws IllegalArgumentException when the given {@link net.sourceforge.cilib.problem.dataset.DataSetBuilder} is not a + * {@link net.sourceforge.cilib.problem.dataset.StaticDataSetBuilder}. This is only temporary, because I * didn't want to change the more generic {@link net.sourceforge.cilib.problem.dataset.DataSetBuilder} too much. * @param dsb the {@link net.sourceforge.cilib.problem.dataset.DataSetBuilder} that represents the dataset that should be * clustered */ @Override public void setDataSetBuilder(DataSetBuilder dsb) { - if (!(dsb instanceof AssociatedPairDataSetBuilder)) - throw new IllegalArgumentException("This ClusteringProblem expects an AssociatedPairDataSet\nONLY FOR NOW\nBECAUSE I didn't want to change the more generic DataSetBuilder"); + if (!(dsb instanceof StaticDataSetBuilder)) + throw new IllegalArgumentException("This ClusteringProblem expects a StaticDataSetBuilder\nONLY FOR NOW\nBECAUSE I didn't want to change the more generic DataSetBuilder"); - AssociatedPairDataSetBuilder builder = (AssociatedPairDataSetBuilder) dsb; + StaticDataSetBuilder builder = (StaticDataSetBuilder) dsb; - dataSetBuilder = DataSetManager.getInstance().getDataSetBuilder(builder); - ClusteringUtils.get().setClusterableDataSet((ClusterableDataSet) dataSetBuilder); + this.dataSetBuilder = DataSetManager.getInstance().getDataSetBuilder(builder); + ClusteringUtils.get().setDataSetBuilder((StaticDataSetBuilder) this.dataSetBuilder); } /** diff --git a/src/main/java/net/sourceforge/cilib/problem/dataset/ClusterableDataSet.java b/src/main/java/net/sourceforge/cilib/problem/dataset/ClusterableDataSet.java deleted file mode 100644 index 1d22eea..0000000 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/ClusterableDataSet.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2003 - 2008 - * Computational Intelligence Research Group (CIRG@UP) - * Department of Computer Science - * University of Pretoria - * South Africa - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package net.sourceforge.cilib.problem.dataset; - -import java.util.ArrayList; - -import net.sourceforge.cilib.type.types.container.Vector; -import net.sourceforge.cilib.util.Cloneable; - -/** - * All datasets that will be clustered have to implement this interface. - * @author Theuns Cloete - */ -public interface ClusterableDataSet { - - public int getNumberOfPatterns(); - - public Pattern getPattern(int index); - - public ArrayList<Pattern> getPatterns(); - public Vector getMean(); - public double getVariance(); - public double getCachedDistance(int x, int y); - public void initialise(); - - /** - * TODO: Complete this javadoc. - */ - public class Pattern implements Cloneable { - private static final long serialVersionUID = 8831874859964777328L; - private String clas = "<not set>"; - public Vector data = null; - - public Pattern(String c, Vector d) { - clas = c; - data = d; - } - - public Pattern(Pattern rhs) { - clas = rhs.clas; - data = rhs.data; - } - - public Pattern getClone() { - return new Pattern(this); - } - - public String toString() { - return clas + " -> " + data; - } - } -} diff --git a/src/main/java/net/sourceforge/cilib/problem/dataset/DataSet.java b/src/main/java/net/sourceforge/cilib/problem/dataset/DataSet.java index 4385f60..d3f156f 100644 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/DataSet.java +++ b/src/main/java/net/sourceforge/cilib/problem/dataset/DataSet.java @@ -23,6 +23,7 @@ package net.sourceforge.cilib.problem.dataset; import java.io.InputStream; import java.io.Serializable; +import java.util.ArrayList; import net.sourceforge.cilib.util.Cloneable; @@ -35,19 +36,20 @@ import net.sourceforge.cilib.util.Cloneable; public abstract class DataSet implements Cloneable, Serializable { private static final long serialVersionUID = 5190227337412349440L; - @Deprecated - protected String patternExpression = null; + protected String identifier = null; public DataSet() { - patternExpression = ""; + identifier = "<not set>"; } public DataSet(DataSet rhs) { - patternExpression = new String(rhs.patternExpression); + identifier = rhs.identifier; } public abstract DataSet getClone(); + public abstract ArrayList<Pattern> parseDataSet(); + /** * Returns the data set as a byte array. * @return the data set as a <code>byte[]</code> @@ -61,23 +63,23 @@ public abstract class DataSet implements Cloneable, Serializable { public abstract InputStream getInputStream(); /** - * Set the regular expression that will be used to split the patterns in the provided DataSet - * file. The format of this regular expression depends on where you are calling the method from. - * When you specify the regular expression in a simulation XML file, the format should be a - * standard regular expression. When you call this method directly with a regular expression in - * double quotes (from a Java source file), then the format of the regular expression should be a - * Java style regular expression. - * @param regexp The regex to use + * Get the unique identifier of this data set. + * + * @return the unique identifier of this data set */ - public void setPatternExpression(String regexp) { - patternExpression = regexp; + public String getIdentifier() { + return identifier; } /** - * Get the regular expression that has been set for this DataSet. - * @return The regular expression. + * Set the identifier of this data set. In the case of a file on disk, i.e. when using + * {@link LocalDataSet}, the filename will be used as the identifier. In the case of a + * dynamic data set, i.e. when using {@link DynamicDataSet}, a generated will might be + * used as the identifier. + * + * @param id the identifier of the data set */ - public String getPatternExpression() { - return patternExpression; + public void setIdentifier(String id) { + identifier = id; } } diff --git a/src/main/java/net/sourceforge/cilib/problem/dataset/DataSetManager.java b/src/main/java/net/sourceforge/cilib/problem/dataset/DataSetManager.java index bed926c..6145dcc 100644 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/DataSetManager.java +++ b/src/main/java/net/sourceforge/cilib/problem/dataset/DataSetManager.java @@ -25,7 +25,9 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Hashtable; -import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; +import net.sourceforge.cilib.problem.Problem; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This class is a Singleton and is responsible for managing all the {@link DataSet}s and @@ -37,23 +39,24 @@ import net.sourceforge.cilib.problem.dataset.ClusterableDataSet.Pattern; * {@link Pattern}s that have been returned by the {@link LocalDataSet#parseDataSet()} * method) makes sure that a specific dataset is parsed and instantiated only once. <br/> * The second, {@link #builders} (with its <code>key</code> the identifier of the dataset - * builder and its <code>value</code> the {@link AssociatedPairDataSetBuilder} object) + * builder and its <code>value</code> the {@link StaticDataSetBuilder} object) * makes sure that a specific dataset builder is built and initialised only once.<br/> The * concrete {@link LocalDataSet} is used, but only for now, because I didn't want to change - * the more generic {@link DataSet}.<br/> The concrete {@link AssociatedPairDataSetBuilder} is + * the more generic {@link DataSet}.<br/> The concrete {@link StaticDataSetBuilder} is * used, but only for now, because I didn't want to change the more generic * {@link DataSetBuilder}. */ public final class DataSetManager implements Serializable { private static final long serialVersionUID = 6735187580654161651L; + private static Logger logger = LoggerFactory.getLogger(DataSetManager.class); private static volatile DataSetManager instance = null; private Hashtable<String, ArrayList<Pattern>> datasets = null; - private Hashtable<String, AssociatedPairDataSetBuilder> builders = null; + private Hashtable<String, StaticDataSetBuilder> builders = null; private DataSetManager() { datasets = new Hashtable<String, ArrayList<Pattern>>(); - builders = new Hashtable<String, AssociatedPairDataSetBuilder>(); + builders = new Hashtable<String, StaticDataSetBuilder>(); } public static synchronized DataSetManager getInstance() { @@ -72,14 +75,15 @@ public final class DataSetManager implements Serializable { * parsed/instantiated before * @return an {@link ArrayList} of {@link Pattern}s representing the given dataset */ - public synchronized ArrayList<Pattern> getDataFromSet(LocalDataSet dataset) { - String identifier = dataset.getFile(); + public synchronized ArrayList<Pattern> getDataFromSet(DataSet dataset) { + String identifier = dataset.getIdentifier(); -// log.debug("Requesting " + identifier); + logger.debug("Requesting " + identifier); if (!datasets.containsKey(identifier)) { + logger.debug("Parsing " + identifier); datasets.put(identifier, dataset.parseDataSet()); } -// log.debug("Returning " + identifier); + logger.debug("Returning " + identifier); return datasets.get(identifier); } @@ -88,20 +92,20 @@ public final class DataSetManager implements Serializable { * requested built up dataset. The dataset builder's identifier is used as the key into * the {@link #builders} {@link Hashtable}. ... [truncated message content] |
From: Theuns C. <the...@gm...> - 2009-06-10 06:42:03
|
--- .../measurement/single/NumberOfClustersFormed.java | 12 ++++++------ .../cilib/problem/ClusteringProblem.java | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java b/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java index 835bd5c..480758e 100644 --- a/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java +++ b/src/main/java/net/sourceforge/cilib/measurement/single/NumberOfClustersFormed.java @@ -73,15 +73,15 @@ public class NumberOfClustersFormed implements Measurement { ClusteringUtils helper = ClusteringUtils.get(); Vector centroids = (Vector) algorithm.getBestSolution().getPosition(); helper.arrangeClustersAndCentroids(centroids); - plotClusters(); +// plotClustersAndCentroids(); return new Int(helper.getArrangedCentroids().size()); } - private void plotClusters() { -// System.out.println("reset"); -// System.out.println("set term jpeg medium"); -// System.out.println("set output \"iteration." + String.format("%04d", Algorithm.get().getIterations()) + ".jpg\""); -// System.out.print("plot [-0.5:10][-5:5] sin(x) - 0.5, 0.5 - sin(x), "); + private void plotClustersAndCentroids() { +// System.out.println("reset"); +// System.out.println("set term jpeg medium"); +// System.out.println("set output \"iteration." + String.format("%04d", Algorithm.get().getIterations()) + ".jpg\""); +// System.out.print("plot [-0.5:10][-5:5] sin(x) - 0.5, 0.5 - sin(x), "); System.out.print("plot "); ArrayList<Hashtable<Integer, Pattern>> arrangedClusters = ClusteringUtils.get().getArrangedClusters(); diff --git a/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java b/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java index b8c8804..ee89d00 100644 --- a/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java +++ b/src/main/java/net/sourceforge/cilib/problem/ClusteringProblem.java @@ -87,7 +87,6 @@ import net.sourceforge.cilib.util.EuclideanDistanceMeasure; public class ClusteringProblem extends OptimisationProblemAdapter { private static final long serialVersionUID = 7027242527499147957L; private static Logger logger = LoggerFactory.getLogger(ClusteringProblem.class); - private FunctionOptimisationProblem innerProblem; private int numberOfClusters; private DomainRegistry domainRegistry; @@ -211,7 +210,7 @@ public class ClusteringProblem extends OptimisationProblemAdapter { /** * Return the actual domain of the problem's dataset, i.e. NOT the duplicated domain - * string as used by the clustering fitness function. + * string as used by the clustering fitness function. For the duplicated domain string, see {@link #getDomain()}. * * @return the {@link #domainRegistry} of this clustering problem */ @@ -238,8 +237,8 @@ public class ClusteringProblem extends OptimisationProblemAdapter { } /** - * Return the domain as used by the configured fitness function, i.e. NOT the simplified - * domain string of the problem's dataset. + * Return the domain as used by the configured fitness function, i.e. NOT the basic + * domain string of the problem's dataset. For the basic domain string, see {@link #getBehaviouralDomain()}. * * @return the {@link #innerProblem}'s {@linkplain net.sourceforge.cilib.problem.FunctionOptimisationProblem#function function's} * domain registry @@ -262,8 +261,9 @@ public class ClusteringProblem extends OptimisationProblemAdapter { */ @Override public void setDataSetBuilder(DataSetBuilder dsb) { - if (!(dsb instanceof StaticDataSetBuilder)) + if (!(dsb instanceof StaticDataSetBuilder)) { throw new IllegalArgumentException("This ClusteringProblem expects a StaticDataSetBuilder\nONLY FOR NOW\nBECAUSE I didn't want to change the more generic DataSetBuilder"); + } StaticDataSetBuilder builder = (StaticDataSetBuilder) dsb; -- 1.6.0.6 |
From: Theuns C. <the...@gm...> - 2009-06-10 06:41:46
|
Hi all, This is the fourth iteration of my set of patches after a rebase from the latest 'master'. You can therefore safely ignore the previous set of patches that I sent to the mailing list. I would appreciate it if we could apply these patches as soon as possible, because each time there is some change to master, I have to rebase and sort out a lot of conflicts which takes a considerable amount of time. During every rebase it is becoming more difficult to remember all the changes that have already been merged and those that still needs to be merged. Feel free to comment and send patches. I think it is time that I put it out there, so that other people can have a look and suggest or make improvements. That's why we switched to Git, right? To make this type of collaboration quicker and easier. The patches include the following: --- begin clustering branch --- 1. This patch includes all the changes I had in my Subversion repository. It includes various updates that range from clustering (mostly) to dynamic environments (less). It also included the dynamic environments stuff that Leo sent through, but it was again merged in a later patch. Git incorporated this into patch 7. This patch also includes the ChargedSwarmInitialisationStrategy which deprecates the ChargedParticleInitialisationStrategy. 2. Renamed a detection strategy. 3. Small cleanup like removing a super() etc. 4. Renamed a method and updated some JavaDoc. 5. Added trivial centroid diversification feature for KMeans. 6. Rebased from the "tabs to spaces" patch. I also fixed my own white space issues. This patch also includes some dynamic environment changes. 7. Added centroid reinitialisation feature for KMeans, as part of centroid initialisation strategy. 8. Update the kmeans.xml file to show examples of using centroid initialisation and diversification. 9. Implemented methods in StatUtils to calculate a variance vector and standard deviation vector. Made use of these methods in clustering measurements. 10. Fixed merge mistakes regarding the pso.dynamic package that were made in previous patches. UPDATE: After another rebase these mistakes were handled correctly in previous patches. This patch can probably be squashed into the next patch. This patch now only contains renames and minor changes regarding the pso.dynamic package. 11. Fixed some mistakes regarding the VonNeumannTopology and CompetitiveCoevolutionParticleReevaluationResponseStrategy that crept in due to the rebase. UPDATE: After another rebase, these mistakes were handled correctly in previous patches. This patch can probably be squashed into the next patch. 12. Various changes that I had to commit in order to rebase. --- end clustering branch --- --- begin multi-threaded-split-coop-alg branch --- NOTE: Patch 13 is still experimental. I would appreciate some feedback. 13. Trying something new: Multi-threaded SplitCooperativeAlgorithm. The idea is to execute each sub-algorithm in its own thread, thereby improving the performance of the SplitCooperateAlgorithm, especially on computers with more than one core. This works very nicely, as long as the algorithm you are using and the problem you are optimising never uses Algorithm.get(), because the algorithm stack is not thread safe. We need some elegant and simple way of getting hold of either the main algorithm or the currently executing sub-algorithm in a thread safe manner. I hope we can find a way by making use of Guice. So try it out and let me know what you think. NOTE: Patch 14 still needs some work. I would appreciate some feedback. 14. Big changes regarding clustering as a result of patch 13. 14.a. The Pattern class was moved to the type.types.container package as Pattern<S extends Vector> and it is now a ForwardingStructuredType<S>. 14.b. The Cluster<Vector> class was introduced which is a Set<Pattern<Vector>>, i.e. also a Type. 14.c. The multi-threaded behaviour of patch 13 caused the entire ClusteringUtils class to break, because it was not thread safe, because it contained state. The ClusteringUtils class was therefore trimmed down and does not contain state anymore. It also makes use of the changes mentioned in 14.a to 14.b. 14.d. Everything else that depend on the clustering code was updated. --- end multi-threaded-split-coop-alg branch --- Look at the commit messages and content of each patch to get a better idea of what each patch contains. |