001/* 002 * Java Genetic Algorithm Library (jenetics-7.2.0). 003 * Copyright (c) 2007-2023 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@gmail.com) 019 */ 020package io.jenetics.internal.engine; 021 022import static java.util.Objects.requireNonNull; 023 024import java.util.Spliterator; 025import java.util.function.Consumer; 026import java.util.function.Function; 027import java.util.function.Supplier; 028 029import io.jenetics.Gene; 030import io.jenetics.engine.Evolution; 031import io.jenetics.engine.EvolutionResult; 032import io.jenetics.engine.EvolutionStart; 033 034/** 035 * The {@code Spliterator} implementation of the {@code EvolutionStream}. 036 * 037 * @param <G> the gene type 038 * @param <C> the evolution result type 039 * 040 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 041 * @since 3.0 042 * @version 5.1 043 */ 044public final class EvolutionSpliterator< 045 G extends Gene<?, G>, 046 C extends Comparable<? super C> 047> 048 implements Spliterator<EvolutionResult<G, C>> 049{ 050 051 private final Supplier<EvolutionStart<G, C>> _start; 052 private final Evolution<G, C> _evolution; 053 054 private long _estimate; 055 private EvolutionStart<G, C> _next = null; 056 057 private EvolutionSpliterator( 058 final Supplier<EvolutionStart<G, C>> start, 059 final Evolution<G, C> evolution, 060 final long estimate 061 ) { 062 _evolution = requireNonNull(evolution); 063 _start = requireNonNull(start); 064 _estimate = estimate; 065 } 066 067 /** 068 * Create a new evolution spliterator with the given {@code start} element 069 * and the {@code evolution} function. 070 * 071 * 072 * @param start the start element 073 * @param evolution the evolution function 074 * @throws NullPointerException if one of the arguments is {@code null} 075 */ 076 public EvolutionSpliterator( 077 final Supplier<EvolutionStart<G, C>> start, 078 final Evolution<G, C> evolution 079 ) { 080 this(start, evolution, Long.MAX_VALUE); 081 } 082 083 @Override 084 public boolean 085 tryAdvance(final Consumer<? super EvolutionResult<G, C>> action) { 086 if (_next == null) { 087 _next = _start.get(); 088 } 089 090 final EvolutionResult<G, C> result = _evolution.evolve(_next); 091 action.accept(result); 092 _next = result.next(); 093 return true; 094 } 095 096 @Override 097 public Spliterator<EvolutionResult<G, C>> trySplit() { 098 return _estimate > 0 099 ? new EvolutionSpliterator<>(_start, _evolution, _estimate >>>= 1) 100 : null; 101 } 102 103 @Override 104 public long estimateSize() { 105 return _estimate; 106 } 107 108 @Override 109 public int characteristics() { 110 return NONNULL | IMMUTABLE | ORDERED; 111 } 112 113 /** 114 * Create a new spliterator with the given {@code start} element and the 115 * {@code evolution} function-function. 116 * 117 * @since 5.1 118 * 119 * @param start the start element 120 * @param evolution the evolution function-function 121 * @param <G> the gene type 122 * @param <C> the evolution result type 123 * @return a new evolution spliterator 124 */ 125 public static <G extends Gene<?, G>, C extends Comparable<? super C>> 126 EvolutionSpliterator<G, C> of( 127 final Supplier<EvolutionStart<G, C>> start, 128 final Function< 129 ? super EvolutionStart<G, C>, 130 ? extends Evolution<G, C>> evolution 131 ) { 132 return new EvolutionSpliterator<>( 133 start, 134 result -> evolution.apply(result).evolve(result) 135 ); 136 } 137 138}