vector<bool> OnePoint::do_crossover(Chromosome& c1, Chromosome& c2) { vector<bool> crossed(flm_conf.chromosome_length, false); // swap tails for (int i = pick_point(); i < flm_conf.chromosome_length; i++) { swap(c1[i], c2[i]); crossed[i] = true; } return crossed; }
vector<bool> TwoPoint::do_crossover(Chromosome& c1, Chromosome& c2) { vector<bool> crossed(flm_conf.chromosome_length, false); pair<int, int> range = pick_range(); // swap range for (int i = range.first; i <= range.second; i++) { swap(c1[i], c2[i]); crossed[i] = true; } return crossed; }
vector<bool> Uniform::do_crossover(Chromosome& c1, Chromosome& c2) { vector<bool> crossed(flm_conf.chromosome_length, false); for (int j = 0; j < flm_conf.chromosome_length; j++) { if (random_bit()) { swap(c1[j], c2[j]); crossed[j] = true; } } return crossed; }
/////////////////////////////// INTERFACE //////////////////////////////// void GeneticClass::Interface(){ lc = 10000; int algorithmIteration = 30; float crossoverRatio = 0.9; int mutationIteration = 1000; int score = 0, parent1, parent2; DrawingPopulation(); Rating(); cout << "Rodzice: " << bestScoreInAll << endl; checksRepeatsInSet(); ////////////// SELEKCJA I KRZYZOWANIE I MUTACJA/////////////////////////////// for (int z = 0; z<algorithmIteration; z++){ int P = -1; // licznik nowej populacji vector<bool> crossed(lc,false); int crossoverIterations = (lc - 2) * crossoverRatio; #pragma omp parallel for for (P = -1; P < crossoverIterations; P += 2) { parent1 = TournamentSelection(10); do parent2 = TournamentSelection(10); while (parent1 == parent2); crossed[parent1] = true; crossed[parent2] = true; Crossover(parent1, parent2, children[P + 1], children[P + 2]); } for (int i = 0 ; i < lc; i++) { //Dopisuje do children osobniki ktore nie braly udzialu w krzyzowaniu if (crossoverIterations != lc) { if (crossed[i] == false) { children[crossoverIterations++] = chromosom[i]; } } else { break; } } chromosom.swap(children); for (int i = 0; i<mutationIteration; i++){ int target = TournamentSelection(100); Mutation(chromosom[target]); // przy zakomentowanym krzyzowaniu wpisalem tu chromosom zamiast children } checksRepeatsInSet(); score = Rating(); cout << "Populacja_" << z << " = " << score << endl; } showBest(); }
bool Brush::intersectsBrush(const Brush& brush) const { if (!bounds().intersects(brush.bounds())) return false; // separating axis theorem // http://www.geometrictools.com/Documentation/MethodOfSeparatingAxes.pdf FaceList::const_iterator faceIt, faceEnd; const VertexList& myVertices = vertices(); const FaceList& theirFaces = brush.faces(); for (faceIt = theirFaces.begin(), faceEnd = theirFaces.end(); faceIt != faceEnd; ++faceIt) { const Face& theirFace = **faceIt; const Vec3f& origin = theirFace.vertices().front()->position; const Vec3f& direction = theirFace.boundary().normal; if (vertexStatusFromRay(origin, direction, myVertices) == PointStatus::PSAbove) return false; } const VertexList& theirVertices = brush.vertices(); for (faceIt = m_faces.begin(), faceEnd = m_faces.end(); faceIt != faceEnd; ++faceIt) { const Face& myFace = **faceIt; const Vec3f& origin = myFace.vertices().front()->position; const Vec3f& direction = myFace.boundary().normal; if (vertexStatusFromRay(origin, direction, theirVertices) == PointStatus::PSAbove) return false; } const EdgeList& myEdges = edges(); const EdgeList& theirEdges = brush.edges(); EdgeList::const_iterator myEdgeIt, myEdgeEnd, theirEdgeIt, theirEdgeEnd; for (myEdgeIt = myEdges.begin(), myEdgeEnd = myEdges.end(); myEdgeIt != myEdgeEnd; ++myEdgeIt) { const Edge& myEdge = **myEdgeIt; for (theirEdgeIt = theirEdges.begin(), theirEdgeEnd = theirEdges.end(); theirEdgeIt != theirEdgeEnd; ++theirEdgeIt) { const Edge& theirEdge = **theirEdgeIt; const Vec3f myEdgeVec = myEdge.vector(); const Vec3f theirEdgeVec = theirEdge.vector(); const Vec3f& origin = myEdge.start->position; const Vec3f direction = crossed(myEdgeVec, theirEdgeVec); PointStatus::Type myStatus = vertexStatusFromRay(origin, direction, myVertices); if (myStatus != PointStatus::PSInside) { PointStatus::Type theirStatus = vertexStatusFromRay(origin, direction, theirVertices); if (theirStatus != PointStatus::PSInside) { if (myStatus != theirStatus) return false; } } } } return true; }
vector<bool> Hybrid::do_crossover(Chromosome& c1, Chromosome& c2) { vector<bool> crossed(flm_conf.chromosome_length, false); // Do two point crossover in first part int smoothing_beginning = flm_conf.chromosome_length - flm_conf.smooth_len; pair<int, int> range = pick_range(smoothing_beginning); for (int i = range.first; i < range.second; i++) { swap(c1[i], c2[i]); crossed[i] = true; } // Do uniform crossover in the smoothing part for (int j = smoothing_beginning; j < flm_conf.chromosome_length; j++) { if (random_bit()) { swap(c1[j], c2[j]); crossed[j] = true; } } return crossed; }
TEST(VecTest, vec3fCrossProduct) { ASSERT_EQ(Vec3f::Null, crossed(Vec3f::Null, Vec3f::Null)); ASSERT_EQ(Vec3f::Null, crossed(Vec3f::Null, Vec3f(2.0f, 34.233f, -10003.0002f))); ASSERT_EQ(Vec3f::PosZ, crossed(Vec3f::PosX, Vec3f::PosY)); ASSERT_VEC_EQ(Vec3f(-2735141.499f, 282853.508f, 421.138f), crossed(Vec3f(12.302f, -0.0017f, 79898.3f), Vec3f(2.0f, 34.233f, -10003.0002f))); const Vec3f t1(7.0f, 4.0f, 0.0f); const Vec3f t2(-2.0f, 22.0f, 0.0f); const Vec3f c1 = crossed(t1, t2).normalized(); const Vec3f c2 = crossed(t1.normalized(), t2.normalized()).normalized(); ASSERT_VEC_EQ(c1, c2); }
ParaxialTexCoordSystem::ParaxialTexCoordSystem(const Vec3& point0, const Vec3& point1, const Vec3& point2, const BrushFaceAttributes& attribs) : m_index(0) { const Vec3 normal = crossed(point2 - point0, point1 - point0).normalized(); setRotation(normal, 0.0f, attribs.rotation()); }
void ParaxialTexCoordSystem::rotateAxes(Vec3& xAxis, Vec3& yAxis, const FloatType angleInRadians, const size_t planeNormIndex) const { const Vec3 rotAxis = crossed(BaseAxes[planeNormIndex * 3 + 2], BaseAxes[planeNormIndex * 3 + 1]); const Quat3 rot(rotAxis, angleInRadians); xAxis = rot * xAxis; yAxis = rot * yAxis; }
void ParaxialTexCoordSystem::doTransform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttributes& attribs, bool lockTexture, const Vec3& oldInvariant) { const Vec3 offset = transformation * Vec3::Null; const Vec3& oldNormal = oldBoundary.normal; Vec3 newNormal = transformation * oldNormal - offset; assert(Math::eq(newNormal.length(), 1.0)); // fix some rounding errors - if the old and new texture axes are almost the same, use the old axis if (newNormal.equals(oldNormal, 0.01)) newNormal = oldNormal; if (!lockTexture || attribs.xScale() == 0.0f || attribs.yScale() == 0.0f) { setRotation(newNormal, attribs.rotation(), attribs.rotation()); return; } // calculate the current texture coordinates of the origin const Vec2f oldInvariantTexCoords = computeTexCoords(oldInvariant, attribs.scale()) + attribs.offset(); // project the texture axes onto the boundary plane along the texture Z axis const Vec3 boundaryOffset = oldBoundary.project(Vec3::Null, getZAxis()); const Vec3 oldXAxisOnBoundary = oldBoundary.project(m_xAxis * attribs.xScale(), getZAxis()) - boundaryOffset; const Vec3 oldYAxisOnBoundary = oldBoundary.project(m_yAxis * attribs.yScale(), getZAxis()) - boundaryOffset; // transform the projected texture axes and compensate the translational component const Vec3 transformedXAxis = transformation * oldXAxisOnBoundary - offset; const Vec3 transformedYAxis = transformation * oldYAxisOnBoundary - offset; const Vec2f textureSize = attribs.textureSize(); const bool preferX = textureSize.x() >= textureSize.y(); /* const FloatType dotX = transformedXAxis.normalized().dot(oldXAxisOnBoundary.normalized()); const FloatType dotY = transformedYAxis.normalized().dot(oldYAxisOnBoundary.normalized()); const bool preferX = Math::abs(dotX) < Math::abs(dotY); */ // obtain the new texture plane norm and the new base texture axes Vec3 newBaseXAxis, newBaseYAxis, newProjectionAxis; const size_t newIndex = planeNormalIndex(newNormal); axes(newIndex, newBaseXAxis, newBaseYAxis, newProjectionAxis); const Plane3 newTexturePlane(0.0, newProjectionAxis); // project the transformed texture axes onto the new texture projection plane const Vec3 projectedTransformedXAxis = newTexturePlane.project(transformedXAxis); const Vec3 projectedTransformedYAxis = newTexturePlane.project(transformedYAxis); assert(!projectedTransformedXAxis.nan() && !projectedTransformedYAxis.nan()); const Vec3 normalizedXAxis = projectedTransformedXAxis.normalized(); const Vec3 normalizedYAxis = projectedTransformedYAxis.normalized(); // determine the rotation angle from the dot product of the new base axes and the transformed, projected and normalized texture axes float cosX = static_cast<float>(newBaseXAxis.dot(normalizedXAxis.normalized())); float cosY = static_cast<float>(newBaseYAxis.dot(normalizedYAxis.normalized())); assert(!Math::isnan(cosX)); assert(!Math::isnan(cosY)); float radX = std::acos(cosX); if (crossed(newBaseXAxis, normalizedXAxis).dot(newProjectionAxis) < 0.0) radX *= -1.0f; float radY = std::acos(cosY); if (crossed(newBaseYAxis, normalizedYAxis).dot(newProjectionAxis) < 0.0) radY *= -1.0f; // TODO: be smarter about choosing between the X and Y axis rotations - sometimes either // one can be better float rad = preferX ? radX : radY; // for some reason, when the texture plane normal is the Y axis, we must rotation clockwise if (newIndex == 4) rad *= -1.0f; const float newRotation = Math::correct(Math::normalizeDegrees(Math::degrees(rad)), 4); doSetRotation(newNormal, newRotation, newRotation); // finally compute the scaling factors Vec2f newScale = Vec2f(projectedTransformedXAxis.length(), projectedTransformedYAxis.length()).corrected(4); // the sign of the scaling factors depends on the angle between the new texture axis and the projected transformed axis if (m_xAxis.dot(normalizedXAxis) < 0.0) newScale[0] *= -1.0f; if (m_yAxis.dot(normalizedYAxis) < 0.0) newScale[1] *= -1.0f; // compute the parameters of the transformed texture coordinate system const Vec3 newInvariant = transformation * oldInvariant; // determine the new texture coordinates of the transformed center of the face, sans offsets const Vec2f newInvariantTexCoords = computeTexCoords(newInvariant, newScale); // since the center should be invariant, the offsets are determined by the difference of the current and // the original texture coordiknates of the center const Vec2f newOffset = attribs.modOffset(oldInvariantTexCoords - newInvariantTexCoords).corrected(4); assert(!newOffset.nan()); assert(!newScale.nan()); assert(!Math::isnan(newRotation)); assert(!Math::zero(newScale.x())); assert(!Math::zero(newScale.y())); attribs.setOffset(newOffset); attribs.setScale(newScale); attribs.setRotation(newRotation); }