1 10 package org.jgap.impl; 11 12 import java.io.*; 13 import java.net.*; 14 import java.util.*; 15 import java.lang.reflect.*; 16 import org.jgap.*; 17 18 40 public class CompositeGene 41 extends BaseGene 42 implements ICompositeGene, IPersistentRepresentation { 43 44 private final static String CVS_REVISION = "$Revision: 1.55 $"; 45 46 50 public final static String GENE_DELIMITER = "#"; 51 52 56 public final static String GENE_DELIMITER_HEADING = "<"; 57 58 62 public final static String GENE_DELIMITER_CLOSING = ">"; 63 64 private Gene m_geneTypeAllowed; 65 66 72 private List m_genes; 73 74 83 public CompositeGene() 84 throws InvalidConfigurationException { 85 this(Genotype.getStaticConfiguration()); 86 } 87 88 95 public CompositeGene(Configuration a_config) 96 throws InvalidConfigurationException { 97 this(a_config, null); 98 } 99 100 112 public CompositeGene(final Configuration a_config, 113 final Gene a_geneTypeAllowed) 114 throws InvalidConfigurationException { 115 super(a_config); 116 m_genes = new Vector(); 117 if (a_geneTypeAllowed != null) { 118 m_geneTypeAllowed = a_geneTypeAllowed; 119 } 120 } 121 122 126 public void addGene(final Gene a_gene) { 127 addGene(a_gene, false); 128 } 129 130 136 public Gene getGeneTypeAllowed() { 137 return m_geneTypeAllowed; 138 } 139 140 153 public void addGene(final Gene a_gene, final boolean a_strict) { 154 if (a_gene == null) { 155 throw new IllegalArgumentException ("Gene instance must not be null!"); 156 } 157 if (m_geneTypeAllowed != null) { 158 if (!a_gene.getClass().getName().equals(m_geneTypeAllowed.getClass(). 159 getName())) { 160 throw new IllegalArgumentException ("Adding a " 161 + a_gene.getClass().getName() 162 + " has been forbidden!"); 163 } 164 } 165 boolean containsGene; 168 if (!a_strict) { 169 containsGene = containsGeneByIdentity(a_gene); 170 } 171 else { 172 containsGene = m_genes.contains(a_gene); 173 } 174 if (containsGene) { 175 throw new IllegalArgumentException ("The gene is already contained" 176 + " in the CompositeGene!"); 177 } 178 m_genes.add(a_gene); 179 } 180 181 191 public boolean removeGeneByIdentity(final Gene a_gene) { 192 int size = size(); 193 if (size < 1) { 194 return false; 195 } 196 else { 197 for (int i = 0; i < size; i++) { 198 if (geneAt(i) == a_gene) { 199 m_genes.remove(i); 200 return true; 201 } 202 } 203 } 204 return false; 205 } 206 207 217 public boolean removeGene(final Gene a_gene) { 218 return m_genes.remove(a_gene); 219 } 220 221 228 public void cleanup() { 229 Gene gene; 230 int size = m_genes.size(); 231 for (int i = 0; i < size; i++) { 232 gene = (Gene) m_genes.get(i); 233 gene.cleanup(); 234 } 235 } 236 237 247 public void setToRandomValue(final RandomGenerator a_numberGenerator) { 248 if (a_numberGenerator == null) { 249 throw new IllegalArgumentException ("Random generatoe must not be null!"); 250 } 251 Gene gene; 252 int size = m_genes.size(); 253 for (int i = 0; i < size; i++) { 254 gene = (Gene) m_genes.get(i); 255 gene.setToRandomValue(a_numberGenerator); 256 } 257 } 258 259 271 public void setValueFromPersistentRepresentation(String a_representation) 272 throws UnsupportedRepresentationException { 273 if (a_representation != null) { 274 try { 275 m_genes.clear(); 278 List r = split(a_representation); 279 Iterator iter = r.iterator(); 280 StringTokenizer st; 281 String clas; 282 String representation; 283 String g; 284 Gene gene; 285 while (iter.hasNext()) { 286 g = URLDecoder.decode( (String ) iter.next(), "UTF-8"); 287 st = new StringTokenizer(g, GENE_DELIMITER); 288 if (st.countTokens() != 2) 289 throw new UnsupportedRepresentationException("In " + g + ", " + 290 "expecting two tokens, separated by " + GENE_DELIMITER); 291 clas = st.nextToken(); 292 representation = st.nextToken(); 293 gene = createGene(clas, representation); 294 addGene(gene); 295 } 296 } 297 catch (Exception ex) { 298 throw new UnsupportedRepresentationException(ex.toString()); 299 } 300 } 301 } 302 303 315 protected Gene createGene(String a_geneClassName, 316 String a_persistentRepresentation) 317 throws Exception { 318 Class geneClass = Class.forName(a_geneClassName); 319 Constructor constr = geneClass.getConstructor(new Class [] {Configuration.class}); 320 Gene gene = (Gene) constr.newInstance(new Object [] {getConfiguration()}); 321 gene.setValueFromPersistentRepresentation(a_persistentRepresentation); 322 return gene; 323 } 324 325 335 public String getPersistentRepresentation() 336 throws UnsupportedOperationException { 337 StringBuffer b = new StringBuffer (); 338 Iterator iter = m_genes.iterator(); 339 Gene gene; 340 while (iter.hasNext()) { 341 gene = (Gene) iter.next(); 342 b.append(GENE_DELIMITER_HEADING); 343 try { 344 b.append( 345 URLEncoder.encode( 346 gene.getClass().getName() + 347 GENE_DELIMITER + 348 gene.getPersistentRepresentation(), "UTF-8" 349 )); 350 } 351 catch (UnsupportedEncodingException uex) { 352 throw new RuntimeException ("UTF-8 should always be supported!", uex); 353 } 354 b.append(GENE_DELIMITER_CLOSING); 355 } 356 return b.toString(); 357 } 358 359 370 public Object getAllele() { 371 List alleles = new Vector(); 372 Gene gene; 373 int size = m_genes.size(); 374 for (int i = 0; i < size; i++) { 375 gene = (Gene) m_genes.get(i); 376 alleles.add(gene.getAllele()); 377 } 378 return alleles; 379 } 380 381 392 public void setAllele(Object a_newValue) { 393 if (! (a_newValue instanceof List)) { 394 throw new IllegalArgumentException ( 395 "The expected type of the allele" 396 + " is a List descendent."); 397 } 398 if (getConstraintChecker() != null) { 399 if (!getConstraintChecker().verify(this, a_newValue, null, -1)) { 400 return; 401 } 402 } 403 List alleles = (List) a_newValue; 404 Gene gene; 405 for (int i = 0; i < alleles.size(); i++) { 406 gene = (Gene) m_genes.get(i); 407 gene.setAllele(alleles.get(i)); 408 } 409 } 410 411 421 protected Gene newGeneInternal() { 422 try { 423 CompositeGene compositeGene = new CompositeGene(getConfiguration()); 424 compositeGene.setConstraintChecker(getConstraintChecker()); 425 Gene gene; 426 int geneSize = m_genes.size(); 427 for (int i = 0; i < geneSize; i++) { 428 gene = (Gene) m_genes.get(i); 429 compositeGene.addGene(gene.newGene(), false); 430 } 431 return compositeGene; 432 } 433 catch (InvalidConfigurationException iex) { 434 throw new IllegalStateException (iex.getMessage()); 435 } 436 } 437 438 453 public int compareTo(Object a_other) { 454 if (a_other == null) { 459 return 1; 460 } 461 if (! (a_other instanceof CompositeGene)) { 462 return this.getClass().getName().compareTo(a_other.getClass().getName()); 463 } 464 CompositeGene otherCompositeGene = (CompositeGene) a_other; 465 if (otherCompositeGene.isEmpty()) { 466 if (isEmpty()) { 470 return 0; 471 } 472 else { 473 return 1; 474 } 475 } 476 else { 477 int numberGenes = Math.min(size(), otherCompositeGene.size()); 480 Gene gene1; 481 Gene gene2; 482 for (int i = 0; i < numberGenes; i++) { 483 gene1 = geneAt(i); 484 gene2 = otherCompositeGene.geneAt(i); 485 int result = gene1.compareTo(gene2); 486 if (result != 0) { 487 return result; 488 } 489 } 490 if (size() == otherCompositeGene.size()) { 494 if (isCompareApplicationData()) { 495 return compareApplicationData(getApplicationData(), 496 otherCompositeGene.getApplicationData()); 497 } 498 else { 499 return 0; 500 } 501 } 502 else { 503 if (size() > otherCompositeGene.size()) { 504 return 1; 505 } 506 else { 507 return -1; 508 } 509 } 510 } 511 } 512 513 525 public String toString() { 526 if (m_genes.isEmpty()) { 527 return "CompositeGene=null"; 528 } 529 else { 530 String result = "CompositeGene=("; 531 Gene gene; 532 for (int i = 0; i < m_genes.size(); i++) { 533 gene = (Gene) m_genes.get(i); 534 result += gene; 535 if (i < m_genes.size() - 1) { 536 result += GENE_DELIMITER; 537 } 538 } 539 return result + ")"; 540 } 541 } 542 543 549 public boolean isEmpty() { 550 return m_genes.isEmpty() ? true : false; 551 } 552 553 560 public Gene geneAt(int a_index) { 561 return (Gene) m_genes.get(a_index); 562 } 563 564 570 public int size() { 571 return m_genes.size(); 572 } 573 574 584 public boolean containsGeneByIdentity(Gene gene) { 585 boolean result; 586 int size = size(); 587 if (size < 1) { 588 result = false; 589 } 590 else { 591 result = false; 592 for (int i = 0; i < size; i++) { 593 if (geneAt(i) == gene) { 596 result = true; 597 break; 598 } 599 } 600 } 601 return result; 602 } 603 604 614 public void applyMutation(int a_index, double a_percentage) { 615 throw new RuntimeException ("applyMutation may not be called for " 621 + "a CompositeGene. Call this method for each" 622 + " gene contained in the CompositeGene."); 623 } 624 625 636 protected static final List split(String a_string) 637 throws UnsupportedRepresentationException { 638 List a = Collections.synchronizedList(new ArrayList()); 639 StringTokenizer st = new StringTokenizer 640 (a_string, GENE_DELIMITER_HEADING + GENE_DELIMITER_CLOSING, true); 641 while (st.hasMoreTokens()) { 642 if (!st.nextToken().equals(GENE_DELIMITER_HEADING)) { 643 throw new UnsupportedRepresentationException(a_string + " no open tag"); 644 } 645 String n = st.nextToken(); 646 if (n.equals(GENE_DELIMITER_CLOSING)) { 647 a.add(""); 648 } 649 else { 650 a.add(n); 651 if (!st.nextToken().equals(GENE_DELIMITER_CLOSING)) { 652 throw new UnsupportedRepresentationException 653 (a_string + " no close tag"); 654 } 655 } 656 } 657 return a; 658 } 659 660 668 public int hashCode() { 669 int hashCode = 1; 670 int geneHashcode; 671 for (int i = 0; i < size(); i++) { 672 geneHashcode = geneAt(i).hashCode(); 673 hashCode = 31 * hashCode + geneHashcode; 674 } 675 return hashCode; 676 } 677 678 683 protected Object getInternalValue() { 684 return null; 685 } 686 } 687 | Popular Tags |