Skip to content

Instantly share code, notes, and snippets.

@montreal91
Last active October 11, 2015 06:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save montreal91/cdfe8d6c8177394144ba to your computer and use it in GitHub Desktop.
Save montreal91/cdfe8d6c8177394144ba to your computer and use it in GitHub Desktop.
values
def GetLuckyTriple( self ):
"""
Метод, который ищет отрезок, содержащий минимум функции.
"""
start = -1
end = self._accuracy * 2 - 1
for i in range( 10000 ):
middle = ( start + end ) / 2
if self._IsTripleLucky( start, end, middle ):
return start, middle, end
length = end - start
start = end
end = start + length * 2
start = 1
end = -self._accuracy * 2 + 1
for i in range( 10000 ):
middle = ( start + end ) / 2
if self._IsTripleLucky( start, end, middle ):
return start, end, middle
length = start - end
start = end
end = start - length * 2
return None
class RMinimumSeeker( object ):
"""
Класс, реализующий функции для поиска минимума на отрезке,
и поиска отрезка, содержащего минимум функции."""
def __init__( self, callback, accuracy=0.01 ):
"""
Конструктор класса, входными аргументами которого являются
функция и точность, с которой вычисляется минимум.
Значение точности по умолчанию 0.01
"""
super( RMinimumSeeker, self ).__init__()
self._callback = callback
self._accuracy = accuracy
def _IsTripleLucky( self, start, end, middle ):
"""
Вспомогательный метод, определяющая, является ли тройка значений счастливой.
"""
start_value = self._callback( start )
end_value = self._callback( end )
middle_value = self._callback( middle )
return middle_value < start_value and middle_value < end_value
def GetLuckyTriple( self ):
"""
Метод, который ищет отрезок, содержащий минимум функции.
"""
#! Оставь пока пустым
middle = -125000
for i in range( 1000 ):
start = middle
end = start + i
middle = ( start + end ) / 2
if self._IsTripleLucky( start, end, middle ):
return start, middle, end
return None
def GetLocalMinimum( self, start, end ):
"""
Метод, который ищет минимальное значение функции методом дихотомии.
"""
while True:
middle = ( start + end ) / 2 # c -- середина отрезка
epsilon = self._accuracy / 2
left = middle - epsilon # yk
right = middle + epsilon # zk
call_left = self._callback( left ) # f( yk )
call_right = self._callback( right ) # f( zk )
print(
"{0:.4f} {1:.4f} {2:.4f} {3:.4f} {4:.4f} {5:.4f}".format(
start,
end,
left,
right,
call_left,
call_right
)
)
if call_left >= call_right:
start = left
elif call_left < call_right:
end = right
if abs( start - end ) < self._accuracy:
print( "\t{0:.4f}\n".format( ( start + end ) / 2 ) )
return
def GetMinimum( self ):
"""
Метод, который ищет минимум функции на всей числовой прямой в два этапа:
На первом этапе производится поиск отрезка, содержащего минимум функции;
На втором этапе производится поиск минимума на отрезке.
"""
lucky_triple = self._GetLuckyTriple()
if lucky_triple is not None:
return self.GetLocalMinimum( lucky_triple[ 0 ], lucky_triple[ -1 ] )
else:
return None
def TestFunction1( arg ):
"""
Тестовая функция, принимающее минимальное значение при arg=2
"""
return ( arg - 2 ) ** 2
def TestFunction2( arg ):
"""
Тестовая функция, принимающее минимальное значение при arg=3
"""
return abs( arg - 3 )
def TestFunction3( arg ):
"""
Тестовая функция, принимающее минимальное значение при arg=2 и терпящая в этой точке разрыв
"""
if arg <=2:
return -arg
else:
return arg
def TestFunction4( arg ):
"""
Тестовая функция, принимающее минимальное значение при arg=3 и терпящая разрыв при arg=1
"""
if arg <= 1:
return 0
elif 1 < arg < 3:
return -arg
else:
return arg - 6
def TestFunction5( arg ):
"""
Тестовая функция, имеющая два локальных минимума при arg=1 и arg=3
"""
if arg <= 1:
return 1 - arg
elif 1 < arg < 3:
return 1 - ( arg - 2 ) ** 2
else:
return arg - 3
# Вычсление тестовых значений
if __name__ == '__main__':
ms1 = RMinimumSeeker( TestFunction1, accuracy=0.02 )
ms1.GetLocalMinimum( 1, 3 )
ms2 = RMinimumSeeker( TestFunction2, accuracy=0.02 )
ms2.GetLocalMinimum( 1, 3 )
ms3 = RMinimumSeeker( TestFunction3, accuracy=0.02 )
ms3.GetLocalMinimum( 1, 3 )
ms4 = RMinimumSeeker( TestFunction4, accuracy=0.02 )
ms4.GetLocalMinimum( 1, 3 )
ms5 = RMinimumSeeker( TestFunction5, accuracy=0.02 )
ms5.GetLocalMinimum( 1, 3 )
c - середина
a, b, c-epsilon, c+epsilon,
1.0000 3.0000 1.9950 2.0050 0.0000 0.0000
1.9950 3.0000 2.4925 2.5025 0.2426 0.2525
1.9950 2.5025 2.2438 2.2538 0.0594 0.0644
1.9950 2.2538 2.1194 2.1294 0.0143 0.0167
1.9950 2.1294 2.0572 2.0672 0.0033 0.0045
1.9950 2.0672 2.0261 2.0361 0.0007 0.0013
1.9950 2.0361 2.0105 2.0205 0.0001 0.0004
1.9950 2.0205 2.0028 2.0128 0.0000 0.0002
2.0039
1.0000 3.0000 1.9950 2.0050 1.0050 0.9950
1.9950 3.0000 2.4925 2.5025 0.5075 0.4975
2.4925 3.0000 2.7412 2.7512 0.2588 0.2488
2.7412 3.0000 2.8656 2.8756 0.1344 0.1244
2.8656 3.0000 2.9278 2.9378 0.0722 0.0622
2.9278 3.0000 2.9589 2.9689 0.0411 0.0311
2.9589 3.0000 2.9745 2.9845 0.0255 0.0155
2.9745 3.0000 2.9822 2.9922 0.0178 0.0078
2.9911
1.0000 3.0000 1.9950 2.0050 -1.9950 2.0050
1.0000 2.0050 1.4975 1.5075 -1.4975 -1.5075
1.4975 2.0050 1.7463 1.7562 -1.7463 -1.7562
1.7463 2.0050 1.8706 1.8806 -1.8706 -1.8806
1.8706 2.0050 1.9328 1.9428 -1.9328 -1.9428
1.9328 2.0050 1.9639 1.9739 -1.9639 -1.9739
1.9639 2.0050 1.9795 1.9895 -1.9795 -1.9895
1.9795 2.0050 1.9872 1.9972 -1.9872 -1.9972
1.9961
1.0000 3.0000 1.9950 2.0050 -1.9950 -2.0050
1.9950 3.0000 2.4925 2.5025 -2.4925 -2.5025
2.4925 3.0000 2.7412 2.7512 -2.7412 -2.7512
2.7412 3.0000 2.8656 2.8756 -2.8656 -2.8756
2.8656 3.0000 2.9278 2.9378 -2.9278 -2.9378
2.9278 3.0000 2.9589 2.9689 -2.9589 -2.9689
2.9589 3.0000 2.9745 2.9845 -2.9745 -2.9845
2.9745 3.0000 2.9822 2.9922 -2.9822 -2.9922
2.9911
1.0000 3.0000 1.9950 2.0050 1.0000 1.0000
1.9950 3.0000 2.4925 2.5025 0.7574 0.7475
2.4925 3.0000 2.7412 2.7512 0.4505 0.4356
2.7412 3.0000 2.8656 2.8756 0.2507 0.2333
2.8656 3.0000 2.9278 2.9378 0.1392 0.1205
2.9278 3.0000 2.9589 2.9689 0.0805 0.0612
2.9589 3.0000 2.9745 2.9845 0.0504 0.0309
2.9745 3.0000 2.9822 2.9922 0.0352 0.0155
2.9911
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment