1 10 package org.jgap.impl; 11 12 import java.lang.reflect.*; 13 import java.util.*; 14 import org.jgap.*; 15 16 33 public class MapGene 34 extends BaseGene implements IPersistentRepresentation{ 35 36 private final static String CVS_REVISION = "$Revision: 1.21 $"; 37 38 41 private Map m_geneMap; 42 43 46 private Object m_value; 47 48 51 final static String ALLELEMAP_BEGIN_DELIMITER = "["; 52 53 final static String ALLELEMAP_END_DELIMITER = "]"; 54 55 63 public MapGene() 64 throws InvalidConfigurationException { 65 this(Genotype.getStaticConfiguration()); 66 } 67 68 75 public MapGene(final Configuration a_config) 76 throws InvalidConfigurationException { 77 super(a_config); 78 m_geneMap = new HashMap(); 79 } 80 81 90 public MapGene(final Configuration a_config, final Map a_alleles) 91 throws InvalidConfigurationException { 92 super(a_config); 93 m_geneMap = new HashMap(); 94 addAlleles(a_alleles); 95 } 96 97 protected Gene newGeneInternal() { 98 try { 99 MapGene result = new MapGene(getConfiguration(), m_geneMap); 100 Object value = getAllele(); 102 result.setAllele(value); 103 return result; 104 } 105 catch (InvalidConfigurationException iex) { 106 throw new IllegalStateException (iex.getMessage()); 107 } 108 } 109 110 117 public void addAllele(final Object a_key, final Object a_value) { 118 m_geneMap.put(a_key, a_value); 119 } 120 121 129 public void addAllele(final Object a_value) { 130 m_geneMap.put(a_value, a_value); 131 } 132 133 141 public void addAllele(final int a_value) { 142 m_geneMap.put(new Integer (a_value), new Integer (a_value)); 143 } 144 145 152 public void addAlleles(final Map a_alleles) { 153 if (a_alleles == null) { 154 throw new IllegalArgumentException ("List of alleles may not be null!"); 155 } 156 else { 157 m_geneMap.putAll(a_alleles); 158 } 159 } 160 161 168 public void removeAlleles(final Object a_key) { 169 m_geneMap.remove(a_key); 170 } 171 172 178 public Map getAlleles() { 179 return m_geneMap; 180 } 181 182 194 public void setToRandomValue(final RandomGenerator a_numberGenerator) { 195 if (m_geneMap.isEmpty()) { 196 m_value = new Integer (a_numberGenerator.nextInt()); 197 } 198 else { 199 m_value = m_geneMap.get(m_geneMap.keySet().toArray()[a_numberGenerator. 200 nextInt(m_geneMap.size())]); 201 } 202 } 203 204 220 public void applyMutation(final int a_index, final double a_percentage) { 221 RandomGenerator rn; 222 rn = getConfiguration().getRandomGenerator(); 223 setToRandomValue(rn); 224 } 225 226 246 public void setValueFromPersistentRepresentation(final String 247 a_representation) 248 throws UnsupportedRepresentationException { 249 if (a_representation != null) { 250 StringTokenizer tokenizer = new StringTokenizer(a_representation, 251 PERSISTENT_FIELD_DELIMITER); 252 if (tokenizer.countTokens() != 2) { 256 throw new UnsupportedRepresentationException( 257 "The format of the given persistent representation " + 258 "is not recognized: it must contain two tokens."); 259 } 260 String valueRepresentation = tokenizer.nextToken(); 261 if (valueRepresentation.equals("null")) { 264 m_value = null; 265 } 266 else { 267 try { 268 m_value = new Integer (Integer.parseInt(valueRepresentation)); 269 } 270 catch (NumberFormatException e) { 271 throw new UnsupportedRepresentationException( 272 "The format of the given persistent representation " + 273 "is not recognized: field 1 does not appear to be " + 274 "an integer value."); 275 } 276 } 277 String s = tokenizer.nextToken(); 280 tokenizer = new StringTokenizer(s, ","); 281 int lastWasOpening = 0; 282 String key = null; 283 String keyClass = null; 284 String valueClass = null; 285 while (tokenizer.hasMoreTokens()) { 286 String element = tokenizer.nextToken(","); 287 if (lastWasOpening == 1) { 288 key = element.substring(0); 289 lastWasOpening = 2; 290 } 291 else if (lastWasOpening == 2) { 292 valueClass = element.substring(0); 293 lastWasOpening = 3; 294 } 295 else if (lastWasOpening == 3) { 296 if (element.endsWith(")")) { 297 element = element.substring(0, element.length() - 1); 298 try { 299 Class keyType = Class.forName(keyClass); 300 Constructor keyC = keyType.getConstructor(new Class []{String .class}); 301 Object keyObject = keyC.newInstance(new Object []{key}); 302 303 Class valueType = Class.forName(valueClass); 304 Constructor valueC = valueType.getConstructor(new Class []{String .class}); 305 Object valueObject = valueC.newInstance(new Object []{element}); 306 addAllele(keyObject, valueObject); 307 lastWasOpening = 0; 308 } catch (Exception cex) { 309 throw new UnsupportedRepresentationException("Invalid class: " 310 + keyClass); 311 } 312 } 313 else { 314 throw new IllegalStateException ("Closing bracket missing"); 315 } 316 } 317 else { 318 if (element.startsWith("(")) { 319 keyClass = element.substring(1); 320 lastWasOpening = 1; 321 } 322 else { 323 throw new IllegalStateException ("Opening bracket missing"); 324 } 325 } 326 } 327 if (lastWasOpening != 0) { 328 throw new IllegalStateException ("Elements missing"); 329 } 330 } 331 } 332 333 350 public String getPersistentRepresentation() 351 throws UnsupportedOperationException { 352 Iterator it = m_geneMap.keySet().iterator(); 356 StringBuffer strbf = new StringBuffer (); 357 boolean first = true; 358 while (it.hasNext()) { 359 if (!first) { 360 strbf.append(","); 361 } 362 Object key = it.next(); 363 Object value = m_geneMap.get(key); 364 strbf.append("(" + key.getClass().getName() + "," + key.toString() + "," + 365 value.getClass().getName() + "," + value.toString() + ")"); 366 first = false; 367 } 368 return m_value.toString() + MapGene.PERSISTENT_FIELD_DELIMITER + 369 strbf.toString(); 370 } 371 372 381 public void setAllele(Object a_newValue) { 382 if (a_newValue == null) { 385 return; 386 } 387 if (m_geneMap.keySet().isEmpty()) { 388 m_value = a_newValue; 389 } 390 else if (m_geneMap.keySet().contains(a_newValue)) { 391 m_value = m_geneMap.get(a_newValue); 392 } 393 else { 394 throw new IllegalArgumentException ("Allele value being set (" 395 + a_newValue 396 + ") is not an element of the set of" 397 + " permitted values."); 398 } 399 } 400 401 417 public int compareTo(Object a_other) { 418 MapGene otherGene = (MapGene) a_other; 419 if (otherGene == null) { 424 return 1; 425 } 426 else if (otherGene.m_value == null) { 427 if (m_value != null) { 430 return 1; 431 } 432 } 433 try { 434 int size1 = m_geneMap.size(); 435 int size2 = otherGene.m_geneMap.size(); 436 if (size1 != size2) { 437 if (size1 < size2) { 438 return -1; 439 } 440 else { 441 return 1; 442 } 443 } 444 else { 445 Iterator it1 = m_geneMap.keySet().iterator(); 447 while (it1.hasNext()) { 449 Object key1 = it1.next(); 450 if (!otherGene.m_geneMap.keySet().contains(key1)) { 451 Object key2 = otherGene.m_geneMap.keySet().iterator().next(); 452 if (Comparable .class.isAssignableFrom(key1.getClass()) 453 && Comparable .class.isAssignableFrom(key2.getClass())) { 454 return ( (Comparable ) key1).compareTo(key2); 455 } 456 else { 457 return -1; 459 } 460 } 461 Object value1 = m_geneMap.get(key1); 462 Object value2 = otherGene.m_geneMap.get(key1); 463 if (value1 == null && value2 != null) { 464 return -1; 465 } 466 else if (value1 == null && value2 != null) { 467 return -1; 468 } 469 else if (!value1.equals(value2)) { 470 if (value2 == null) { 471 return 1; 472 } 473 else { 474 if (Comparable .class.isAssignableFrom(value1.getClass()) 475 && Comparable .class.isAssignableFrom(value2.getClass())) { 476 return ( (Comparable ) value1).compareTo(value2); 477 } 478 else { 479 return -1; 481 } 482 } 483 } 484 } 485 } 486 if (m_value == null) { 487 if (otherGene.m_value != null) { 488 return 1; 489 } 490 else { 491 return 0; 492 } 493 } 494 Method method = m_value.getClass().getMethod("compareTo", 495 new Class [] {otherGene.m_value.getClass()}); 496 Integer i = (Integer ) method.invoke(m_value, 497 new Object [] {otherGene.m_value}); 498 return i.intValue(); 499 } 500 catch (InvocationTargetException ex) { 501 ex.printStackTrace(); 502 throw new IllegalArgumentException ("CompareTo method of the Gene value" + 503 " object cannot be invoked."); 504 } 505 catch (IllegalArgumentException ex) { 506 ex.printStackTrace(); 507 throw new IllegalArgumentException ("The value object of the Gene does" + 508 " not have a compareTo method. It" + 509 " cannot be compared."); 510 } 511 catch (IllegalAccessException ex) { 512 ex.printStackTrace(); 513 throw new IllegalArgumentException ("The compareTo method of the Gene" + 514 " value object cannot be accessed "); 515 } 516 catch (SecurityException ex) { 517 ex.printStackTrace(); 518 throw new IllegalArgumentException ("The compareTo method of the Gene" + 519 " value object cannot be accessed." + 520 " Insufficient permission levels."); 521 } 522 catch (NoSuchMethodException ex) { 523 ex.printStackTrace(); 524 throw new IllegalArgumentException ("The value object of the Gene does" + 525 " not have a compareTo method. It" + 526 " cannot be compared."); 527 } 528 } 529 530 534 protected Object getInternalValue() { 535 return m_value; 536 } 537 538 546 public int hashCode() { 547 if (getInternalValue() == null) { 548 return -71; 549 } 550 else { 551 return super.hashCode(); 552 } 553 } 554 555 564 public String toString() { 565 String result = "["; 566 if (m_geneMap.size() < 1) { 567 result += "null"; 568 } 569 else { 570 Set keys = m_geneMap.keySet(); 571 Iterator keyIterator = keys.iterator(); 572 boolean firstTime = true; 573 while (keyIterator.hasNext()) { 574 if (!firstTime) { 575 result += ","; 576 } 577 else { 578 firstTime = false; 579 } 580 Object key = keyIterator.next(); 581 String keyString; 582 if (key == null) { 583 keyString = "null"; 584 } 585 else { 586 keyString = key.toString(); 587 } 588 result += "(" + keyString + ","; 589 Object value = m_geneMap.get(key); 590 String valueString; 591 if (value == null) { 592 valueString = "null"; 593 } 594 else { 595 valueString = value.toString(); 596 } 597 result += valueString + ")"; 598 } 599 } 600 result += "]"; 601 return result; 602 } 603 } 604 | Popular Tags |