Commit 3dd2879b authored by Javad's avatar Javad
Browse files

Added Backtracking search function

parent a5c3550f
...@@ -45,11 +45,13 @@ add_executable(my_app main.cpp ${source_files} ${tinyxml_src}) ...@@ -45,11 +45,13 @@ add_executable(my_app main.cpp ${source_files} ${tinyxml_src})
#add_executable(test_xmlparser ./test/test_xmlparser.cpp ${source_files} ${tinyxml_src}) #add_executable(test_xmlparser ./test/test_xmlparser.cpp ${source_files} ${tinyxml_src})
#add_executable(test_socialforces ./test/SocialForcesExample.cpp ${source_files} ${tinyxml_src}) #add_executable(test_socialforces ./test/SocialForcesExample.cpp ${source_files} ${tinyxml_src})
#add_executable(test_ttcaDca ./test/DcaTtcaExample.cpp ${source_files} ${tinyxml_src}) #add_executable(test_ttcaDca ./test/DcaTtcaExample.cpp ${source_files} ${tinyxml_src})
add_executable(test_localSearch ./test/TestLocalSearch.cpp ${source_files} ${tinyxml_src})
target_link_libraries(my_app) target_link_libraries(my_app)
#target_link_libraries(test_xmlparser) #target_link_libraries(test_xmlparser)
#target_link_libraries(test_socialforces) #target_link_libraries(test_socialforces)
#target_link_libraries(test_ttcaDca) #target_link_libraries(test_ttcaDca)
target_link_libraries(test_localSearch)
#message(${Boost_LIBRARIES}) #message(${Boost_LIBRARIES})
#message(${Boost_LIBRARY_DIRS}) #message(${Boost_LIBRARY_DIRS})
......
#ifndef LOCALSEARCH_H
#define LOCALSEARCH_H
#include "vector2D.h"
class LocalSearch
{
public:
LocalSearch() {}
static double backtr(Vector2D& x0, Vector2D grad, double (*F)(Vector2D), double alpha_0=1, double gamma=1e-4, double delta=0.5, double rhok=1e-8);
};
#endif // LOCALSEARCH_H
...@@ -56,10 +56,8 @@ class Vector2D { ...@@ -56,10 +56,8 @@ class Vector2D {
void normalize() { void normalize() {
float mag = magnitude(); float mag = magnitude();
if(mag > 0){ x_ /= mag;
x_ /= mag; y_ /= mag;
y_ /= mag;
}
} }
Vector2D getnormalized() { Vector2D getnormalized() {
Vector2D Result(x_, y_); Vector2D Result(x_, y_);
...@@ -67,8 +65,7 @@ class Vector2D { ...@@ -67,8 +65,7 @@ class Vector2D {
return Result; return Result;
} }
float dot(Vector2D * v) { return this->x_ * v->x_ + this->y_ * v->y_;} float dot(Vector2D * v) { return this->x_ * v->x_ + this->y_ * v->y_;}
float dot(const Vector2D& v) { return this->x_ * v.x_ + this->y_ * v.y_; } float dot(Vector2D v) { return this->x_ * v.x_ + this->y_ * v.y_; }
//float dot(Vector2D v) { return this->x_ * v.x_ + this->y_ * v.y_; }
void set(float x, float y) { void set(float x, float y) {
this->x_ = x; this->x_ = x;
...@@ -94,13 +91,15 @@ class Vector2D { ...@@ -94,13 +91,15 @@ class Vector2D {
x_ -= rhs.x(); y_ -= rhs.y(); x_ -= rhs.x(); y_ -= rhs.y();
return *this; return *this;
} }
}; };
Vector2D operator-(const Vector2D& lhs, const Vector2D &rhs); Vector2D operator-(Vector2D lhs, Vector2D rhs);
Vector2D operator+(const Vector2D &lhs, const Vector2D &rhs); Vector2D operator+(Vector2D lhs, Vector2D rhs);
Vector2D operator*(const float lhs, const Vector2D &rhs); Vector2D operator*(float lhs, Vector2D rhs);
Vector2D operator*(const Vector2D &lhs, const float rhs); Vector2D operator*(Vector2D lhs, float rhs);
Vector2D operator/(const Vector2D &lhs, const float rhs); Vector2D operator/(Vector2D lhs, float rhs);
Vector2D operator-(Vector2D lhs);
double norm(Vector2D x);
#endif // LIB_VECTOR2D_H #endif // LIB_VECTOR2D_H
#include "tools/localsearch.h"
#include "iostream"
using namespace std;
double LocalSearch::backtr(Vector2D &x0, Vector2D grad, double (*F)(Vector2D), double alpha_0, double gamma, double delta, double rhok)
{
/*
https://www.mathworks.com/matlabcentral/fileexchange/45572-backtracking-armijo-type?s_tid=FX_rc2_behav
%% BACKTRACKING ARMIJO-TYPE
% DESCRIPTION:
% Search method along a coordinate axis in which the search should be conducted
% in both directions of the axis. It should also take into account the fact that
% one direction dk can be assigned such that alpha=0 represents a
% local minimum point of the function g(alpha)=F(xk+alpha*dk), for which
% may not be able to find positive or negative values ??of alpha
% close to 0 for which g(alpha)<g(0). If you do not want to use any
% derivative, numerical "finished" procedures must define can
% discriminate the situation. The model presented is an outline
% Backtracking Armijo-type, based on the condition of acceptability of type "Parabolic".
%
% function [alpha] = backtr(alpha_guess,Xk,dk,F,gamma,delta,rhok)
% INPUT:
% NOTE: (*) indicates necessary input, the other variables are optional
% (*) alpha _guess - current steplength (1*1) [>0];
% (*) Xk - current iterate (N*1);
% (*) dk - search direction (N*1);
% gamma - constant provided by the user (1*1) [>0];
% delta - constant provided by the user (1*1) into the range [0, 1];
% rhok - constant provided by the user (1*1) into the range [0, 1];
% (*) F - function handle of the objective function (RN->R );
% OUTPUT:
% alpha - value of alpha whether the condition holds (1*1);
% REVISION:
% Ennio Condoleo - 21.15 13 Feb 2014
% REFERENCE: https://goo.gl/TUoCYu
%
*/
Vector2D Xk = x0;
Vector2D dk = grad;
F(Xk); // test
// positive direction (+)alpha
double alpha = alpha_0;
while (F(Xk+alpha*dk)>F(Xk)-gamma*alpha*alpha*pow(norm(dk),2))
{
if (alpha*norm(dk) < rhok)
alpha = 0; // % <-- failure to search for a value of alpha nonzero
else
alpha = alpha*delta; // % <-- reduction of the steplength
}
double alpha1 = alpha;
double F1 = F(Xk+alpha1*dk)-(F(Xk)-gamma*alpha1*alpha1*pow(norm(dk),2));
// negative direction (-)alpha
alpha = alpha_0;
while (F(Xk-alpha*dk)>F(Xk)-gamma*alpha*alpha*pow(norm(dk),2))
{
if (alpha*norm(dk) < rhok)
alpha = 0; // % <-- failure to search for a value of alpha nonzero
else
alpha = alpha*delta; // % <-- reduction of the steplength
}
double alpha2 = -alpha;
double F2 = F(Xk+alpha2*dk)-(F(Xk)-gamma*alpha2*alpha2*pow(norm(dk),2));
// choice of the value of alpha for which it is provided with sufficient reduction
if (F1<F2)
alpha = alpha1;
else
alpha = alpha2;
return alpha;
}
...@@ -24,21 +24,31 @@ ...@@ -24,21 +24,31 @@
*/ */
#include <tools/vector2D.h> #include "tools/vector2D.h"
Vector2D operator-(const Vector2D& lhs, const Vector2D &rhs) { Vector2D operator-(Vector2D lhs, Vector2D rhs) {
return Vector2D(lhs.x() - rhs.x(), lhs.y() - rhs.y()); return Vector2D(lhs.x() - rhs.x(), lhs.y() - rhs.y());
} }
Vector2D operator+(const Vector2D &lhs, const Vector2D &rhs) { Vector2D operator+(Vector2D lhs, Vector2D rhs) {
return Vector2D(lhs.x() + rhs.x(), lhs.y() + rhs.y()); return Vector2D(lhs.x() + rhs.x(), lhs.y() + rhs.y());
} }
Vector2D operator*(const float lhs, const Vector2D &rhs) { Vector2D operator*(float lhs, Vector2D rhs) {
return Vector2D(rhs.x() * lhs, rhs.y() * lhs); return Vector2D(rhs.x() * lhs, rhs.y() * lhs);
} }
Vector2D operator*(const Vector2D &lhs, const float rhs) { Vector2D operator*(Vector2D lhs, float rhs) {
return rhs * lhs; return rhs * lhs;
} }
Vector2D operator/(const Vector2D &lhs, const float rhs) { Vector2D operator/(Vector2D lhs, float rhs) {
return (1.f / rhs) * lhs; return (1.f / rhs) * lhs;
} }
\ No newline at end of file double norm(Vector2D x)
{
double sum2 = x.x() * x.x() + x.y() * x.y();
return sqrt(sum2);
}
Vector2D operator-(Vector2D lhs)
{
return Vector2D(-lhs.x(), -lhs.y());
}
#include "tools/localsearch.h"
#include "tools/vector2D.h"
#include <iostream>
using namespace std;
// (𝑥 − 2)^2 ==> 𝑥* = 2
double testfunc(Vector2D x, Vector2D* grad = NULL)
{
double y = pow(x.x() -2, 2);
cout << "f(" << x.x() << ") = " << y << endl;
if(grad)
{
double g = 2 * pow((x.x()-2), 1);
cout << "grad(" << x.x() << ") = " << g << endl;
grad->set(g, 0);
}
return y;
}
double f(Vector2D x)
{
return testfunc(x, NULL);
}
int main(int argc, char *argv[])
{
Vector2D x0(0, 0);
Vector2D g;
int N_ITR = 5;
for (int i=0; i<N_ITR; i++) {
testfunc(x0, &g);
double alfa = LocalSearch::backtr(x0, -g, f, 10, 1e-4, 0.5);
x0 = x0 - alfa * g;
}
cout << "********** Result ***************\n" ;
f(x0);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment