1 | package de.uka.ipd.sdq.dsexplore.opt4j.representation; |
2 | |
3 | import java.util.Set; |
4 | |
5 | import org.apache.log4j.Logger; |
6 | import org.opt4j.core.problem.Genotype; |
7 | import org.opt4j.core.Individual; |
8 | import org.opt4j.core.IndividualStateListener; |
9 | import org.opt4j.core.Objectives; |
10 | |
11 | import de.uka.ipd.sdq.dsexplore.opt4j.genotype.DesignDecisionGenotype; |
12 | import de.uka.ipd.sdq.dsexplore.opt4j.start.Opt4JStarter; |
13 | import de.uka.ipd.sdq.pcm.designdecision.DecisionSpace; |
14 | |
15 | |
16 | public class DSEIndividual extends Individual { |
17 | |
18 | |
19 | private DecisionSpace problem; |
20 | |
21 | public DSEIndividual(DecisionSpace problem){ |
22 | this.problem = problem; |
23 | } |
24 | |
25 | protected DSEIndividual(){ |
26 | this.problem = Opt4JStarter.getProblem().getEMFProblem(); |
27 | } |
28 | |
29 | /** Logger for log4j. */ |
30 | private static Logger logger = |
31 | Logger.getLogger("de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEIndividual"); |
32 | |
33 | |
34 | @Override |
35 | public DesignDecisionGenotype getGenotype(){ |
36 | return (DesignDecisionGenotype)super.getGenotype(); |
37 | } |
38 | |
39 | |
40 | |
41 | /** |
42 | * Checks the equality of this and o. |
43 | * Returns false if o is not a DSEIndividual or subtype. |
44 | * If both this and o are not genotyped, super.equals(o) is called. |
45 | * Returns false if either this or o (exclusive) are not genotyped. |
46 | * Finally, if none of the above matches, this method returns whether the |
47 | * genotype strings of o and this are equal. |
48 | * @param o The other object |
49 | * @return true if o and this are equal as defined above. |
50 | */ |
51 | @Override |
52 | public boolean equals(Object o){ |
53 | if (o == this){ |
54 | return true; |
55 | } |
56 | if (!(o instanceof DSEIndividual)){ |
57 | return false; |
58 | } else { |
59 | DSEIndividual other = (DSEIndividual)o; |
60 | String otherGenotypeString = other.getGenotypeString(); |
61 | String myGenotypeString = this.getGenotypeString(); |
62 | if (otherGenotypeString == null && myGenotypeString == null){ |
63 | return super.equals(other); |
64 | } else if (otherGenotypeString == null || myGenotypeString == null){ |
65 | // I need to say we are not equal and cannot ask my super type, |
66 | // because of the hash code equivalence rule. |
67 | // If the other does not have a genotype string, but I do, and |
68 | // my super type says we are equal, then there is a conflict |
69 | // because the hash codes are not equal. |
70 | return false; |
71 | } else { |
72 | return otherGenotypeString.equals(myGenotypeString); |
73 | } |
74 | } |
75 | |
76 | |
77 | } |
78 | |
79 | /** |
80 | * |
81 | * @return may be null if this individual does not have a genotype yet. |
82 | */ |
83 | public String getGenotypeString() { |
84 | if (genotype instanceof DesignDecisionGenotype){ |
85 | String genotypeString = DSEDecoder.getGenotypeString((DesignDecisionGenotype)genotype); |
86 | return genotypeString; |
87 | } else { |
88 | throw new RuntimeException("DSEIndividual cannot handle arbitrary genotypes yet, fix the code"); |
89 | } |
90 | } |
91 | |
92 | /** |
93 | * {@inheritDoc} |
94 | */ |
95 | @Override |
96 | public void setIndividualStatusListeners( |
97 | Set<IndividualStateListener> individualStateListeners) { |
98 | super.setIndividualStatusListeners(individualStateListeners); |
99 | } |
100 | |
101 | /** |
102 | * Returns the hash code of the getGenotypeString() string if this individual |
103 | * is already genotyped. Returns super.hashCode() if this inidividual is not |
104 | * yet genotyped. |
105 | */ |
106 | @Override |
107 | public int hashCode(){ |
108 | if (this.genotype != null){ |
109 | return this.getGenotypeString().hashCode(); |
110 | } else { |
111 | return super.hashCode(); |
112 | } |
113 | |
114 | } |
115 | |
116 | /** |
117 | * Returns the objectives. |
118 | * |
119 | * @return the objectives |
120 | */ |
121 | @Override |
122 | public DSEObjectives getObjectives() { |
123 | return (DSEObjectives)super.getObjectives(); |
124 | } |
125 | |
126 | /** |
127 | * Sets the objectives. They have to be instances of type {@link DSEObjective}, or |
128 | * an {@link IllegalArgumentException} is thrown |
129 | * |
130 | * @param objectives |
131 | * the objectives to be set |
132 | * @throws IllegalArgumentException if objectives are not of type |
133 | * {@link DSEObjective}. |
134 | */ |
135 | @Override |
136 | public void setObjectives(Objectives objectives) { |
137 | if (! (objectives instanceof DSEObjectives)){ |
138 | String error = "DSEIndividual only supports DSEObjectives to contain the analysis results. Contact developers."; |
139 | logger.error(error); |
140 | throw new IllegalArgumentException(error); |
141 | } |
142 | super.setObjectives(objectives); |
143 | } |
144 | |
145 | public String getID() { |
146 | return this.getGenotypeString(); |
147 | } |
148 | |
149 | public long getNumericID() { |
150 | return this.getGenotype().getNumericID(); |
151 | } |
152 | |
153 | public DecisionSpace getProblem(){ |
154 | return this.problem; |
155 | } |
156 | |
157 | } |