Advertisement
Guest User

Untitled

a guest
Jun 23rd, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.25 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cmath>
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <vector>
  6.  
  7. typedef float(*function)( const float *args );
  8.  
  9. const float PHI = ( 1.0f + std::sqrt( 5.0f ) ) / 2.0f;
  10. const float RESPHI = 2.0f - PHI;
  11.  
  12. int it = 0;
  13.  
  14.  
  15. float f( const float *args )
  16. {
  17. it += 1;
  18.  
  19. const float x = args[0];
  20.  
  21. return 2*x*2*x - 12 * x;
  22. }
  23.  
  24. float rosenbrock( const float *args )
  25. {
  26. it += 1;
  27. const float x = args[0];
  28. const float y = args[1];
  29.  
  30. return ( 100.0f * ( y - x * x ) * ( y - x * x ) + ( 1.0f - x ) * ( 1.0f - x ) );
  31. }
  32.  
  33.  
  34. void Bisection();
  35. void GoldenSection();
  36. void Powell(); //квадратична интерполци
  37. void HookeJeeves();
  38. void NelderMead();
  39.  
  40. void print_menu();
  41.  
  42. float BisectionSearch( function f, float a, float b, const float exp = 0.01f );
  43. float GoldenSectionSearch2( function f, float a, float b, const float exp = 0.01f );
  44. void HookeJeeves( function f, const int n, const float *startpt, float *endpt, const float rho, float exp );
  45. void NelderMead( function func, float *start, const int n, const float exp, const float scale );
  46. float PowellSearch( function f, const float x, const float dx, const float expf = 0.01f, const float expx = 0.01f );
  47.  
  48. int main()
  49. {
  50. print_menu();
  51.  
  52. int method = 0;
  53. while( std::cin >> method )
  54. {
  55. switch( method )
  56. {
  57. case 1:
  58. Bisection();
  59. break;
  60. case 2:
  61. GoldenSection();
  62. break;
  63. case 3:
  64. Powell();
  65. break;
  66. case 4:
  67. HookeJeeves();
  68. break;
  69. case 5:
  70. NelderMead();
  71. break;
  72. default:
  73. std::cout << "Error!\n";
  74. break;
  75. }
  76. }
  77. }
  78.  
  79. void print_menu()
  80. {
  81. std::cout << "\tMenu:\n";
  82.  
  83. std::cout << '1' << " Bisection method\n";
  84. std::cout << '2' << " Goldensection method\n";
  85. std::cout << '3' << " Powell method\n"; //Квадратичная интерполяция
  86. std::cout << '4' << " Hooke-Jeeves method\n";
  87. std::cout << '5' << " Nelder-Mead method\n"; //Симплекс метод
  88. }
  89.  
  90. void Bisection()
  91. {
  92. it = 0;
  93.  
  94. float a = 0.0f;
  95. float b = 0.0f;
  96. float exp = 0.0f;
  97.  
  98. std::cout << "a = ";
  99. std::cin >> a;
  100.  
  101. std::cout << "b = ";
  102. std::cin >> b;
  103.  
  104. std::cout << "e = ";
  105. std::cin >> exp;
  106.  
  107. printf( "\n\tBisection search\n" );
  108. float x = BisectionSearch( f, a, b, exp );
  109. std::cout << "Min x =\t" << std::fixed << x << '\n';
  110. std::cout << "F(x) =\t" << std::fixed << f( &x ) << '\n';
  111. std::cout << "Function call = " << it << "\n\n";
  112. }
  113.  
  114. void GoldenSection()
  115. {
  116. float a, b, exp;
  117.  
  118. std::cout << "a = ";
  119. std::cin >> a;
  120.  
  121. std::cout << "b = ";
  122. std::cin >> b;
  123.  
  124. std::cout << "e = ";
  125. std::cin >> exp;
  126.  
  127. it = 0;
  128. float x = GoldenSectionSearch( f, a, b, exp );
  129. std::cout << "\n\tGolden section search\n";
  130. std::cout << "Min x =\t" << std::fixed << x << '\n';
  131. std::cout << "F(x) =\t" << std::fixed << f( &x ) << '\n';
  132. std::cout << "Function call = " << it << "\n\n";
  133. }
  134.  
  135.  
  136. void Powell()
  137. {
  138. it = 0;
  139.  
  140. float x1 = 0.0f;
  141. float dx = 0.0f;
  142. float ef = 0.0f;
  143. float ex = 0.0f;
  144.  
  145. std::cout << "x1 = ";
  146. std::cin >> x1;
  147.  
  148. std::cout << "dx = ";
  149. std::cin >> dx;
  150.  
  151. std::cout << "ef = ";
  152. std::cin >> ef;
  153.  
  154. std::cout << "ex = ";
  155. std::cin >> ex;
  156.  
  157.  
  158. const float x = PowellSearch( f, x1, dx, ef, ex );
  159. std::cout << "\n\tPowell section search\n";
  160. std::cout << "Min x =\t" << std::fixed << x << '\n';
  161. std::cout << "F(x) =\t" << std::fixed << f( &x ) << '\n';
  162. std::cout << "Function call = " << it << "\n\n";
  163. }
  164.  
  165. void HookeJeeves()
  166. {
  167. it = 0;
  168. float startpt[2];
  169. float endpt[2];
  170.  
  171. float exp = 0.0f;
  172.  
  173. std::cout << "x = ";
  174. std::cin >> startpt[0];
  175.  
  176. std::cout << "y = ";
  177. std::cin >> startpt[1];
  178.  
  179. std::cout << "e = ";
  180. std::cin >> exp;
  181.  
  182. HookeJeeves( rosenbrock, 2, startpt, endpt, 0.65f, exp );
  183. std::cout << "\n\tHooke Jeeves search\n";
  184. std::cout << "Min \n";
  185. for( int i = 0; i < 2; i++ )
  186. {
  187. printf( "%c =\t%.9f\n", i == 0 ? 'x' : 'y', endpt[i] );
  188. }
  189.  
  190. std::cout << "F(x, y) =\t" << std::fixed << rosenbrock( endpt ) << '\n';
  191. std::cout << "Function call = " << it << "\n\n";
  192. }
  193.  
  194. void NelderMead()
  195. {
  196. it = 0;
  197. float start[2];
  198.  
  199. float exp = 0.0f;
  200.  
  201. std::cout << "x = ";
  202. std::cin >> start[0];
  203.  
  204. std::cout << "y = ";
  205. std::cin >> start[1];
  206.  
  207. std::cout << "e = ";
  208. std::cin >> exp;
  209.  
  210. std::cout << "\n\tNelder Mead search";
  211. NelderMead( rosenbrock, start, 2, exp, 1.0f );
  212. std::cout << "Function call = " << it << '\n';
  213. }
  214.  
  215.  
  216. //Метод бисекции
  217. float BisectionSearch( function f, float a, float b, const float exp )
  218. {
  219. float x1 = 0.0f;
  220. float x2 = 0.0f;
  221.  
  222. float f1 = 0.0f;
  223. float f2 = 0.0f;
  224.  
  225. float xm = (a + b) / 2.0f;
  226. float fm = f( &xm );
  227.  
  228. do
  229. {
  230. x1 = (xm + a) / 2.0f;
  231. f1 = f( &x1 );
  232.  
  233. x2 = (xm + b) / 2.0f;
  234. f2 = f( &x2 );
  235.  
  236. if( f1 < fm )
  237. {
  238. b = xm;
  239. xm = x1;
  240. fm = f1;
  241. }
  242. else
  243. {
  244. if( fm > f2 )
  245. {
  246. a = xm;
  247. xm = x2;
  248. fm = f2;
  249. }
  250. else
  251. {
  252. a = x1;
  253. b = x2;
  254. }
  255. }
  256.  
  257. } while( std::abs( b - a ) > exp );
  258.  
  259. return (a + b) / 2.0f;
  260. }
  261.  
  262.  
  263.  
  264.  
  265. //Метод золотого сечения
  266. float GoldenSectionSearch2( function f, float a, float b, const float exp )
  267. {
  268. float x1 = b - ( b - a ) / PHI;
  269. float x2 = a + ( b - a ) / PHI;
  270.  
  271. float f1 = f( &x1 );
  272. float f2 = f( &x2 );
  273.  
  274. while( ( b - a ) / 2.0f >= exp )
  275. {
  276. if( f1 < f2 )
  277. {
  278. b = x2;
  279. x2 = x1;
  280. x1 = a + ( b - x2 );
  281.  
  282. f1 = f( &x1 );
  283. }
  284. else
  285. {
  286. a = x1;
  287. x1 = x2;
  288. x2 = b - ( x1 - a );
  289.  
  290. f2 = f( &x2 );
  291. }
  292. }
  293.  
  294. return ( a + b ) / 2.0f;
  295. }
  296.  
  297. struct Point_t
  298. {
  299. float x;
  300. float f;
  301. };
  302.  
  303.  
  304. //Квадратичная интерполяция
  305. float Approximation( const Point_t p[3] )
  306. {
  307. float x1 = p[0].x;
  308. float x2 = p[1].x;
  309. float x3 = p[2].x;
  310.  
  311. float f1 = p[0].f;
  312. float f2 = p[1].f;
  313. float f3 = p[2].f;
  314.  
  315. const float a1 = ( f2 - f1 ) / ( x2 - x1 );
  316. const float a2 = ( 1.0f / ( x3 - x2 ) ) * ( ( ( f3 - f1 ) / ( x3 - x1 ) ) - a1 );
  317.  
  318. const float xdash = ( ( x2 + x1 ) / 2.0f ) - ( a1 / ( 2.0f * a2 ) );
  319.  
  320. return xdash;
  321. }
  322.  
  323. float PowellSearch( function f, const float x, const float dx, const float expf, const float expx )
  324. {
  325. float x1 = x;
  326. float x2 = x1 + dx;
  327. float x3 = 0.0f;
  328.  
  329. float f1 = f( &x1 );
  330. float f2 = f( &x2 );
  331. float f3 = 0.0f;
  332.  
  333. if( f1 > f2 )
  334. {
  335. x3 = x1 + dx;
  336. }
  337. if( f1 < f2 )
  338. {
  339. x3 = x1 - dx;
  340. }
  341.  
  342. f3 = f( &x3 );
  343.  
  344. Point_t p[3] = { { x1, f2 }, { x2, f2 }, { x3, f3 } };
  345.  
  346. float xdash = 0.0f;
  347. float fdash = 0.0f;
  348.  
  349. do
  350. {
  351. std::sort( p, p + 3, []( const Point_t &a, const Point_t &b ) -> bool
  352. {
  353. return a.f < b.f;
  354. } );
  355.  
  356. xdash = Approximation( p );
  357. fdash = f( &xdash );
  358.  
  359. p[2].x = xdash;
  360. p[2].f = fdash;
  361.  
  362. } while( ( std::fabs( p[0].f - fdash ) > expf && ( std::fabs( p[0].x - xdash ) > expx ) ) );
  363.  
  364. return xdash;
  365. }
  366.  
  367.  
  368. //Метод Хука-Дживса
  369. float best_nearby( function f, float *delta, float *point, const float prevbest, const int n )
  370. {
  371. float z[2];
  372.  
  373. float minf = prevbest;
  374.  
  375. for( int i = 0; i < n; i++ )
  376. {
  377. z[i] = point[i];
  378. }
  379.  
  380. for( int i = 0; i < n; i++ )
  381. {
  382. z[i] = point[i] + delta[i];
  383. float ftmp = f( z );
  384.  
  385. if( ftmp < minf )
  386. {
  387. minf = ftmp;
  388. }
  389. else
  390. {
  391. delta[i] = 0.0f - delta[i];
  392. z[i] = point[i] + delta[i];
  393. ftmp = f( z );
  394.  
  395. if( ftmp < minf )
  396. {
  397. minf = ftmp;
  398. }
  399. else
  400. {
  401. z[i] = point[i];
  402. }
  403. }
  404. }
  405.  
  406. for( int i = 0; i < n; i++ )
  407. {
  408. point[i] = z[i];
  409. }
  410.  
  411. return minf;
  412. }
  413.  
  414. void HookeJeeves( function f, const int n, const float *startpt, float *endpt, const float rho, float exp )
  415. {
  416. float delta[2];
  417. float xbefore[2];
  418. float newx[2];
  419.  
  420. float steplength = rho;
  421.  
  422. for( int i = 0; i < n; i++ )
  423. {
  424. newx[i] = startpt[i];
  425. xbefore[i] = startpt[i];
  426.  
  427. delta[i] = std::fabs( startpt[i] * steplength );
  428.  
  429. if( delta[i] == 0.0 )
  430. {
  431. delta[i] = steplength;
  432. }
  433. }
  434.  
  435. float fbefore = f( newx );
  436.  
  437. float newf = fbefore;
  438.  
  439. while( ( steplength > exp ) )
  440. {
  441. for( int i = 0; i < n; i++ )
  442. {
  443. newx[i] = xbefore[i];
  444. }
  445.  
  446. newf = best_nearby( f, delta, newx, fbefore, n);
  447.  
  448. while( ( newf < fbefore ) )
  449. {
  450. for( int i = 0; i < n; i++ )
  451. {
  452. if( newx[i] <= xbefore[i] )
  453. {
  454. delta[i] = 0.0f - std::fabs( delta[i] );
  455. }
  456. else
  457. {
  458. delta[i] = std::fabs( delta[i] );
  459. }
  460.  
  461. float tmp = xbefore[i];
  462. xbefore[i] = newx[i];
  463. newx[i] = newx[i] + newx[i] - tmp;
  464. }
  465. fbefore = newf;
  466. newf = best_nearby( f, delta, newx, fbefore, n);
  467.  
  468. if( newf >= fbefore )
  469. {
  470. break;
  471. }
  472. }
  473. if( ( steplength >= exp) && (newf >= fbefore) )
  474. {
  475. steplength *= rho;
  476. for( int i = 0; i < n; i++)
  477. {
  478. delta[i] *= rho;
  479. }
  480. }
  481. }
  482. for( int i = 0; i < n; i++ )
  483. {
  484. endpt[i] = xbefore[i];
  485. }
  486. }
  487.  
  488.  
  489. //Симплекс-метод
  490.  
  491. const float ALPHA = 1.0f;
  492. const float BETA = 0.5;
  493. const float GAMMA = 2.0;
  494.  
  495. void NelderMead( function func, float *start, const int n, const float exp, const float scale )
  496. {
  497. int vs;
  498. int vh;
  499. int vg;
  500.  
  501. float pn,qn;
  502. float fr;
  503. float fe;
  504. float fc;
  505.  
  506. std::vector<std::vector<float>> v( n + 1, std::vector<float>( n ) );
  507. std::vector<float> f( n + 1, 0.0f );
  508. std::vector<float> vr( n, 0.0f );
  509. std::vector<float> ve( n, 0.0f );
  510. std::vector<float> vc( n, 0.0f );
  511. std::vector<float> vm( n, 0.0f );
  512.  
  513.  
  514. pn = scale * ( std::sqrt( n + 1.0f ) - 1.0f + n ) / ( n * std::sqrt( 2.0f ) );
  515. qn = scale * ( std::sqrt( n + 1.0f ) - 1.0f ) / ( n * std::sqrt( 2.0f ) );
  516.  
  517. for( int i = 0; i < n; i++ )
  518. {
  519. v[0][i] = start[i];
  520. }
  521.  
  522. for( int i = 1; i <= n; i++ )
  523. {
  524. for( int j = 0; j < n; j++ )
  525. {
  526. if( i - 1 == j )
  527. {
  528. v[i][j] = pn + start[j];
  529. }
  530. else
  531. {
  532. v[i][j] = qn + start[j];
  533. }
  534. }
  535. }
  536.  
  537. for( int j = 0; j <= n; j++ )
  538. {
  539. f[j] = func( v[j].data() );
  540. }
  541.  
  542.  
  543. while( true )
  544. {
  545. //2.
  546. vg = 0;
  547. for( int j = 0; j <= n; j++ )
  548. {
  549. if( f[j] > f[vg] )
  550. {
  551. vg = j;
  552. }
  553. }
  554.  
  555. vs = 0;
  556. for( int j=0; j <= n; j++ )
  557. {
  558. if( f[j] < f[vs] )
  559. {
  560. vs = j;
  561. }
  562. }
  563.  
  564. vh = vs;
  565. for( int j = 0; j <= n; j++ )
  566. {
  567. if( f[j] > f[vh] && f[j] < f[vg] )
  568. {
  569. vh = j;
  570. }
  571. }
  572.  
  573. //3.
  574. for( int j = 0; j <= n-1; j++ )
  575. {
  576. float cent = 0.0f;
  577. for( int m = 0; m <= n; m++ )
  578. {
  579. if( m != vg )
  580. {
  581. cent += v[m][j];
  582. }
  583. }
  584. vm[j] = cent / n;
  585. }
  586.  
  587. //4.
  588. for( int j = 0; j <= n-1; j++ )
  589. {
  590. vr[j] = ( 1.0f + ALPHA ) * vm[j] - ALPHA * v[vg][j];
  591. }
  592. fr = func( vr.data() );
  593.  
  594. if( fr <= f[vh] && fr > f[vs] )
  595. {
  596. v[vg] = vr;
  597. f[vg] = fr;
  598. }
  599.  
  600. if( fr <= f[vs] )
  601. {
  602. for( int j = 0; j <= n - 1; j++ )
  603. {
  604. ve[j] = ( 1.0f - GAMMA ) * vm[j] + GAMMA * vr[j];
  605. }
  606. fe = func( ve.data() );
  607.  
  608. if (fe < fr)
  609. {
  610. v[vg] = ve;
  611. f[vg] = fe;
  612. }
  613. else
  614. {
  615. v[vg] = vr;
  616. f[vg] = fr;
  617. }
  618. }
  619.  
  620. if( fr > f[vh] )
  621. {
  622. for( int j = 0; j <= n - 1; j++ )
  623. {
  624. vc[j] = BETA * v[vg][j] + ( 1.0f - BETA ) * vm[j];
  625. }
  626.  
  627. fc = func( vc.data() );
  628.  
  629.  
  630. if( fc < f[vg] )
  631. {
  632. v[vg] = vc;
  633. f[vg] = fc;
  634. }
  635. else
  636. {
  637. for( int row = 0; row <= n; row++ )
  638. {
  639. if( row != vs )
  640. {
  641. for( int j = 0; j <= n - 1; j++ )
  642. {
  643. v[row][j] = v[vs][j] + ( v[row][j] - v[vs][j] ) / 2.0f;
  644. }
  645. }
  646. }
  647. f[vg] = func( v[vg].data() );
  648.  
  649. f[vh] = func( v[vh].data() );
  650. }
  651. }
  652.  
  653. float fsum = 0.0;
  654.  
  655. for( int j = 0; j <= n; j++ )
  656. {
  657. fsum += f[j];
  658. }
  659.  
  660. float favg = fsum / ( n + 1 );
  661. float s = 0.0f;
  662.  
  663. for( int j = 0; j <= n; j++ )
  664. {
  665. s += pow( ( f[j] - favg ), 2.0f) / n;
  666. }
  667. s = std::sqrt( s );
  668.  
  669. if( s < exp )
  670. {
  671. break;
  672. }
  673. }
  674.  
  675. vs = 0;
  676. for( int j = 0; j <= n; j++ )
  677. {
  678. if( f[j] < f[vs] )
  679. {
  680. vs = j;
  681. }
  682. }
  683.  
  684. std::cout << "\nMin\n";
  685. for( int j = 0; j < n; j++ )
  686. {
  687. printf( "%c =\t%.9f\n", j == 0 ? 'x' : 'y', v[vs][j] );
  688. }
  689.  
  690. std::cout << "F(x, y) = " << std::fixed << func( v[vs].data() ) << '\n';
  691. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement