
    'j$S                    ^   d dl mZ d dlmZmZmZmZmZ d dlZd dl	Z	d dl
mZ d dlZd dlZd dlZ G d dej                  ZdKd
Z G d dej                  Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d dej                  Z G d de          Z G d de          Z G d de          Z G d d e          ZdLd'ZdLd(ZdLd)Z G d* d+e          Z  G d, d-e          Z! G d. d/e          Z" G d0 d1e          Z# G d2 d3ej                  Z$ G d4 d5ej                  Z% G d6 d7          Z& G d8 d9          Z'dMd?Z( G d@ dA          Z)dNdDZ* G dE dFe$          Z+ G dG dHe+          Z, G dI dJe$          Z-dS )O    )annotations)SequenceIterableOptionalCallableUnionN)	dataclassc                      e Zd ZU dZdZded<   ded<   ej        dd	            Ze	ej        dd                        Z
d Zd Zd Zd Zd Zd Zd Zd Zej        dd            ZdS )DNAzAbstract DNA class.NzOptional[float]fitnesslist_datavaluesr   c                    d S N selfr   s     X/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/addons/genetic_algorithm.pyresetz	DNA.reset           returnboolc                    d S r   r   r   s    r   is_validzDNA.is_valid!   s	     	r   c                *    t          j        |           S r   )copydeepcopyr   s    r   r   zDNA.copy&   s    }T"""r   c                    d | _         d S r   r   r   s    r   _taintz
DNA._taint)   s    r   c                J    | j         j         dt          | j                   dS )N())	__class____name__strr   r   s    r   __repr__zDNA.__repr__,   s&    .)>>C
OO>>>>r   c                P    t          || j                  sJ | j        |j        k    S r   )
isinstancer'   r   )r   others     r   __eq__z
DNA.__eq__/   s)    %00000zU[((r   c                *    t          | j                  S r   )lenr   r   s    r   __len__zDNA.__len__3   s    4:r   c                6    | j                             |          S r   )r   __getitem__)r   items     r   r3   zDNA.__getitem__6   s    z%%d+++r   c                d    | j                             ||           |                                  d S r   )r   __setitem__r#   )r   keyvalues      r   r6   zDNA.__setitem__9   s+    
sE***r   c                *    t          | j                  S r   )iterr   r   s    r   __iter__zDNA.__iter__=   s    DJr   indexintNonec                    d S r   r   r   r<   s     r   flip_mutate_atzDNA.flip_mutate_at@   r   r   r   r   r   r   r<   r=   r   r>   )r(   
__module____qualname____doc__r   __annotations__abcabstractmethodr   propertyr   r   r#   r*   r.   r1   r3   r6   r;   rA   r   r   r   r   r      s"        #G####KKK        X# # #  ? ? ?) ) )  , , ,        	     r   r   dnar   floatc                    | j         S r   r"   )rL   s    r   dna_fitnessrO   E   s
    ;r   c                  4    e Zd ZdZej        dd            ZdS )	MutatezAbstract mutation.rL   r   raterM   c                    d S r   r   )r   rL   rR   s      r   mutatezMutate.mutateL   r   r   NrL   r   rR   rM   )r(   rE   rF   rG   rI   rJ   rT   r   r   r   rQ   rQ   I   s<             r   rQ   c                      e Zd ZdZddZdS )	
FlipMutatezFlip one bit mutation.rL   r   rR   rM   c                    t          t          |                    D ].}t          j                    |k     r|                    |           /d S r   )ranger0   randomrA   )r   rL   rR   r<   s       r   rT   zFlipMutate.mutateT   sM    3s88__ 	* 	*E}%%""5)))	* 	*r   NrU   r(   rE   rF   rG   rT   r   r   r   rW   rW   Q   s.          * * * * * *r   rW   c                      e Zd ZdZddZdS )	NeighborSwapMutatezSwap two neighbors mutation.rL   r   rR   rM   c                    t          t          |                    D ]6}t          j                    |k     r|dz
  }||         }||         ||<   |||<   7d S N   rY   r0   rZ   )r   rL   rR   r<   i2tmps         r   rT   zNeighborSwapMutate.mutate]   sa    3s88__ 	! 	!E}%%QY"ge*B E
	! 	!r   NrU   r[   r   r   r   r]   r]   Z   s.        &&! ! ! ! ! !r   r]   c                      e Zd ZdZddZdS )	RandomSwapMutatez Swap two random places mutation.rL   r   rR   rM   c                    t          |          }t          |          D ]Q}t          j                    |k     r8t          j        d|          }||k    r|dz  }||         }||         ||<   |||<   Rd S )Nr   r`   )r0   rY   rZ   	randrange)r   rL   rR   lengthr<   rb   rc   s          r   rT   zRandomSwapMutate.mutatei   s    S6]] 	! 	!E}%%%a00;;!GB"ge*B E
	! 	!r   NrU   r[   r   r   r   re   re   f   s.        **	! 	! 	! 	! 	! 	!r   re   c                  $    e Zd ZdZdddZdd
ZdS )ReverseMutatez'Reverse some consecutive bits mutation.   bitsr=   c                J    t          t          |d                    | _        d S r_   r=   max_bitsr   rl   s     r   __init__zReverseMutate.__init__x       T1&&


r   rL   r   rR   rM   c                    t          |          }t          j                    ||| j        z  z  k     rFt          j        || j        z
            }|| j        z   }|||         }t	          |          |||<   d S d S r   )r0   rZ   rp   rg   reversedr   rL   rR   rh   i1rb   rl   s          r   rT   zReverseMutate.mutate{   s    S=??TTZ
 
 
 !&4:"566BdjBr"u:D!$C2JJJ
 
r   Nrk   rl   r=   rU   r(   rE   rF   rG   rr   rT   r   r   r   rj   rj   u   sG        11' ' ' ' '( ( ( ( ( (r   rj   c                  $    e Zd ZdZdddZdd
ZdS )ScrambleMutatez(Scramble some consecutive bits mutation.rk   rl   r=   c                J    t          t          |d                    | _        d S r_   rn   rq   s     r   rr   zScrambleMutate.__init__   rs   r   rL   r   rR   rM   c                   t          |          }t          j                    ||| j        z  z  k     rMt          j        || j        z
            }|| j        z   }|||         }t          j        |           ||||<   d S d S r   )r0   rZ   rp   rg   shufflerv   s          r   rT   zScrambleMutate.mutate   s    S=??TTZ
 
 
 !&4:"566BdjBr"u:DN4   C2JJJ
 
r   Nrx   ry   rU   rz   r   r   r   r|   r|      sG        22' ' ' ' '	 	 	 	 	 	r   r|   c                  4    e Zd ZdZej        dd            ZdS )MatezAbstract recombination.dna1r   dna2c                    d S r   r   r   r   r   s      r   	recombinezMate.recombine   s    r   Nr   r   r   r   )r(   rE   rF   rG   rI   rJ   r   r   r   r   r   r      s<        !!     r   r   c                      e Zd ZdZddZdS )Mate1pCXz"One point crossover recombination.r   r   r   c                r    t          |          }t          j        d|          }t          ||||           d S Nr   r0   rZ   rg   recombine_dna_2pcx)r   r   r   rh   r<   s        r   r   zMate1pCX.recombine   s9    T F++4uf55555r   Nr   r(   rE   rF   rG   r   r   r   r   r   r      s.        ,,6 6 6 6 6 6r   r   c                      e Zd ZdZddZdS )Mate2pCXz"Two point crossover recombination.r   r   r   c                    t          |          }t          j        d|          }t          j        d|          }||k    r||}}t          ||||           d S r   r   r   r   r   rh   rw   rb   s         r   r   zMate2pCX.recombine   ]    Ta((a((77B4r2.....r   Nr   r   r   r   r   r   r      s.        ,,/ / / / / /r   r   c                      e Zd ZdZddZdS )MateUniformCXzUniform recombination.r   r   r   c                    t          t          |                    D ]1}t          j                    dk    r||         }||         ||<   |||<   2d S )Ng      ?ra   )r   r   r   r<   rc   s        r   r   zMateUniformCX.recombine   sZ    3t99%% 	" 	"E}$$5k"5kU!U		" 	"r   Nr   r   r   r   r   r   r      s.          " " " " " "r   r   c                      e Zd ZdZddZdS )MateOrderedCXz8Recombination class for ordered DNA like UniqueIntDNA().r   r   r   c                    t          |          }t          j        d|          }t          j        d|          }||k    r||}}t          ||||           d S r   )r0   rZ   rg   recombine_dna_ocx1r   s         r   r   zMateOrderedCX.recombine   r   r   Nr   r   r   r   r   r   r      s.        BB/ / / / / /r   r   r   r   rw   r=   rb   r>   c                J    | ||         }|||         }|| ||<   ||||<   dS )zTwo point crossover.Nr   )r   r   rw   rb   part1part2s         r   r   r      s:    BKEBKEDBKDBKKKr   c                v    |                                  }t          | |||           t          ||||           dS )zOrdered crossover.N)r   replace_dna_ocx1)r   r   rw   rb   copy1s        r   r   r      s=    IIKKET4R(((T5"b)))))r   c                    |                                  }|||         }|| ||<   d}t          |          }|D ]}||v r||k    r|}|| |<   |dz  }dS )zWReplace a part in dna1 by dna2 and preserve order of remaining values in
    dna1.
    r   r`   N)r   set)	r   r   rw   rb   oldnewr<   new_setr8   s	            r   r   r      s     ))++C
r"u+CDBKE#hhG  GB;;EU
 r   c                      e Zd ZdZdZddZedd	            Zedd            Ze	dd            Z
d Zd ZddZddZdS )FloatDNAz,Arbitrary float numbers in the range [0, 1].r   r   r   Iterable[float]c                d    t          |          | _        |                                  d | _        d S r   )r   r   _check_valid_datar   r   s     r   rr   zFloatDNA.__init__   s,    "&v,,
   (,r   rh   r=   r   c                F     | d t          |          D                       S )Nc              3  <   K   | ]}t          j                     V  d S r   rZ   .0_s     r   	<genexpr>z"FloatDNA.random.<locals>.<genexpr>   s(      ;;FMOO;;;;;;r   rY   clsrh   s     r   rZ   zFloatDNA.random   s'    s;;U6]];;;<<<r   nlist[FloatDNA]c                >      fdt          |          D             S )Nc                :    g | ]}                               S r   r   r   r   r   rh   s     r   
<listcomp>z%FloatDNA.n_random.<locals>.<listcomp>   %    555q

6""555r   r   r   r   rh   s   ` `r   n_randomzFloatDNA.n_random   '    55555E!HH5555r   r   c                >    t          d | j        D                       S )Nc              3  6   K   | ]}d |cxk    odk    nc V  dS               ?Nr   r   vs     r   r   z$FloatDNA.is_valid.<locals>.<genexpr>  s6      77q3!????s????777777r   allr   r   s    r   r   zFloatDNA.is_valid   s!    77DJ777777r   c                2    | j         st          d          d S )Nzdata value out of range)r   
ValueErrorr   s    r   r   zFloatDNA._check_valid_data  s%    } 	86777	8 	8r   c                p    | j         d}nd| j         d}t          d | j        D                        | S )N, fitness=None
, fitness=.4fc                .    g | ]}t          |d           S )   )roundr   s     r   r   z$FloatDNA.__str__.<locals>.<listcomp>  s     777quQ{{777r   r   r)   r   r   r   s     r   __str__zFloatDNA.__str__  sM    <&GG54<555G77DJ77788C'CCCr   c                ~    t          |          | _        |                                  |                                  d S r   )r   r   r   r#   r   s     r   r   zFloatDNA.reset  s2    &\\
   r   r<   r>   c                6    d| j         |         z
  | j         |<   d S Nr   r   r@   s     r   rA   zFloatDNA.flip_mutate_at  s     $*U"33
5r   N)r   r   )rh   r=   r   r   )r   r=   rh   r=   r   r   rC   rD   )r(   rE   rF   rG   	__slots__rr   classmethodrZ   r   rK   r   r   r   r   rA   r   r   r   r   r      s        66$I- - - -
 = = = [= 6 6 6 [6 8 8 8 X88 8 8D D D   
4 4 4 4 4 4r   r   c                  |    e Zd ZdZdZddZedd            Zedd            Z	edd            Z
d ZddZddZdS )BitDNAzOne bit DNA.r   r   r   c                P    t          d |D                       | _        d | _        d S )Nc              3  4   K   | ]}t          |          V  d S r   r   r   s     r   r   z"BitDNA.__init__.<locals>.<genexpr>  s(      %>%>!d1gg%>%>%>%>%>%>r   )r   r   r   r   s     r   rr   zBitDNA.__init__  s+    !%%>%>v%>%>%>!>!>
(,r   r   r   c                    dS )NTr   r   s    r   r   zBitDNA.is_valid   s    tr   rh   r=   c                F     | d t          |          D                       S )Nc              3  Z   K   | ]&}t          t          j        d d                    V  'dS )r   r`   N)r   rZ   randintr   s     r   r   z BitDNA.random.<locals>.<genexpr>&  s6      EE!4q!,,--EEEEEEr   r   r   s     r   rZ   zBitDNA.random$  s'    sEEuV}}EEEEEEr   r   list[BitDNA]c                >      fdt          |          D             S )Nc                :    g | ]}                               S r   r   r   s     r   r   z#BitDNA.n_random.<locals>.<listcomp>*  r   r   r   r   s   ` `r   r   zBitDNA.n_random(  r   r   c                p    | j         d}nd| j         d}t          d | j        D                        | S )Nr   r   r   c                ,    g | ]}t          |          S r   r=   r   s     r   r   z"BitDNA.__str__.<locals>.<listcomp>1      222!s1vv222r   r   r   s     r   r   zBitDNA.__str__,  M    <&GG54<555G22tz22233>W>>>r   r>   c                j    t          d |D                       | _        |                                  d S )Nc              3  4   K   | ]}t          |          V  d S r   r   r   s     r   r   zBitDNA.reset.<locals>.<genexpr>4  s(      22a$q''222222r   r   r   r#   r   s     r   r   zBitDNA.reset3  s1    22622222
r   r<   c                2    | j         |          | j         |<   d S r   r   r@   s     r   rA   zBitDNA.flip_mutate_at7  s     $
5 11
5r   NrB   rC   )rh   r=   r   r   )r   r=   rh   r=   r   r   r   r   r   r>   rD   )r(   rE   rF   rG   r   rr   rK   r   r   rZ   r   r   r   rA   r   r   r   r   r     s        $I- - - -    X F F F [F 6 6 6 [6? ? ?   2 2 2 2 2 2r   r   c                  |    e Zd ZdZdZddZedd	            Zedd            Ze	dd            Z
d ZddZddZdS )UniqueIntDNAaU  Unique integer values in the range from 0 to length-1.
    E.g. UniqueIntDNA(10) = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    Requires MateOrderedCX() as recombination class to preserve order and
    validity after DNA recombination.

    Requires mutation by swapping like SwapRandom(), SwapNeighbors(),
    ReversMutate() or ScrambleMutate()
    r   r   Union[int, Iterable]c                    |  t          |t                    r"t          t          |                    | _        n,d |D             | _        | j        st          | j                  d | _        d S )Nc                ,    g | ]}t          |          S r   r   r   s     r   r   z)UniqueIntDNA.__init__.<locals>.<listcomp>M  s    111Q#a&&111r   )r,   r=   r   rY   r   r   	TypeErrorr   r   s     r   rr   zUniqueIntDNA.__init__H  sk    fc"" 	,eFmm,,DJJ11&111DJ= ,
+++(,r   rh   r=   r   c                N     | |          }t          j        |j                   |S r   )rZ   r   r   )r   rh   rL   s      r   rZ   zUniqueIntDNA.randomR  s&    c&kksy!!!
r   r   list[UniqueIntDNA]c                >      fdt          |          D             S )Nc                :    g | ]}                               S r   r   r   s     r   r   z)UniqueIntDNA.n_random.<locals>.<listcomp>Z  r   r   r   r   s   ` `r   r   zUniqueIntDNA.n_randomX  r   r   r   c                p    t          t          | j                            t          | j                  k    S r   )r0   r   r   r   s    r   r   zUniqueIntDNA.is_valid\  s%    3tz??##s4:66r   c                p    | j         d}nd| j         d}t          d | j        D                        | S )Nr   r   r   c                ,    g | ]}t          |          S r   r   r   s     r   r   z(UniqueIntDNA.__str__.<locals>.<listcomp>e  r   r   r   r   s     r   r   zUniqueIntDNA.__str__`  r   r   r   r>   c                j    t          d |D                       | _        |                                  d S )Nc              3  4   K   | ]}t          |          V  d S r   r   r   s     r   r   z%UniqueIntDNA.reset.<locals>.<genexpr>h  (      11Q#a&&111111r   r   r   s     r   r   zUniqueIntDNA.resetg  1    11&11111
r   r<   c                     t          d          )Nzflip mutation not supported)r   r@   s     r   rA   zUniqueIntDNA.flip_mutate_atk  s    5666r   N)r   r   )rh   r=   r   r   )r   r=   rh   r=   r   r   rC   r   rD   )r(   rE   rF   rG   r   rr   r   rZ   r   rK   r   r   r   rA   r   r   r   r   r   ;  s          %I- - - -    [
 6 6 6 [6 7 7 7 X7? ? ?   7 7 7 7 7 7r   r   c                      e Zd ZdZdZddZedd
            Zedd            Ze	dd            Z
d Zd ZddZddZdS )
IntegerDNAzkInteger values in the range from 0 to max_ - 1.
    E.g. IntegerDNA([0, 1, 2, 3, 4, 0, 1, 2, 3, 4], 5)
    r   r   Iterable[int]max_r=   c                    t          |          | _        t          |          | _        | j        st          | j                  d | _        d S r   )r=   _maxr   r   r   r   r   )r   r   r  s      r   rr   zIntegerDNA.__init__v  sA    II	 $V
} 	(DJ'''(,r   rh   r   c                l    t          |           | fdt          |          D                       S )Nc              3  B   K   | ]}t          j        d           V  dS r   N)rZ   rg   )r   r   imaxs     r   r   z$IntegerDNA.random.<locals>.<genexpr>  s0      EE!F$Q--EEEEEEr   )r=   rY   )r   rh   r  r  s      @r   rZ   zIntegerDNA.random}  s;    4yysEEEEuV}}EEEtLLLr   r   list[IntegerDNA]c                B      fdt          |          D             S )Nc                <    g | ]}                               S r   r   )r   r   r   rh   r  s     r   r   z'IntegerDNA.n_random.<locals>.<listcomp>  s'    ;;;Q

64((;;;r   r   )r   r   rh   r  s   ` ``r   r   zIntegerDNA.n_random  s+    ;;;;;;%((;;;;r   r   c                D     t           fd j        D                       S )Nc              3  B   K   | ]}d |cxk    o
j         k     nc V  dS r  )r  )r   r   r   s     r   r   z&IntegerDNA.is_valid.<locals>.<genexpr>  sA      ::!1%%%%DI%%%%::::::r   r   r   s   `r   r   zIntegerDNA.is_valid  s(    ::::tz::::::r   c                Z    | j         j         dt          | j                   d| j         dS )Nr%   z, r&   )r'   r(   r)   r   r  r   s    r   r*   zIntegerDNA.__repr__  s0    .)KKC
OOKKtyKKKKr   c                p    | j         d}nd| j         d}t          d | j        D                        | S )Nr   r   r   c                ,    g | ]}t          |          S r   r   r   s     r   r   z&IntegerDNA.__str__.<locals>.<listcomp>  r   r   r   r   s     r   r   zIntegerDNA.__str__  r   r   r   r>   c                j    t          d |D                       | _        |                                  d S )Nc              3  4   K   | ]}t          |          V  d S r   r   r   s     r   r   z#IntegerDNA.reset.<locals>.<genexpr>  r   r   r   r   s     r   r   zIntegerDNA.reset  r  r   r<   c                F    | j         | j        |         z
  dz
  | j        |<   d S r_   )r  r   r@   s     r   rA   zIntegerDNA.flip_mutate_at  s'     I
5(99A=
5r   N)r   r  r  r=   )rh   r=   r  r=   r   r  )r   r=   rh   r=   r  r=   r   r  rC   r   rD   )r(   rE   rF   rG   r   rr   r   rZ   r   rK   r   r*   r   r   rA   r   r   r   r  r  o  s          %I- - - - M M M [M < < < [< ; ; ; X;L L L? ? ?   > > > > > >r   r  c                  V    e Zd ZdZej        d
d            Zej        dd            Zd	S )	SelectionzAbstract selection class.countr=   r   Iterable[DNA]c                    d S r   r   r   r  s     r   pickzSelection.pick  r   r   
candidatesc                    d S r   r   r   r  s     r   r   zSelection.reset  r   r   Nr  r=   r   r  r  r  )r(   rE   rF   rG   rI   rJ   r  r   r   r   r   r  r    s`        ##    	     r   r  c                  4    e Zd ZdZej        dd            ZdS )		EvaluatorzAbstract evaluation class.rL   r   r   rM   c                    d S r   r   r   rL   s     r   evaluatezEvaluator.evaluate  r   r   NrL   r   r   rM   )r(   rE   rF   rG   rI   rJ   r(  r   r   r   r%  r%    s<        $$     r   r%  c                  h    e Zd Ze G d d                      ZddZdd
ZddZedd            Z	dS )Logc                  .    e Zd ZU ded<   ded<   ded<   dS )	Log.EntryrM   runtimer   avg_fitnessN)r(   rE   rF   rH   r   r   r   Entryr-    s0         r   r0  r   r>   c                    g | _         d S r   )entriesr   s    r   rr   zLog.__init__  s    (*r   r.  rM   r   r/  c                n    | j                             t                              |||                     d S r   )r2  appendr+  r0  )r   r.  r   r/  s       r   addzLog.add  s.    CIIgwDDEEEEEr   filenamer)   c                    d | j         D             }t          |d          5 }t          j        ||d           d d d            d S # 1 swxY w Y   d S )Nc                6    g | ]}|j         |j        |j        fS r   )r.  r   r/  )r   es     r   r   zLog.dump.<locals>.<listcomp>  s%    LLL!AIq}5LLLr   wtr   )indent)r2  openjsondump)r   r6  datafps       r   r>  zLog.dump  s    LLt|LLL(D!! 	*RIdBq))))	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*s   AAAc                    t          |d          5 }t          j        |          }d d d            n# 1 swxY w Y   t                      }|D ]\  }}}|                    |||           |S )Nrt)r<  r=  loadr+  r5  )r   r6  r@  r?  logr.  r   r/  s           r   rC  zLog.load  s    (D!! 	!R9R==D	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	!ee-1 	3 	3)GWkGGGWk2222
s   266Nr   r>   )r.  rM   r   rM   r/  rM   r   r>   )r6  r)   r   r>   )r6  r)   r   r+  )
r(   rE   rF   r	   r0  rr   r5  r>  r   rC  r   r   r   r+  r+    s               Y
+ + + +F F F F* * * *
    [  r   r+  c                  6    e Zd Zd Zd Zd ZddZddZd ZdS )
HallOfFamec                :    || _         t                      | _        d S r   )r  dict_unique_entriesr  s     r   rr   zHallOfFame.__init__  s    
#vvr   c                ^      fd                                  d  j                 D             S )Nc              3  2   K   | ]}j         |         V  d S r   )rJ  )r   kr   s     r   r   z&HallOfFame.__iter__.<locals>.<genexpr>  s<       
 
()D #
 
 
 
 
 
r   )_sorted_keysr  r   s   `r   r;   zHallOfFame.__iter__  sE    
 
 
 
-1->->-@-@4:-N
 
 
 	
r   c                R    t          | j                                        d          S )NT)reverse)sortedrJ  keysr   s    r   rN  zHallOfFame._sorted_keys  s$    d*//114@@@@r   rL   r   c                6    |j         J || j        |j         <   d S r   )r   rJ  r'  s     r   r5  zHallOfFame.add  s%    {&&&,/S[)))r   r  r=   r   	list[DNA]c                    | j         |                                 }fd|d t          || j                           D             S )Nc                     g | ]
}|         S r   r   r   rM  r2  s     r   r   z"HallOfFame.get.<locals>.<listcomp>  s    CCCq
CCCr   )rJ  rN  minr  )r   r  rR  r2  s      @r   getzHallOfFame.get  sM    &  ""CCCCD)A3udj+A+A)A$BCCCCr   c                    t          | j                  | j        k    rd S | j        |                                 }fd|d | j                 D             | _        d S )Nc                "    i | ]}||         S r   r   rW  s     r   
<dictcomp>z$HallOfFame.purge.<locals>.<dictcomp>  s    JJJ!71:JJJr   )r0   rJ  r  rN  )r   rR  r2  s     @r   purgezHallOfFame.purge  sf    t#$$
22F&  ""JJJJtLdjL7IJJJr   N)rL   r   )r  r=   r   rT  )	r(   rE   rF   rr   r;   rN  r5  rY  r]  r   r   r   rG  rG    s        & & &
 
 

A A A0 0 0 0D D D D
K K K K Kr   rG  r  Sequence[DNA]best_fitness	thresholdr  c                ~    |dk    r$t          | t                    }d|z
  |j        z  n||z  fd| D             S )Nr   r7   r   c              3  2   K   | ]}|j         k    |V  d S r   r"   )r   c	min_values     r   r   z#threshold_filter.<locals>.<genexpr>  s/      ;;!QY%:%:A%:%:%:%:;;r   )rX  rO   r   )r  r_  r`  minimumre  s       @r   threshold_filterrg    sX     sjk2229_7		 9,	;;;;z;;;;r   c                      e Zd ZdZ	 d#d$d	Zd%dZed&d            Zed'd            Zd(dZ		 	 d)d*dZ
d+dZd+dZd,dZd-d!Zd-d"ZdS ).GeneticOptimizera  A genetic algorithm (GA) is a meta-heuristic inspired by the process of
    natural selection. Genetic algorithms are commonly used to generate
    high-quality solutions to optimization and search problems by relying on
    biologically inspired operators such as mutation, crossover and selection.

    Source: https://en.wikipedia.org/wiki/Genetic_algorithm

    This implementation searches always for the maximum fitness, fitness
    comparisons are always done by the "greater than" operator (">").
    The algorithm supports negative values to search for the minimum fitness
    (e.g. Travelling Salesmen Problem: -900 > -1000). Reset the start fitness
    by the method :meth:`reset_fitness` accordingly::

        optimizer.reset_fitness(-1e99)

    r   	evaluatorr%  max_generationsr=   max_fitnessrM   c                ,   |dk     rt          d          d| _        t                      | _        g | _        || _        t                      | _        t                      | _	        t                      | _        t          |          | _        t          |          | _        d| _        d| _        d| _        d| _        d| _        d	| _        d
| _        d	| _        d	| _        t3          g           | _        d	| _        d
| _        t;          d          | _        d S )Nr`   zrequires max_generations > 0ri  g.B}Td   gffffff?g{Gz?   r   r   
   )r   namer+  rD  r  rj  RouletteSelection	selectionr   materW   mutationr=   rk  rM   rl  max_runtimemax_stagnationcrossover_ratemutation_rateelitismr`  
generation
start_timer.  r   best_dnar_  
stagnationrG  hall_of_fame)r   rj  rk  rl  s       r   rr   zGeneticOptimizer.__init__  s     Q;<<<&	55%' %.$5$7$7"**	"  #?33"'"4"4"&!"! !$  !!#BZZ#& &rNNr   r8   r   r>   c                .    t          |          | _        d S r   )rM   r_  )r   r8   s     r   reset_fitnesszGeneticOptimizer.reset_fitness/  s    !%LLr   r   c                *    t          | j                  S r   )r   r{  r   s    r   is_executedzGeneticOptimizer.is_executed2  s    DO$$$r   c                *    t          | j                  S r   )r0   r  r   s    r   r  zGeneticOptimizer.count6  s    4?###r   rL   r  c                f    | j         s| j                            |           d S t          d          )Nzalready executed)r  r  extendr   r'  s     r   add_candidateszGeneticOptimizer.add_candidates:  s8     	0O""3'''''.///r   Nfeedback,Optional[Callable[[GeneticOptimizer], bool]]intervalc                   | j         rt          d          | j        st          d           t	          j                    }|| _        t          d| j        dz             D ]| _	        | 
                                 t	          j                    }|| j        z
  | _        | j        | j        k    s | j        | j        k    s| j        | j        k    r d S |r||z
  |k    r ||           r d S |}|                                  d S )Nzcan only run oncezno DNA defined!r`   )r  r   r  printtimeperf_counterr|  rY   rk  r{  measure_fitnessr.  r_  rl  rv  r~  rw  next_generation)r   r  r  t0t1s        r   executezGeneticOptimizer.execute@  s&   
  	1/000 	%#$$$  $Q(<q(@AA 	# 	#DO  """"$$B/DL!T%555<4#333?d&999 BGh..8D>> EE  """"	# 	#r   c                   | xj         dz  c_         d}| j        D ]t}|j        ||j        z  }| j                            |          }||_        ||z  }| j                            |           || j        k    r|| _        || _        d| _         u| j        	                                 	 |t          | j                  z  }n# t          $ r d}Y nw xY w| j                            t          j                    | j        z
  | j        |           d S )Nr`   r   r   )r~  r  r   rj  r(  r  r5  r_  r}  r]  r0   ZeroDivisionErrorrD  r  r  r|  )r   fitness_sumrL   r   r/  s        r   r  z GeneticOptimizer.measure_fitness[  s3   1 ? 	$ 	$C{&s{*n--c22G!CK7"K!!#&&&***$+! #"#!!!	%DO(<(<<KK  	 	 	KKK	$/1	
 	
 	
 	
 	
s   )C CCc                   t          | j                  }g }| j        }|                    |                     | j                             | j        dk    r2|                    | j                            | j                             t          |          |k     r|	                    d          \  }}|
                                }|
                                }|                     ||           |                     ||           |                    |           |                    |           t          |          |k     || _        d S )Nr   ro  )r0   r  rs  r   filter_thresholdrz  r  r  rY  r  r   r   rT   r4  )r   r  r  selectorr   r   s         r   r  z GeneticOptimizer.next_generationv  s#   DO$$ "
>t,,T_==>>><!d/33DLAABBB*oo%%!q))JD$99;;D99;;DNN4&&&KKd###d###d### *oo%% %r   r  r^  c                R    | j         dk    rt          || j        | j                   S |S )Nr   )r`  rg  r_  r!  s     r   r  z!GeneticOptimizer.filter_threshold  s5    >C#D-t~   r   r   r   r   c                x    t          j                     | j        k     r| j                            ||           d S d S r   )rZ   rx  rt  r   r   s      r   r   zGeneticOptimizer.recombine  s<    =??T000Id+++++ 10r   c                    | j                             || j                   | j                             || j                   d S r   )ru  rT   ry  r   s      r   rT   zGeneticOptimizer.mutate  s>    T4#5666T4#566666r   )r   )rj  r%  rk  r=   rl  rM   )r8   rM   r   r>   rC   )r   r=   )rL   r  r   )r  r  r  rM   r   r>   rE  )r  r^  r   r  r   )r(   rE   rF   rG   rr   r  rK   r  r  r  r  r  r  r  r   rT   r   r   r   ri  ri    s,        * !	&+ &+ &+ &+ &+P) ) ) ) % % % X% $ $ $ X$0 0 0 0 BF# # # # #6
 
 
 
6% % % %&   , , , ,7 7 7 7 7 7r   ri  weightsr   c                    d | D             S )Nc              3  J   K   | ]}|d k    rd ndt          |          z  V  dS r   )abs)r   ws     r   r   z(conv_negative_weights.<locals>.<genexpr>  s8      ??!188CCs1vv??????r   r   )r  s    r   conv_negative_weightsr    s    ??w????r   c                  ,    e Zd ZdZdddZdd
ZddZdS )rr  zSelection by fitness values.Fnegative_valuesr   r   r>   c                J    g | _         g | _        t          |          | _        d S r   )_candidates_weightsr   _negative_values)r   r  s     r   rr   zRouletteSelection.__init__  s'    &(%' $_ 5 5r   r  r  c                    t          |          | _        | j        r2t          t          d | j        D                                 | _        d S d | j        D             | _        d S )Nc              3  $   K   | ]}|j         V  d S r   r"   r   rL   s     r   r   z*RouletteSelection.reset.<locals>.<genexpr>  s$      %N%Ncck%N%N%N%N%N%Nr   c                    g | ]	}|j         
S r   r"   r  s     r   r   z+RouletteSelection.reset.<locals>.<listcomp>  s    EEESS[EEEr   )r   r  r  r  r  r!  s     r   r   zRouletteSelection.reset  so    
++  	F %%N%NT=M%N%N%NNN DMMM FED4DEEEDMMMr   r  r=   c                D    t          j        | j        | j        |          S )N)rM  )rZ   choicesr  r  r  s     r   r  zRouletteSelection.pick  s    ~d.GGGGr   N)F)r  r   r   r>   r#  r"  r(   rE   rF   rG   rr   r   r  r   r   r   rr  rr    se        &&6 6 6 6 6
F F F FH H H H H Hr   rr  c                      e Zd ZdZddZdS )RankBasedSelectionzSelection by rank of fitness.r  r  c                    t          |          | _        | j                            t                     t          t	          dt          | j                  dz                       | _        d S )Nrb  r`   )r   r  sortrO   rY   r0   r  r!  s     r   r   zRankBasedSelection.reset  s[    
+++... U1c$*:&;&;a&?@@AAr   Nr#  )r(   rE   rF   rG   r   r   r   r   r  r    s4        ''B B B B B Br   r  c                  *    e Zd ZdZddZddZdd	Zd
S )TournamentSelectionz@Selection by choosing the best of a certain count of candidates.r  r=   c                "    g | _         || _        d S r   )r  r  r!  s     r   rr   zTournamentSelection.__init__  s    &($r   r  c                .    t          |          | _        d S r   )r   r  r!  s     r   r   zTournamentSelection.reset  s    
++r   r  r   c              #      K   t          |          D ]G} fdt           j                  D             }|                    t                     |d         V  Hd S )Nc                B    g | ]}t          j        j                  S r   )rZ   choicer  )r   r   r   s     r   r   z,TournamentSelection.pick.<locals>.<listcomp>  s3       45d.//  r   rb  )rY   r  r  rO   )r   r  r   r   s   `   r   r  zTournamentSelection.pick  s      u 	 	A   9>t9O9O  F KKKK(((*	 	r   N)r  r=   r#  r"  r  r   r   r   r  r    sV        JJ% % % %, , , ,     r   r  r)  )
r   r   r   r   rw   r=   rb   r=   r   r>   )r  r^  r_  rM   r`  rM   r   r  )r  r   r   r   ).
__future__r   typingr   r   r   r   r   rI   r   dataclassesr	   r=  rZ   r  ABCr   rO   rQ   rW   r]   re   rj   r|   r   r   r   r   r   r   r   r   r   r   r   r  r  r%  r+  rG  rg  ri  r  rr  r  r  r   r   r   <module>r     sA   # " " " " "              


  ! ! ! ! ! !   + + + + +#' + + +\       SW   * * * * * * * *	! 	! 	! 	! 	! 	! 	! 	!! ! ! ! !v ! ! !( ( ( ( (F ( ( ("    V   $    37   6 6 6 6 6t 6 6 6	/ 	/ 	/ 	/ 	/t 	/ 	/ 	/" " " " "D " " "	/ 	/ 	/ 	/ 	/D 	/ 	/ 	/   * * * *   $'4 '4 '4 '4 '4s '4 '4 '4T!2 !2 !2 !2 !2S !2 !2 !2H17 17 17 17 173 17 17 17h*> *> *> *> *> *> *> *>Z	 	 	 	 	 	 	 	              8K K K K K K K K<< < < <b7 b7 b7 b7 b7 b7 b7 b7J@ @ @ @
H H H H H	 H H H,	B 	B 	B 	B 	B* 	B 	B 	B    )     r   