001/* 002 * Java Genetic Algorithm Library (jenetics-3.9.0). 003 * Copyright (c) 2007-2017 Franz Wilhelmstötter 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 * Author: 018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at) 019 */ 020package org.jenetics.xml; 021 022import static java.util.Objects.requireNonNull; 023import static org.jenetics.xml.stream.Writer.attr; 024import static org.jenetics.xml.stream.Writer.elem; 025import static org.jenetics.xml.stream.Writer.elems; 026import static org.jenetics.xml.stream.Writer.text; 027 028import java.io.OutputStream; 029import java.util.Collection; 030import java.util.stream.Collectors; 031 032import javax.xml.stream.XMLStreamException; 033 034import org.jenetics.BoundedGene; 035import org.jenetics.Chromosome; 036import org.jenetics.Gene; 037import org.jenetics.xml.stream.AutoCloseableXMLStreamWriter; 038import org.jenetics.xml.stream.Writer; 039import org.jenetics.xml.stream.XML; 040 041/** 042 * This class contains static fields and methods, for creating chromosome- and 043 * genotype writers for different gene types. 044 * 045 * <pre>{@code 046 * final Writer<Genotype<BitGene> bgw = 047 * Writers.Genotype.writer(Writers.BitChromosome.writer())); 048 * 049 * final Writer<Genotype<IntegerGene>> igw = 050 * Writers.Genotype.writer(Writers.IntegerChromosome.writer())); 051 * 052 * final Writer<Genotype<DoubleGene>> dgw = 053 * Writers.Genotype.writer(Writers.DoubleChromosome.writer())); 054 * }</pre> 055 * 056 * This class also contains some helper methods, which makes it easier to write 057 * Jenetics domain objects to a given output stream. 058 * <pre>{@code 059 * final List<Genotype<BitGene>> genotypes = ...; 060 * try (OutputStream out = Files.newOutputStream(Paths.get("path"))) { 061 * Writers.write(out, genotypes, Writers.BitChromosome.writer()); 062 * } 063 * }</pre> 064 * 065 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a> 066 * @version 3.9 067 * @since 3.9 068 */ 069public final class Writers { 070 private Writers() {} 071 072 /** 073 * This class contains static writer methods for 074 * {@link org.jenetics.BitChromosome} objects. 075 * <p> 076 * <b>Writer code</b> 077 * <pre>{@code 078 * final BitChromosome value = BitChromosome.of(20, 0.5); 079 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 080 * Writers.BitChromosome.writer().write(value, xml); 081 * } 082 * }</pre> 083 * 084 * <b>XML output</b> 085 * <pre> {@code 086 * <bit-chromosome length="20" ones-probability="0.5">11100011101011001010</bit-chromosome> 087 * }</pre> 088 * 089 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a> 090 * @version 3.9 091 * @since 3.9 092 */ 093 public static final class BitChromosome { 094 private BitChromosome() {} 095 096 static final String ROOT_NAME = "bit-chromosome"; 097 static final String LENGTH_NAME = "length"; 098 static final String ONES_PROBABILITY_NAME = "ones-probability"; 099 100 /** 101 * Return a {@link Writer} for {@link org.jenetics.BitChromosome} 102 * objects. 103 * 104 * @return a chromosome writer 105 */ 106 public static Writer<org.jenetics.BitChromosome> writer() { 107 return elem(ROOT_NAME, 108 attr(LENGTH_NAME).map(org.jenetics.BitChromosome::length), 109 attr(ONES_PROBABILITY_NAME).map(ch -> ch.getOneProbability()), 110 text().map(org.jenetics.BitChromosome::toCanonicalString) 111 ); 112 } 113 114 /** 115 * Write the given {@link org.jenetics.BitChromosome} to the given 116 * output stream. 117 * 118 * @param out the target output stream 119 * @param data the bit-chromosome to write 120 * @throws XMLStreamException if an error occurs while writing the 121 * chromosome 122 * @throws NullPointerException if one of the given arguments is 123 * {@code null} 124 */ 125 public static void write( 126 final OutputStream out, 127 final org.jenetics.BitChromosome data 128 ) 129 throws XMLStreamException 130 { 131 requireNonNull(data); 132 requireNonNull(out); 133 134 try (AutoCloseableXMLStreamWriter xml = XML.writer(out)) { 135 writer().write(xml, data); 136 } 137 } 138 } 139 140 141 /** 142 * This class contains static writer methods for 143 * {@link org.jenetics.CharacterChromosome} objects. 144 * <p> 145 * <b>Writer code</b> 146 * <pre>{@code 147 * final CharacterChromosome value = CharacterChromosome.of("ASDF", CharSeq.of("A-Z")); 148 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 149 * Writers.CharacterChromosome.writer().write(value, xml); 150 * } 151 * }</pre> 152 * 153 * <b>XML output</b> 154 * <pre> {@code 155 * <character-chromosome length="4"> 156 * <valid-alleles>ABCDEFGHIJKLMNOPQRSTUVWXYZ<valid-alleles> 157 * <alleles>ASDF</alleles> 158 * </character-chromosome> 159 * }</pre> 160 */ 161 public static final class CharacterChromosome { 162 private CharacterChromosome() {} 163 164 static final String ROOT_NAME = "character-chromosome"; 165 static final String LENGTH_NAME = "length"; 166 static final String VALID_ALLELES_NAME = "valid-alleles"; 167 static final String ALLELES_NAME = "alleles"; 168 169 /** 170 * Return a {@link Writer} for {@link org.jenetics.CharacterChromosome} 171 * objects. 172 * 173 * @return a chromosome writer 174 */ 175 public static Writer<org.jenetics.CharacterChromosome> writer() { 176 return elem(ROOT_NAME, 177 attr(LENGTH_NAME).map(org.jenetics.CharacterChromosome::length), 178 elem(VALID_ALLELES_NAME, 179 text().map(ch -> ch.getGene().getValidCharacters())), 180 elem(ALLELES_NAME, 181 text().map(org.jenetics.CharacterChromosome::toString)) 182 ); 183 } 184 185 /** 186 * Write the given {@link org.jenetics.CharacterChromosome} to the given 187 * output stream. 188 * 189 * @param out the target output stream 190 * @param data the chromosome to write 191 * @param indent the XML level indentation 192 * @throws XMLStreamException if an error occurs while writing the 193 * chromosome 194 * @throws NullPointerException if the {@code chromosome} or output 195 * stream is {@code null} 196 */ 197 public static void write( 198 final OutputStream out, 199 final org.jenetics.CharacterChromosome data, 200 final String indent 201 ) 202 throws XMLStreamException 203 { 204 requireNonNull(data); 205 requireNonNull(out); 206 207 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) { 208 writer().write(xml, data); 209 } 210 } 211 212 /** 213 * Write the given {@link org.jenetics.CharacterChromosome} to the given 214 * output stream. 215 * 216 * @param out the target output stream 217 * @param data the chromosome to write 218 * @throws XMLStreamException if an error occurs while writing the 219 * chromosome 220 * @throws NullPointerException if the {@code chromosome} or output 221 * stream is {@code null} 222 */ 223 public static void write( 224 final OutputStream out, 225 final org.jenetics.CharacterChromosome data 226 ) 227 throws XMLStreamException 228 { 229 write(out, data, null); 230 } 231 232 } 233 234 /** 235 * This class contains static writer methods for 236 * {@link org.jenetics.BoundedChromosome} objects. 237 * 238 * <p> 239 * <b>XML template</b> 240 * <pre> {@code 241 * <root-name length="3"> 242 * <min>aaa</min> 243 * <max>zzz</max> 244 * <alleles> 245 * <allele>iii</allele> 246 * <allele>fff</allele> 247 * <allele>ggg</allele> 248 * </alleles> 249 * </root-name> 250 * }</pre> 251 */ 252 public static final class BoundedChromosome { 253 private BoundedChromosome() {} 254 255 static final String LENGTH_NAME = "length"; 256 static final String MIN_NAME = "min"; 257 static final String MAX_NAME = "max"; 258 static final String ALLELE_NAME = "allele"; 259 static final String ALLELES_NAME = "alleles"; 260 261 /** 262 * Create a bounded chromosome writer with the given configuration. 263 * 264 * @param rootName the name of the root element. E.g. {@code int-chromosome} 265 * @param alleleWriter the XML writer used for the alleles 266 * @param <A> the allele type 267 * @param <G> the bounded gene type 268 * @param <C> the bounded chromosome type 269 * @return a bounded chromosome XML writer 270 * @throws NullPointerException if one of the arguments is {@code null} 271 */ 272 public static < 273 A extends Comparable<? super A>, 274 G extends BoundedGene<A, G>, 275 C extends org.jenetics.BoundedChromosome<A, G> 276 > 277 Writer<C> writer( 278 final String rootName, 279 final Writer<? super A> alleleWriter 280 ) { 281 requireNonNull(rootName); 282 requireNonNull(alleleWriter); 283 284 return elem(rootName, 285 attr(LENGTH_NAME).map(ch -> ch.length()), 286 elem(MIN_NAME, alleleWriter.map(ch -> ch.getMin())), 287 elem(MAX_NAME, alleleWriter.map(ch -> ch.getMax())), 288 elem(ALLELES_NAME, 289 elems(ALLELE_NAME, alleleWriter) 290 .map(ch -> ch.toSeq().map(G::getAllele)) 291 ) 292 ); 293 } 294 } 295 296 /** 297 * This class contains static writer methods for 298 * {@link org.jenetics.IntegerChromosome} objects. 299 * <p> 300 * <b>Writer code</b> 301 * <pre>{@code 302 * final IntegerChromosome value = IntegerChromosome 303 * .of(Integer.MIN_VALUE, Integer.MAX_VALUE, 3); 304 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 305 * Writers.IntegerChromosome.writer().write(value, xml); 306 * } 307 * }</pre> 308 * 309 * <b>XML output</b> 310 * <pre> {@code 311 * <int-chromosome length="3"> 312 * <min>-2147483648</min> 313 * <max>2147483647</max> 314 * <alleles> 315 * <allele>-1878762439</allele> 316 * <allele>-957346595</allele> 317 * <allele>-88668137</allele> 318 * </alleles> 319 * </int-chromosome> 320 * }</pre> 321 */ 322 public static final class IntegerChromosome { 323 private IntegerChromosome() {} 324 325 static final String ROOT_NAME = "int-chromosome"; 326 327 /** 328 * Return the default integer allele writer for the 329 * {@code IntegerChromosome}. 330 * 331 * @return the default integer allele writer 332 */ 333 public static Writer<Integer> alleleWriter() { 334 return text(); 335 } 336 337 /** 338 * Return a {@link Writer} for {@link org.jenetics.IntegerChromosome} 339 * objects. 340 * 341 * @param alleleWriter the allele writer used for writing the integer 342 * allele. Might be useful for using different integer 343 * <i>encodings</i>. 344 * @return a chromosome writer 345 * @throws NullPointerException if the given {@code alleleWriter} is 346 * {@code null} 347 */ 348 public static Writer<org.jenetics.IntegerChromosome> 349 writer(final Writer<? super Integer> alleleWriter) { 350 requireNonNull(alleleWriter); 351 352 return BoundedChromosome.writer(ROOT_NAME, alleleWriter); 353 } 354 355 /** 356 * Return a {@link Writer} for {@link org.jenetics.IntegerChromosome} 357 * objects. 358 * 359 * @return a chromosome writer 360 */ 361 public static Writer<org.jenetics.IntegerChromosome> writer() { 362 return writer(alleleWriter()); 363 } 364 365 /** 366 * Write the given {@link org.jenetics.IntegerChromosome} to the given 367 * output stream. 368 * 369 * @param out the target output stream 370 * @param data the chromosome to write 371 * @param indent the XML level indentation 372 * @throws XMLStreamException if an error occurs while writing the 373 * chromosome 374 * @throws NullPointerException if the {@code chromosome} or output 375 * stream is {@code null} 376 */ 377 public static void write( 378 final OutputStream out, 379 final org.jenetics.IntegerChromosome data, 380 final String indent 381 ) 382 throws XMLStreamException 383 { 384 requireNonNull(data); 385 requireNonNull(out); 386 387 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) { 388 writer().write(xml, data); 389 } 390 } 391 392 /** 393 * Write the given {@link org.jenetics.IntegerChromosome} to the given 394 * output stream. 395 * 396 * @param out the target output stream 397 * @param data the chromosome to write 398 * @throws XMLStreamException if an error occurs while writing the 399 * chromosome 400 * @throws NullPointerException if the {@code chromosome} or output 401 * stream is {@code null} 402 */ 403 public static void write( 404 final OutputStream out, 405 final org.jenetics.IntegerChromosome data 406 ) 407 throws XMLStreamException 408 { 409 write(out, data, null); 410 } 411 } 412 413 /** 414 * This class contains static writer methods for 415 * {@link org.jenetics.LongChromosome} objects. 416 * <p> 417 * <b>Writer code</b> 418 * <pre>{@code 419 * final LongChromosome value = LongChromosome 420 * .of(Long.MIN_VALUE, Long.MAX_VALUE, 3); 421 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 422 * Writers.LongChromosome.writer().write(value, xml); 423 * } 424 * }</pre> 425 * 426 * <b>XML output</b> 427 * <pre> {@code 428 * <long-chromosome length="3"> 429 * <min>-9223372036854775808</min> 430 * <max>9223372036854775807</max> 431 * <alleles> 432 * <allele>-1345217698116542402</allele> 433 * <allele>-7144755673073475303</allele> 434 * <allele>6053786736809578435</allele> 435 * </alleles> 436 * </long-chromosome> 437 * }</pre> 438 */ 439 public static final class LongChromosome { 440 private LongChromosome() {} 441 442 static final String ROOT_NAME = "long-chromosome"; 443 444 /** 445 * Return the default long allele writer for the 446 * {@code IntegerChromosome}. 447 * 448 * @return the default long allele writer 449 */ 450 public static Writer<Long> alleleWriter() { 451 return Writer.text(); 452 } 453 454 /** 455 * Return a {@link Writer} for {@link org.jenetics.LongChromosome} 456 * objects. 457 * 458 * @param alleleWriter the allele writer used for writing the long 459 * allele. Might be useful for using different long 460 * <i>encodings</i>. 461 * @return a chromosome writer 462 * @throws NullPointerException if the given {@code alleleWriter} is 463 * {@code null} 464 */ 465 public static Writer<org.jenetics.LongChromosome> 466 writer(final Writer<? super Long> alleleWriter) { 467 return BoundedChromosome.writer(ROOT_NAME, alleleWriter); 468 } 469 470 /** 471 * Return a {@link Writer} for {@link org.jenetics.LongChromosome} 472 * objects. 473 * 474 * @return a chromosome writer 475 */ 476 public static Writer<org.jenetics.LongChromosome> writer() { 477 return writer(alleleWriter()); 478 } 479 480 /** 481 * Write the given {@link org.jenetics.LongChromosome} to the given 482 * output stream. 483 * 484 * @param out the target output stream 485 * @param data the chromosome to write 486 * @param indent the XML level indentation 487 * @throws XMLStreamException if an error occurs while writing the 488 * chromosome 489 * @throws NullPointerException if the {@code chromosome} or output 490 * stream is {@code null} 491 */ 492 public static void write( 493 final OutputStream out, 494 final org.jenetics.LongChromosome data, 495 final String indent 496 ) 497 throws XMLStreamException 498 { 499 requireNonNull(data); 500 requireNonNull(out); 501 502 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) { 503 writer().write(xml, data); 504 } 505 } 506 507 /** 508 * Write the given {@link org.jenetics.LongChromosome} to the given 509 * output stream. 510 * 511 * @param out the target output stream 512 * @param data the chromosome to write 513 * @throws XMLStreamException if an error occurs while writing the 514 * chromosome 515 * @throws NullPointerException if the {@code chromosome} or output 516 * stream is {@code null} 517 */ 518 public static void write( 519 final OutputStream out, 520 final org.jenetics.LongChromosome data 521 ) 522 throws XMLStreamException 523 { 524 write(out, data, null); 525 } 526 } 527 528 /** 529 * This class contains static writer methods for 530 * {@link org.jenetics.DoubleChromosome} objects. 531 * <p> 532 * <b>Writer code</b> 533 * <pre>{@code 534 * final DoubleChromosome value = DoubleChromosome.of(0.0, 1.0, 3); 535 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 536 * Writers.DoubleChromosome.writer().write(value, xml); 537 * } 538 * }</pre> 539 * 540 * <b>XML output</b> 541 * <pre> {@code 542 * <double-chromosome length="3"> 543 * <min>0.0</min> 544 * <max>1.0</max> 545 * <alleles> 546 * <allele>0.27251556008507416</allele> 547 * <allele>0.003140816229067145</allele> 548 * <allele>0.43947528327497376</allele> 549 * </alleles> 550 * </double-chromosome> 551 * }</pre> 552 */ 553 public static final class DoubleChromosome 554 //extends WriterProvider<org.jenetics.DoubleChromosome> 555 { 556 private DoubleChromosome() {} 557 558 static final String ROOT_NAME = "double-chromosome"; 559 560 /** 561 * Return the default double allele writer for the 562 * {@code DoubleChromosome}. 563 * 564 * @return the default double allele writer 565 */ 566 public static Writer<Double> alleleWriter() { 567 return text().map(Object::toString); 568 } 569 570 /** 571 * Return a {@link Writer} for {@link org.jenetics.DoubleChromosome} 572 * objects. 573 * 574 * @param alleleWriter the allele writer used for writing the long 575 * allele. Might be useful for using different long 576 * <i>encodings</i>. 577 * @return a chromosome writer 578 * @throws NullPointerException if the given {@code alleleWriter} is 579 * {@code null} 580 */ 581 public static Writer<org.jenetics.DoubleChromosome> 582 writer(final Writer<? super Double> alleleWriter) { 583 return BoundedChromosome.writer(ROOT_NAME, alleleWriter); 584 } 585 586 /** 587 * Return a {@link Writer} for {@link org.jenetics.DoubleChromosome} 588 * objects. 589 * 590 * @return a chromosome writer 591 */ 592 public static Writer<org.jenetics.DoubleChromosome> writer() { 593 return writer(alleleWriter()); 594 } 595 596 public Class<org.jenetics.DoubleChromosome> type() { 597 return org.jenetics.DoubleChromosome.class; 598 } 599 600 /** 601 * Write the given {@link org.jenetics.DoubleChromosome} to the given 602 * output stream. 603 * 604 * @param out the target output stream 605 * @param data the chromosome to write 606 * @param indent the XML level indentation 607 * @throws XMLStreamException if an error occurs while writing the 608 * chromosome 609 * @throws NullPointerException if the {@code chromosome} or output 610 * stream is {@code null} 611 */ 612 public static void write( 613 final OutputStream out, 614 final org.jenetics.DoubleChromosome data, 615 final String indent 616 ) 617 throws XMLStreamException 618 { 619 requireNonNull(data); 620 requireNonNull(out); 621 622 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) { 623 writer().write(xml, data); 624 } 625 } 626 627 /** 628 * Write the given {@link org.jenetics.DoubleChromosome} to the given 629 * output stream. 630 * 631 * @param out the target output stream 632 * @param data the chromosome to write 633 * @throws XMLStreamException if an error occurs while writing the 634 * chromosome 635 * @throws NullPointerException if the {@code chromosome} or output 636 * stream is {@code null} 637 */ 638 public static void write( 639 final OutputStream out, 640 final org.jenetics.DoubleChromosome data 641 ) 642 throws XMLStreamException 643 { 644 write(out, data, null); 645 } 646 } 647 648 /** 649 * This class contains static writer methods for 650 * {@link org.jenetics.PermutationChromosome} objects. 651 * <p> 652 * <b>Writer code</b> 653 * <pre>{@code 654 * final PermutationChromosome<Integer> value = 655 * PermutationChromosome.ofInteger(5) 656 * 657 * final Writer<PermutationChromosome<Integer> writer = 658 * Writers.PermutationChromosome.writer(); 659 * 660 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 661 * Writers.PermutationChromosome.writer().write(value, xml); 662 * } 663 * }</pre> 664 * 665 * <b>XML output</b> 666 * <pre> {@code 667 * <permutation-chromosome length="5"> 668 * <valid-alleles type="java.lang.Integer"> 669 * <allele>0</allele> 670 * <allele>1</allele> 671 * <allele>2</allele> 672 * <allele>3</allele> 673 * <allele>4</allele> 674 * </valid-alleles> 675 * <order>2 1 3 5 4</order> 676 * </permutation-chromosome> 677 * }</pre> 678 */ 679 public static final class PermutationChromosome { 680 private PermutationChromosome() {} 681 682 static final String ROOT_NAME = "permutation-chromosome"; 683 static final String LENGTH_NAME = "length"; 684 static final String VALID_ALLELES_NAME = "valid-alleles"; 685 static final String ALLELE_NAME = "allele"; 686 static final String ORDER_NAME = "order"; 687 688 /** 689 * Create a writer for permutation-chromosomes. How to write the valid 690 * alleles is defined by the given {@link Writer}. 691 * 692 * @param alleleWriter the allele writer 693 * @param <A> the allele type 694 * @return a new permutation chromosome writer 695 * @throws NullPointerException if the given allele {@code writer} is 696 * {@code null} 697 */ 698 public static <A> Writer<org.jenetics.PermutationChromosome<A>> 699 writer(final Writer<? super A> alleleWriter) { 700 return elem(ROOT_NAME, 701 attr(LENGTH_NAME).map(org.jenetics.PermutationChromosome::length), 702 elem(VALID_ALLELES_NAME, 703 attr("type").map(PermutationChromosome::toAlleleTypeName), 704 elems(ALLELE_NAME, alleleWriter) 705 .map(ch -> ch.getValidAlleles()) 706 ), 707 elem(ORDER_NAME, text()) 708 .map(ch -> ch.stream() 709 .map(g -> Integer.toString(g.getAlleleIndex())) 710 .collect(Collectors.joining(" "))) 711 ); 712 } 713 714 private static String toAlleleTypeName( 715 final org.jenetics.PermutationChromosome<?> ch 716 ) { 717 return ch.getGene().getAllele().getClass().getCanonicalName(); 718 } 719 720 /** 721 * Create a writer for permutation-chromosomes. The valid alleles are 722 * serialized by calling the {@link Object#toString()} method. Calling 723 * this method is equivalent with: 724 * <pre>{@code 725 * final Writer<PermutationChromosome<Double> writer = 726 * PermutationChromosome.write(text().map(Objects::toString)); 727 * }</pre> 728 * 729 * Example output: 730 * <pre> {@code 731 * <permutation-chromosome length="15"> 732 * <valid-alleles type="java.lang.Double"> 733 * <allele>0.27251556008507416</allele> 734 * <allele>0.003140816229067145</allele> 735 * <allele>0.43947528327497376</allele> 736 * <allele>0.10654807463069327</allele> 737 * <allele>0.19696530915810317</allele> 738 * <allele>0.7450003838065538</allele> 739 * <allele>0.5594416969271359</allele> 740 * <allele>0.02823782430152355</allele> 741 * <allele>0.5741102315010789</allele> 742 * <allele>0.4533651041367144</allele> 743 * <allele>0.811148141800367</allele> 744 * <allele>0.5710456351848858</allele> 745 * <allele>0.30166768355230955</allele> 746 * <allele>0.5455492865240272</allele> 747 * <allele>0.21068427527733102</allele> 748 * </valid-alleles> 749 * <order>13 12 4 6 8 14 7 2 11 5 3 0 9 10 1</order> 750 * </permutation-chromosome> 751 * }</pre> 752 * 753 * @param <A> the allele type 754 * @return a new permutation chromosome writer 755 */ 756 public static <A> Writer<org.jenetics.PermutationChromosome<A>> writer() { 757 return writer(text()); 758 } 759 760 /** 761 * Write the given {@link org.jenetics.PermutationChromosome} to the 762 * given output stream. 763 * 764 * @param <A> the allele type 765 * @param out the target output stream 766 * @param data the chromosome to write 767 * @param indent the XML level indentation 768 * @throws XMLStreamException if an error occurs while writing the 769 * chromosome 770 * @throws NullPointerException if the {@code chromosome} or output 771 * stream is {@code null} 772 */ 773 public static <A> void write( 774 final OutputStream out, 775 final org.jenetics.PermutationChromosome<A> data, 776 final String indent 777 ) 778 throws XMLStreamException 779 { 780 requireNonNull(data); 781 requireNonNull(out); 782 783 try (AutoCloseableXMLStreamWriter writer = XML.writer(out, indent)) { 784 PermutationChromosome.<A>writer().write(writer, data); 785 } 786 } 787 788 /** 789 * Write the given {@link org.jenetics.PermutationChromosome} to the 790 * given output stream. 791 * 792 * @param <A> the allele type 793 * @param out the target output stream 794 * @param data the chromosome to write 795 * @param indent the XML level indentation 796 * @param alleleWriter the allele writer of the permutation chromosome 797 * @throws XMLStreamException if an error occurs while writing the 798 * chromosome 799 * @throws NullPointerException if the {@code chromosome} or output 800 * stream is {@code null} 801 */ 802 public static <A> void write( 803 final OutputStream out, 804 final org.jenetics.PermutationChromosome<A> data, 805 final String indent, 806 final Writer<? super A> alleleWriter 807 ) 808 throws XMLStreamException 809 { 810 requireNonNull(data); 811 requireNonNull(alleleWriter); 812 requireNonNull(out); 813 814 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) { 815 PermutationChromosome.<A>writer(alleleWriter) 816 .write(xml, data); 817 } 818 } 819 820 /** 821 * Write the given {@link org.jenetics.PermutationChromosome} to the 822 * given output stream. 823 * 824 * @param <A> the allele type 825 * @param out the target output stream 826 * @param data the chromosome to write 827 * @throws XMLStreamException if an error occurs while writing the 828 * chromosome 829 * @throws NullPointerException if the {@code chromosome} or output 830 * stream is {@code null} 831 */ 832 public static <A> void write( 833 final OutputStream out, 834 final org.jenetics.PermutationChromosome<A> data 835 ) 836 throws XMLStreamException 837 { 838 write(out, data, null, text()); 839 } 840 841 /** 842 * Write the given {@link org.jenetics.PermutationChromosome} to the 843 * given output stream. 844 * 845 * @param <A> the allele type 846 * @param out the target output stream 847 * @param data the chromosome to write 848 * @param alleleWriter the allele writer used to write the chromosome 849 * alleles 850 * @throws XMLStreamException if an error occurs while writing the 851 * chromosome 852 * @throws NullPointerException if the {@code chromosome} or output 853 * stream is {@code null} 854 */ 855 public static <A> void write( 856 final OutputStream out, 857 final org.jenetics.PermutationChromosome<A> data, 858 final Writer<? super A> alleleWriter 859 ) 860 throws XMLStreamException 861 { 862 write(out, data, null, alleleWriter); 863 } 864 865 } 866 867 /** 868 * This class contains static writer methods for 869 * {@link org.jenetics.Genotype} objects. 870 * <p> 871 * <b>Writer code</b> 872 * <pre>{@code 873 * final Genotype<DoubleGene> gt = Genotype.of( 874 * DoubleChromosome.of(0.0, 1.0, 3), 875 * DoubleChromosome.of(0.0, 1.0, 2) 876 * ); 877 * final Writer<Genotype<DoubleGene>> writer = 878 * Writers.Genotype.writer(Writers.DoubleChromosome.writer()); 879 * 880 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 881 * writer.write(value, xml); 882 * } 883 * }</pre> 884 * 885 * <b>XML output</b> 886 * <pre> {@code 887 * <genotype length="2" ngenes="5"> 888 * <double-chromosome length="3"> 889 * <min>0.0</min> 890 * <max>1.0</max> 891 * <alleles> 892 * <allele>0.27251556008507416</allele> 893 * <allele>0.003140816229067145</allele> 894 * <allele>0.43947528327497376</allele> 895 * </alleles> 896 * </double-chromosome> 897 * <double-chromosome length="2"> 898 * <min>0.0</min> 899 * <max>1.0</max> 900 * <alleles> 901 * <allele>0.4026521545744768</allele> 902 * <allele>0.36137605952663554</allele> 903 * <alleles> 904 * </double-chromosome> 905 * </genotype> 906 * }</pre> 907 */ 908 public static final class Genotype { 909 private Genotype() {} 910 911 static final String ROOT_NAME = "genotype"; 912 static final String LENGTH_NAME = "length"; 913 static final String NGENES_NAME = "ngenes"; 914 915 /** 916 * Create a writer for genotypes of arbitrary chromosomes. How to write the 917 * genotypes chromosomes is defined by the given {@link Writer}. 918 * 919 * @param writer the chromosome writer 920 * @param <A> the allele type 921 * @param <G> the gene type 922 * @param <C> the chromosome type 923 * @return a new genotype writer 924 * @throws NullPointerException if the given chromosome {@code writer} is 925 * {@code null} 926 */ 927 public static < 928 A, 929 G extends Gene<A, G>, 930 C extends Chromosome<G> 931 > 932 Writer<org.jenetics.Genotype<G>> writer(final Writer<? super C> writer) { 933 return elem( 934 ROOT_NAME, 935 attr(LENGTH_NAME).map(org.jenetics.Genotype<G>::length), 936 attr(NGENES_NAME).map(org.jenetics.Genotype<G>::getNumberOfGenes), 937 elems(writer).map(gt -> cast(gt.toSeq())) 938 ); 939 } 940 941 @SuppressWarnings("unchecked") 942 private static <A, B> B cast(final A value) { 943 return (B)value; 944 } 945 946 /** 947 * Write the given {@link org.jenetics.Genotype} to the given output 948 * stream. 949 * 950 * @param <A> the allele type 951 * @param <G> the gene type 952 * @param <C> the chromosome type 953 * @param out the target output stream 954 * @param data the genotype to write 955 * @param indent the XML level indentation 956 * @param chromosomeWriter the chromosome writer used to write the 957 * genotypes 958 * @throws XMLStreamException if an error occurs while writing the 959 * chromosome 960 * @throws NullPointerException if the one of the arguments is 961 * {@code null} 962 */ 963 public static < 964 A, 965 G extends Gene<A, G>, 966 C extends Chromosome<G> 967 > 968 void write( 969 final OutputStream out, 970 final org.jenetics.Genotype<G> data, 971 final String indent, 972 final Writer<? super C> chromosomeWriter 973 ) 974 throws XMLStreamException 975 { 976 requireNonNull(data); 977 requireNonNull(chromosomeWriter); 978 requireNonNull(out); 979 980 try (AutoCloseableXMLStreamWriter writer = XML.writer(out, indent)) { 981 Genotype.<A, G, C>writer(chromosomeWriter).write(writer, data); 982 } 983 } 984 985 /** 986 * Write the given {@link org.jenetics.Genotype} to the given output 987 * stream. 988 * 989 * @param <A> the allele type 990 * @param <G> the gene type 991 * @param <C> the chromosome type 992 * @param out the target output stream 993 * @param data the genotype to write 994 * @param chromosomeWriter the chromosome writer used to write the 995 * genotypes 996 * @throws XMLStreamException if an error occurs while writing the 997 * chromosome 998 * @throws NullPointerException if the one of the arguments is 999 * {@code null} 1000 */ 1001 public static < 1002 A, 1003 G extends Gene<A, G>, 1004 C extends Chromosome<G> 1005 > 1006 void write( 1007 final OutputStream out, 1008 final org.jenetics.Genotype<G> data, 1009 final Writer<? super C> chromosomeWriter 1010 ) 1011 throws XMLStreamException 1012 { 1013 requireNonNull(data); 1014 requireNonNull(chromosomeWriter); 1015 requireNonNull(out); 1016 1017 try (AutoCloseableXMLStreamWriter xml = XML.writer(out)) { 1018 Genotype.<A, G, C>writer(chromosomeWriter).write(xml, data); 1019 } 1020 } 1021 1022 } 1023 1024 /** 1025 * This class contains static writer methods for 1026 * {@link org.jenetics.Genotype} objects. 1027 * <p> 1028 * <b>Writer code</b> 1029 * <pre>{@code 1030 * final Genotype<DoubleGene> gt = Genotype.of( 1031 * DoubleChromosome.of(0.0, 1.0, 3), 1032 * DoubleChromosome.of(0.0, 1.0, 2) 1033 * ); 1034 * 1035 * final Writer<Collection<Genotype<DoubleGene>>> writer = 1036 * Writers.Genotypes.writer(Writers.DoubleChromosome.writer()); 1037 * 1038 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 1039 * writer.write(asList(value), xml); 1040 * } 1041 * }</pre> 1042 * 1043 * <pre> {@code 1044 * <genotypes length="1"> 1045 * <genotype length="2" ngenes="5"> 1046 * <double-chromosome length="3"> 1047 * <min>0.0</min> 1048 * <max>1.0</max> 1049 * <alleles> 1050 * <allele>0.27251556008507416</allele> 1051 * <allele>0.003140816229067145</allele> 1052 * <allele>0.43947528327497376</allele> 1053 * </alleles> 1054 * </double-chromosome> 1055 * <double-chromosome length="2"> 1056 * <min>0.0</min> 1057 * <max>1.0</max> 1058 * <alleles> 1059 * <allele>0.4026521545744768</allele> 1060 * <allele>0.36137605952663554</allele> 1061 * <alleles> 1062 * </double-chromosome> 1063 * </genotype> 1064 * </genotypes> 1065 * }</pre> 1066 */ 1067 public static final class Genotypes { 1068 private Genotypes() {} 1069 1070 static final String ROOT_NAME = "genotypes"; 1071 static final String LENGTH_NAME = "length"; 1072 1073 /** 1074 * Create a writer for genotypes of arbitrary chromosomes. How to write the 1075 * genotypes chromosomes is defined by the given {@link Writer}. The 1076 * following writer allows to write double-gene chromosomes: 1077 * <pre>{@code 1078 * final Writer<Collection<Genotype<DoubleGene>>> writer = 1079 * Writers.Genotypes.writer(Writers.DoubleChromosome.writer()); 1080 * }</pre> 1081 * 1082 * @param writer the chromosome writer 1083 * @param <A> the allele type 1084 * @param <G> the gene type 1085 * @param <C> the chromosome type 1086 * @return a new genotype writer 1087 * @throws NullPointerException if the given chromosome {@code writer} is 1088 * {@code null} 1089 */ 1090 public static < 1091 A, 1092 G extends Gene<A, G>, 1093 C extends Chromosome<G> 1094 > 1095 Writer<Collection<org.jenetics.Genotype<G>>> 1096 writer(final Writer<? super C> writer) { 1097 return elem( 1098 ROOT_NAME, 1099 attr(LENGTH_NAME).map(Collection::size), 1100 elems(Genotype.writer(writer)) 1101 ); 1102 } 1103 1104 /** 1105 * Write the given {@link org.jenetics.Genotype} to the given output 1106 * stream. 1107 * 1108 * @param <A> the allele type 1109 * @param <G> the gene type 1110 * @param <C> the chromosome type 1111 * @param out the target output stream 1112 * @param data the genotypes to write 1113 * @param indent the XML level indentation 1114 * @param chromosomeWriter the chromosome writer used to write the 1115 * genotypes 1116 * @throws XMLStreamException if an error occurs while writing the 1117 * chromosome 1118 * @throws NullPointerException if the one of the arguments is 1119 * {@code null} 1120 */ 1121 public static < 1122 A, 1123 G extends Gene<A, G>, 1124 C extends Chromosome<G> 1125 > 1126 void write( 1127 final OutputStream out, 1128 final Collection<org.jenetics.Genotype<G>> data, 1129 final String indent, 1130 final Writer<? super C> chromosomeWriter 1131 ) 1132 throws XMLStreamException 1133 { 1134 requireNonNull(data); 1135 requireNonNull(chromosomeWriter); 1136 requireNonNull(out); 1137 1138 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) { 1139 Genotypes.<A, G, C>writer(chromosomeWriter).write(xml, data); 1140 } 1141 } 1142 1143 /** 1144 * Write the given {@link org.jenetics.Genotype} to the given output 1145 * stream. 1146 * 1147 * @param <A> the allele type 1148 * @param <G> the gene type 1149 * @param <C> the chromosome type 1150 * @param out the target output stream 1151 * @param data the genotypes to write 1152 * @param chromosomeWriter the chromosome writer used to write the 1153 * genotypes 1154 * @throws XMLStreamException if an error occurs while writing the 1155 * chromosome 1156 * @throws NullPointerException if the one of the arguments is 1157 * {@code null} 1158 */ 1159 public static < 1160 A, 1161 G extends Gene<A, G>, 1162 C extends Chromosome<G> 1163 > 1164 void write( 1165 final OutputStream out, 1166 final Collection<org.jenetics.Genotype<G>> data, 1167 final Writer<? super C> chromosomeWriter 1168 ) 1169 throws XMLStreamException 1170 { 1171 requireNonNull(data); 1172 requireNonNull(chromosomeWriter); 1173 requireNonNull(out); 1174 1175 try (AutoCloseableXMLStreamWriter xml = XML.writer(out)) { 1176 Genotypes.<A, G, C>writer(chromosomeWriter).write(xml, data); 1177 } 1178 } 1179 1180 } 1181 1182 1183 /** 1184 * Write the given {@link org.jenetics.Genotype} to the given output 1185 * stream. 1186 * 1187 * @see Genotypes#write(OutputStream, Collection, Writer) 1188 * 1189 * @param <A> the allele type 1190 * @param <G> the gene type 1191 * @param <C> the chromosome type 1192 * @param out the target output stream 1193 * @param data the genotypes to write 1194 * @param chromosomeWriter the chromosome writer used to write the 1195 * genotypes 1196 * @throws XMLStreamException if an error occurs while writing the 1197 * chromosome 1198 * @throws NullPointerException if the one of the arguments is 1199 * {@code null} 1200 */ 1201 public static < 1202 A, 1203 G extends Gene<A, G>, 1204 C extends Chromosome<G> 1205 > 1206 void write( 1207 final OutputStream out, 1208 final Collection<org.jenetics.Genotype<G>> data, 1209 final Writer<? super C> chromosomeWriter 1210 ) 1211 throws XMLStreamException 1212 { 1213 Genotypes.write(out, data, chromosomeWriter); 1214 } 1215 1216}