@@ -173,6 +173,33 @@ namespace NEAT
173173 py::object itp = bs::get<py::object>(it->second .m_Details );
174174 t = itp (); // details is a function that returns a random instance of the trait
175175 }
176+
177+ if (it->second .type == " pyclassset" )
178+ {
179+ // this time m_Details is a (list, probs) tuple
180+ // the list is a list of classes that get instantiated
181+ py::object tup = bs::get<py::object>(it->second .m_Details );
182+ py::list classlist = py::extract<py::list>(tup[0 ]);
183+ py::list probs = py::extract<py::list>(tup[1 ]);
184+ std::vector<double > dprobs;
185+
186+ // get the probs
187+ int ln = py::len (probs);
188+ if ((ln == 0 ) || (py::len (classlist) == 0 ))
189+ {
190+ throw std::runtime_error (" Empty class or probs list" );
191+ }
192+
193+ for (int i=0 ; i<ln; i++)
194+ {
195+ dprobs.push_back (py::extract<double >(probs[i]));
196+ }
197+
198+ // instantiate random class
199+ int idx = a_RNG.Roulette (dprobs);
200+ py::object itp = py::extract<py::object>(classlist[idx]);
201+ t = itp ();
202+ }
176203#endif
177204
178205 Trait tr;
@@ -399,7 +426,7 @@ namespace NEAT
399426 did_mutate = true ;
400427 }
401428#ifdef USE_BOOST_PYTHON
402- else if (it->second .type == " pyobject" )
429+ else if (( it->second .type == " pyobject" ) || (it-> second . type == " pyclassset " ) )
403430 {
404431 m_Traits[it->first ].value = bs::get<py::object>(m_Traits[it->first ].value ).attr (" mutate" )();
405432 did_mutate = true ;
@@ -562,7 +589,11 @@ namespace NEAT
562589 // //////////////
563590 LinkGene ()
564591 {
565-
592+ m_FromNeuronID = 0 ;
593+ m_ToNeuronID = 0 ;
594+ m_InnovationID = 0 ;
595+ m_Weight = 0 ;
596+ m_IsRecurrent = false ;
566597 }
567598
568599 LinkGene (int a_InID, int a_OutID, int a_InnovID, double a_Wgt, bool a_Recurrent = false )
0 commit comments