1 10 package org.jgap.supergenes; 11 12 import java.io.*; 13 import java.lang.reflect.*; 14 import java.net.*; 15 import java.util.*; 16 import org.jgap.*; 17 18 30 public abstract class AbstractSupergene 31 extends BaseGene 32 implements Supergene, SupergeneValidator, IPersistentRepresentation { 33 34 private final static String CVS_REVISION = "$Revision: 1.21 $"; 35 36 40 public final static String GENE_DELIMITER = "#"; 41 42 46 public final static String GENE_DELIMITER_HEADING = "<"; 47 48 52 public final static String GENE_DELIMITER_CLOSING = ">"; 53 54 59 public final static int MAX_RETRIES = 1; 60 61 65 public final static int MAX_IMMUTABLE_GENES = 100000; 66 67 68 private Gene[] m_genes; 69 70 71 private static Set[] m_immutable = new Set[1]; 72 73 77 public Gene[] getGenes() { 78 return m_genes; 79 } 80 81 93 public final Gene geneAt(final int a_index) { 94 return m_genes[a_index]; 95 }; 96 97 105 public AbstractSupergene() 106 throws InvalidConfigurationException { 107 this(Genotype.getStaticConfiguration(), new Gene[]{}); 108 } 109 110 119 public AbstractSupergene(final Configuration a_config) 120 throws InvalidConfigurationException { 121 this(a_config, new Gene[]{}); 122 } 123 124 131 public AbstractSupergene(final Configuration a_conf, final Gene[] a_genes) 132 throws InvalidConfigurationException { 133 super(a_conf); 134 if (a_genes == null) { 135 throw new RuntimeException ("null value for genes not allowed!"); 136 } 137 m_genes = a_genes; 138 } 139 140 146 public boolean isValid() { 147 if (m_validator == null) { 148 return true; 149 } 150 else { 151 return m_validator.isValid(m_genes, this); 152 } 153 } 154 155 175 public boolean isValid(final Gene[] a_case, final Supergene a_forSupergene) { 176 throw new Error ("For " + getClass().getName() + ", override " 177 + " isValid (Gene[], Supergene) or set an" 178 + " external validator."); 179 } 180 181 193 protected Gene newGeneInternal() { 194 Gene[] g = new Gene[m_genes.length]; 195 for (int i = 0; i < m_genes.length; i++) { 196 g[i] = m_genes[i].newGene(); 197 } 198 try { 199 Constructor constr = getClass().getConstructor(new Class [] {Configuration.class, Gene[].class}); 200 AbstractSupergene age = 201 (AbstractSupergene) constr.newInstance(new Object [] {getConfiguration(), getGenes()}); 202 if (m_validator != this) { 203 age.setValidator(m_validator); 204 } 205 age.m_genes = g; 206 return age; 207 } 208 catch (Exception ex) { 209 ex.printStackTrace(); 210 throw new Error ( 211 "This should not happen. Is the constructor with parameters " 212 + "{org.jgap.Configuration, org,jgap,Gene[]} provided for " 213 + getClass().getName() + "?"); 214 } 215 } 216 217 224 public void applyMutation(final int a_index, final double a_percentage) { 225 if (a_index < m_immutable.length) { 229 if (m_immutable[a_index] != null) { 230 synchronized (m_immutable) { 231 if (m_immutable[a_index].contains(this)) { 232 return; 233 } 234 } 235 } 236 } 237 Object backup = m_genes[a_index].getAllele(); 244 for (int i = 0; i < MAX_RETRIES; i++) { 245 m_genes[a_index].applyMutation(0, a_percentage); 246 if (isValid()) { 247 return; 248 } 249 } 250 m_genes[a_index].setAllele(backup); 252 markImmutable(a_index); 253 } 254 255 258 private void markImmutable(final int a_index) { 259 synchronized (m_immutable) { 260 if (m_immutable.length <= a_index) { 261 Set[] r = new Set[2 * m_immutable.length]; 264 System.arraycopy(m_immutable, 0, r, 0, m_immutable.length); 265 m_immutable = r; 266 } 267 if (m_immutable[a_index] == null) { 268 m_immutable[a_index] = new TreeSet(); 269 } 270 if (m_immutable[a_index].size() < MAX_IMMUTABLE_GENES) { 271 m_immutable[a_index].add(this); 272 } 273 } 274 ; 275 } 276 277 284 public static void reset() { 285 m_immutable = new Set[1]; 286 } 287 288 295 public void setToRandomValue(final RandomGenerator a_numberGenerator) { 296 for (int i = 0; i < m_genes.length; i++) { 298 m_genes[i].setToRandomValue(a_numberGenerator); 299 } 300 if (isValid()) { 301 return; 302 } 303 for (int i = 0; i < MAX_RETRIES; i++) { 304 for (int j = 0; j < m_genes.length; j++) { 305 m_genes[j].setToRandomValue(a_numberGenerator); 308 if (isValid()) { 309 return; 310 } 311 } 312 } 313 } 314 315 320 public void setAllele(final Object a_superAllele) { 321 if (m_genes.length < 1) { 322 return; 324 } 325 Object [] a = (Object []) a_superAllele; 326 if (a.length != m_genes.length) { 327 throw new IllegalArgumentException ("Record length, " + a.length 328 + " not equal to " 329 + m_genes.length); 330 } 331 for (int i = 0; i < m_genes.length; i++) { 332 m_genes[i].setAllele(a[i]); 333 } 334 } 335 336 340 public Object getAllele() { 341 Object [] o = new Object [m_genes.length]; 342 for (int i = 0; i < m_genes.length; i++) { 343 o[i] = m_genes[i].getAllele(); 344 } 345 return o; 346 } 347 348 353 public String getPersistentRepresentation() { 354 StringBuffer b = new StringBuffer (); 355 String validator = null; 357 String v_representation = ""; 358 SupergeneValidator v = getValidator(); 359 if (v == null) { 360 validator = "null"; 361 } 362 else 363 if (v == this) { 364 validator = "this"; 365 } 366 else { 367 validator = v.getClass().getName(); 368 v_representation = v.getPersistent(); 369 } 370 b.append(GENE_DELIMITER_HEADING); 371 b.append(encode(validator + GENE_DELIMITER + v_representation)); 372 b.append(GENE_DELIMITER_CLOSING); 373 Gene gene; 375 for (int i = 0; i < m_genes.length; i++) { 376 gene = m_genes[i]; 377 b.append(GENE_DELIMITER_HEADING); 378 b.append(encode(gene.getClass().getName() + GENE_DELIMITER 379 + gene.getPersistentRepresentation())); 380 b.append(GENE_DELIMITER_CLOSING); 381 } 382 return b.toString(); 383 } 384 385 401 public void setValueFromPersistentRepresentation(String a_representation) 402 throws UnsupportedRepresentationException { 403 if (a_representation != null) { 404 try { 405 List r = split(a_representation); 408 Iterator iter = r.iterator(); 409 m_genes = new Gene[r.size() - 1]; 410 StringTokenizer st; 413 String clas; 414 String representation; 415 String g; 416 Gene gene; 417 String validator = (String ) iter.next(); 418 setValidator(createValidator(decode(validator))); 419 for (int i = 0; i < m_genes.length; i++) { 420 g = decode( (String ) iter.next()); 421 st = new StringTokenizer(g, GENE_DELIMITER); 422 if (st.countTokens() != 2) 423 throw new UnsupportedRepresentationException("In " + g + ", " + 424 "expecting two tokens, separated by " + GENE_DELIMITER); 425 clas = st.nextToken(); 426 representation = st.nextToken(); 427 gene = createGene(clas, representation); 428 m_genes[i] = gene; 429 } 430 } 431 catch (Exception ex) { 432 ex.printStackTrace(); 433 throw new UnsupportedRepresentationException(ex.getCause(). 434 getMessage()); 435 } 436 } 437 else { 438 throw new UnsupportedRepresentationException("null value not allowed"); 439 } 440 } 441 442 443 protected SupergeneValidator createValidator(String a_rep) { 444 try { 445 StringTokenizer vo = new StringTokenizer 446 (a_rep, GENE_DELIMITER, true); 447 if (vo.countTokens() != 2)throw new Error 448 ("In " + a_rep + ", expecting two tokens, separated by " + 449 GENE_DELIMITER); 450 String clas = vo.nextToken(); 451 SupergeneValidator sv; 452 if (clas.equals("this")) { 453 sv = this; 454 } 455 else if (clas.equals("null")) { 456 sv = null; 457 } 458 else { 459 Class svClass = Class.forName(clas); 461 Constructor constr = svClass.getConstructor(new Class [] {Configuration.class}); 462 sv = (SupergeneValidator) constr.newInstance(new Object [] { 463 getConfiguration()}); 464 } 465 if (sv != null) { 466 sv.setFromPersistent(decode(vo.nextToken())); 467 } 468 return sv; 469 } 470 catch (Exception ex) { 471 throw new Error 472 ("Unable to create validator from '" + a_rep + "' for " + 473 getClass().getName(), ex); 474 } 475 } 476 477 478 protected Gene createGene(String a_geneClassName, 479 String a_persistentRepresentation) 480 throws Exception { 481 Class geneClass = Class.forName(a_geneClassName); 482 Constructor constr = geneClass.getConstructor(new Class [] {Configuration.class}); 483 Gene gene = (Gene) constr.newInstance(new Object [] {getConfiguration()}); 484 gene.setValueFromPersistentRepresentation(a_persistentRepresentation); 485 return gene; 486 } 487 488 489 public void cleanup() { 490 for (int i = 0; i < m_genes.length; i++) { 491 m_genes[i].cleanup(); 492 } 493 } 494 495 499 public String toString() { 500 StringBuffer b = new StringBuffer (); 501 b.append("Supergene " + getClass().getName() + " {"); 502 for (int i = 0; i < m_genes.length; i++) { 503 b.append("|"); 504 b.append(m_genes[i].toString()); 505 b.append("|"); 506 } 507 if (m_validator == null) { 508 b.append(" non validating"); 509 } 510 else { 511 b.append(" validator: "+m_validator.getClass().getName()); 512 } 513 b.append("}"); 514 return b.toString(); 515 } 516 517 518 public int size() { 519 return m_genes.length; 520 } 521 522 524 public int compareTo(Object o) { 525 AbstractSupergene q = (AbstractSupergene) o; 526 int c = m_genes.length - q.m_genes.length; 527 if (c != 0) { 528 return c; 529 } 530 for (int i = 0; i < m_genes.length; i++) { 531 c = m_genes[i].compareTo(q.m_genes[i]); 532 if (c != 0) { 533 return c; 534 } 535 } 536 if (getClass().equals(o.getClass())) { 537 return 0; 538 } 539 return getClass().getName().compareTo(o.getClass().getName()); 540 } 541 542 548 public boolean equals(Object a_gene) { 549 if (a_gene == null || ! (a_gene.getClass().equals(getClass()))) { 550 return false; 551 } 552 AbstractSupergene age = (AbstractSupergene) a_gene; 553 if (m_validator != age.m_validator) 554 if (m_validator != null && age.m_immutable != null) 555 if (!m_validator.getClass().equals(age.m_validator.getClass())) 556 return false; 557 return Arrays.equals(m_genes, age.m_genes); 558 } 559 560 561 public int hashCode() { 562 int s = 0; 563 for (int i = m_genes.length - 1; i >= 0; i--) { 564 s += m_genes[i].hashCode(); 565 } 566 return s; 567 } 568 569 570 protected static final String encode(String a_x) { 571 try { 572 return URLEncoder.encode(a_x, "UTF-8"); 573 } 574 catch (UnsupportedEncodingException ex) { 575 throw new Error ("This should never happen!"); 576 } 577 } 578 579 580 protected static final String decode(String a_x) { 581 try { 582 return URLDecoder.decode(a_x, "UTF-8"); 583 } 584 catch (UnsupportedEncodingException ex) { 585 throw new Error ("This should never happen!"); 586 } 587 } 588 589 597 protected static final List split(String a_string) 598 throws UnsupportedRepresentationException { 599 List a = Collections.synchronizedList(new ArrayList()); 600 StringTokenizer st = new StringTokenizer 601 (a_string, GENE_DELIMITER_HEADING + GENE_DELIMITER_CLOSING, true); 602 while (st.hasMoreTokens()) { 603 if (!st.nextToken().equals(GENE_DELIMITER_HEADING)) { 604 throw new UnsupportedRepresentationException 605 (a_string + " no open tag"); 606 } 607 String n = st.nextToken(); 608 if (n.equals(GENE_DELIMITER_CLOSING)) a.add(""); else { 610 a.add(n); 611 if (!st.nextToken().equals(GENE_DELIMITER_CLOSING)) { 612 throw new UnsupportedRepresentationException 613 (a_string + " no close tag"); 614 } 615 } 616 } 617 return a; 618 } 619 620 621 public void addGene(Gene a_gene) { 622 Gene[] genes = new Gene[m_genes.length + 1]; 623 System.arraycopy(m_genes, 0, genes, 0, m_genes.length); 624 genes[m_genes.length] = a_gene; 625 m_genes = genes; 626 } 627 628 634 public void setValidator(SupergeneValidator a_validator) { 635 m_validator = a_validator; 636 } 637 638 643 public SupergeneValidator getValidator() { 644 return m_validator; 645 } 646 647 648 protected SupergeneValidator m_validator = this; 649 650 652 public String getPersistent() { 653 return ""; 654 } 655 656 658 public void setFromPersistent(String a_from) { 659 } 660 661 664 public Object getInternalValue() { 665 if (true) { 666 throw new RuntimeException ("getInternalValue() called unexpectedly!"); 667 } 668 return null; 669 } 670 } 671 | Popular Tags |