1 | /* |
---|
2 | Copyright 2006 by Sean Luke |
---|
3 | Licensed under the Academic Free License version 3.0 |
---|
4 | See the file "LICENSE" for more information |
---|
5 | */ |
---|
6 | |
---|
7 | |
---|
8 | package ec.vector; |
---|
9 | |
---|
10 | import ec.*; |
---|
11 | import ec.util.*; |
---|
12 | import java.io.*; |
---|
13 | |
---|
14 | |
---|
15 | /* |
---|
16 | * VectorGene.java |
---|
17 | * Created: Thu Mar 22 13:13:20 EST 2001 |
---|
18 | */ |
---|
19 | |
---|
20 | /** |
---|
21 | * VectorGene is an abstract superclass of objects which may be used in |
---|
22 | * the genome array of GeneVectorIndividuals. |
---|
23 | * |
---|
24 | |
---|
25 | * <p>In addition to serialization for checkpointing, VectorGenes may read and write themselves to streams in three ways. |
---|
26 | * |
---|
27 | * <ul> |
---|
28 | * <li><b>writeGene(...,DataOutput)/readGene(...,DataInput)</b> This method |
---|
29 | * transmits or receives a VectorGene in binary. It is the most efficient approach to sending |
---|
30 | * VectorGenes over networks, etc. The default versions of writeGene/readGene throw errors. |
---|
31 | * You don't need to implement them if you don't plan on using read/writeGene. |
---|
32 | * |
---|
33 | * <li><b>printGene(...,PrintWriter)/readGene(...,LineNumberReader)</b> This |
---|
34 | * approach transmits or receives a VectorGene in text encoded such that the VectorGene is largely readable |
---|
35 | * by humans but can be read back in 100% by ECJ as well. To do this, these methods will typically encode numbers |
---|
36 | * using the <tt>ec.util.Code</tt> class. These methods are mostly used to write out populations to |
---|
37 | * files for inspection, slight modification, then reading back in later on. <b>readGene</b> |
---|
38 | * reads in a line, then calls <b>readGeneFromString</b> on that line. |
---|
39 | * You are responsible for implementing readGeneFromString: the Code class is there to help you. |
---|
40 | * The default version throws an error if called. |
---|
41 | * <b>printGene</b> calls <b>printGeneToString<b> |
---|
42 | * and printlns the resultant string. You are responsible for implementing the printGeneToString method in such |
---|
43 | * a way that readGeneFromString can read back in the VectorGene println'd with printGeneToString. The default form |
---|
44 | * of printGeneToString() simply calls <b>toString()</b> |
---|
45 | * by default. You might override <b>printGeneToString()</b> to provide better information. You are not required to implement these methods, but without |
---|
46 | * them you will not be able to write VectorGenes to files in a simultaneously computer- and human-readable fashion. |
---|
47 | * |
---|
48 | * <li><b>printGeneForHumans(...,PrintWriter)</b> This |
---|
49 | * approach prints a VectorGene in a fashion intended for human consumption only. |
---|
50 | * <b>printGeneForHumans</b> calls <b>printGeneToStringForHumans()<b> |
---|
51 | * and printlns the resultant string. The default form of this method just returns the value of |
---|
52 | * <b>toString()</b>. You may wish to override this to provide more information instead. |
---|
53 | * You should handle one of these methods properly |
---|
54 | * to ensure VectorGenes can be printed by ECJ. |
---|
55 | * </ul> |
---|
56 | |
---|
57 | <p><b>Default Base</b><br> |
---|
58 | vector.vect-gene |
---|
59 | |
---|
60 | * @author Sean Luke |
---|
61 | * @version 1.0 |
---|
62 | */ |
---|
63 | public abstract class VectorGene implements Prototype |
---|
64 | { |
---|
65 | public static final String P_VECTORGENE = "vect-gene"; |
---|
66 | |
---|
67 | public void setup(final EvolutionState state, final Parameter base) |
---|
68 | { |
---|
69 | // nothing by default |
---|
70 | } |
---|
71 | |
---|
72 | public Parameter defaultBase() |
---|
73 | { |
---|
74 | return VectorDefaults.base().push(P_VECTORGENE); |
---|
75 | } |
---|
76 | |
---|
77 | public Object clone() |
---|
78 | { |
---|
79 | try { return super.clone(); } |
---|
80 | catch (CloneNotSupportedException e) |
---|
81 | { throw new InternalError(); } // never happens |
---|
82 | } |
---|
83 | |
---|
84 | |
---|
85 | |
---|
86 | /** Generates a hash code for this gene -- the rule for this is that the hash code |
---|
87 | must be the same for two genes that are equal to each other genetically. */ |
---|
88 | public abstract int hashCode(); |
---|
89 | |
---|
90 | /** Unlike the standard form for Java, this function should return true if this |
---|
91 | gene is "genetically identical" to the other gene. */ |
---|
92 | public abstract boolean equals( final Object other ); |
---|
93 | |
---|
94 | /** |
---|
95 | The reset method randomly reinitializes the gene. |
---|
96 | */ |
---|
97 | public abstract void reset(final EvolutionState state, final int thread); |
---|
98 | |
---|
99 | /** |
---|
100 | Mutate the gene. The default form just resets the gene. |
---|
101 | */ |
---|
102 | public void mutate(final EvolutionState state, final int thread) |
---|
103 | { |
---|
104 | reset(state,thread); |
---|
105 | } |
---|
106 | |
---|
107 | /** |
---|
108 | Nice printing. The default form simply calls printGeneToStringForHumans and prints the result, |
---|
109 | but you might want to override this. |
---|
110 | */ |
---|
111 | public void printGeneForHumans( final EvolutionState state, final int verbosity, final int log ) |
---|
112 | { state.output.println(printGeneToStringForHumans(),log); } |
---|
113 | |
---|
114 | /** Prints the gene to a string in a human-readable fashion. The default simply calls toString(). */ |
---|
115 | public String printGeneToStringForHumans() |
---|
116 | { return toString(); } |
---|
117 | |
---|
118 | /** Prints the gene to a string in a fashion readable by readGeneFromString and parseable by readGene(state, reader). |
---|
119 | Override this. The default form returns toString(). */ |
---|
120 | public String printGeneToString() |
---|
121 | { return toString(); } |
---|
122 | |
---|
123 | /** Reads a gene from a string, which may contain a final '\n'. |
---|
124 | Override this method. The default form generates an error. |
---|
125 | */ |
---|
126 | public void readGeneFromString(final String string, final EvolutionState state) |
---|
127 | { state.output.error("readGeneFromString(string,state) unimplemented in " + this.getClass()); } |
---|
128 | |
---|
129 | /** |
---|
130 | Prints the gene in a way that can be read by readGene(). The default form simply |
---|
131 | calls printGeneToString(). Override this gene to do custom writing to the log, |
---|
132 | or just override printGeneToString(...), which is probably easier to do. |
---|
133 | */ |
---|
134 | public void printGene( final EvolutionState state, final int verbosity, final int log ) |
---|
135 | { state.output.println(printGeneToString(),log); } |
---|
136 | |
---|
137 | /** |
---|
138 | Prints the gene in a way that can be read by readGene(). The default form simply |
---|
139 | calls printGeneToString(state). Override this gene to do custom writing, |
---|
140 | or just override printGeneToString(...), which is probably easier to do. |
---|
141 | */ |
---|
142 | public void printGene( final EvolutionState state, final PrintWriter writer ) |
---|
143 | { writer.println(printGeneToString()); } |
---|
144 | |
---|
145 | /** |
---|
146 | Reads a gene printed by printGene(...). The default form simply reads a line into |
---|
147 | a string, and then calls readGeneFromString() on that line. Override this gene to do |
---|
148 | custom reading, or just override readGeneFromString(...), which is probably easier to do. |
---|
149 | */ |
---|
150 | public void readGene(final EvolutionState state, |
---|
151 | final LineNumberReader reader) |
---|
152 | throws IOException |
---|
153 | { readGeneFromString(reader.readLine(),state); } |
---|
154 | |
---|
155 | /** Override this if you need to write rules out to a binary stream */ |
---|
156 | public void writeGene(final EvolutionState state, |
---|
157 | final DataOutput dataOutput) throws IOException |
---|
158 | { |
---|
159 | state.output.fatal("writeGene(EvolutionState, DataOutput) not implemented in " + this.getClass()); |
---|
160 | } |
---|
161 | |
---|
162 | /** Override this if you need to read rules in from a binary stream */ |
---|
163 | public void readGene(final EvolutionState state, |
---|
164 | final DataInput dataInput) throws IOException |
---|
165 | { |
---|
166 | state.output.fatal("readGene(EvolutionState, DataInput) not implemented in " + this.getClass()); |
---|
167 | } |
---|
168 | |
---|
169 | } |
---|