Найти - Пользователи
Полная версия: Произвольная функция для работы с ней.
Начало » Центр помощи » Произвольная функция для работы с ней.
1
Mechisla
Добрый день! Есть такая задача:
Необходимо написать код для вычисления минимума функции произвольной размерности. Вопрос заключается в том, как можно сделать так, чтобы программа работала в режиме black box, т.е. я ввожу функцию, а она мне точку минимума. Основная проблема, как сделать, чтобы достаточно было только ввести функцию. Пример ввода такой x1^2 + 2x1+ x2^3 + 5x2^2…
Потом, чтобы получить возможность числено производную брать и т.п..
У кого какие идеи есть?
Rodegast
Как-то так:
 def MIN(txt):
     foo = lambda x: eval(txt)
     return min( foo(x) for x in xrange(-200, 200) ) 
>>> MIN("x**2+x**3+5*x**2") 
-7760000
Mechisla
Rodegast
Как-то так:
Размерность функции любая, т.е. переменных в ней может быть и 3, и 10, и так далее.
f = f(x1, x2, x3…)
А нужна функция, так как необходимо реализовать метод Ньютона.

Может можно реализовать подобным образом
 function = str(input())
.
.
.
Я не знаю, как можно сделать так, чтобы создать функцию с переменным количеством аргументов, точнее знаю, что можно использовать **kwargs. Но не получится получить return ax1^t + bx2^3 ….
Может не знаю что-то. Еще опыта не так много.
JOHN_16
Mechisla
Этим хорошо занимается модуль simpy
scidam
Если это упражнение, то все-таки нужно конкретизировать возможный вид функции многих переменных. Если она полиномиального типа, как у вас указано в примере ввода, то здесь SimPy (как правильно указал John_16); С помощью этого пакета производную можно взять символьно, найти все критические точки и найти ту, в которой функция минимальна. Но это, если вид f простой, как вы указали, а то можно легко наткнуться на ситуации, когда df/dx_j = 0 не решатся символьно, да и численно могут быть проблемы.
Если это задача реальная, то можно посмотреть в сторону пакета SciPy раздел оптимизация, здесь есть много методов численного поиска локальных и глобальных минимумов…
Mechisla
scidam
Если это упражнение, то все-таки нужно конкретизировать возможный вид функции многих переменных. Если она полиномиального типа, как у вас указано в примере ввода, то здесь SimPy (как правильно указал John_16); С помощью этого пакета производную можно взять символьно, найти все критические точки и найти ту, в которой функция минимальна. Но это, если вид f простой, как вы указали, а то можно легко наткнуться на ситуации, когда df/dx_j = 0 не решатся символьно, да и численно могут быть проблемы.Если это задача реальная, то можно посмотреть в сторону пакета SciPy раздел оптимизация, здесь есть много методов численного поиска локальных и глобальных минимумов…


К сожалению подобные пакеты нельзя использовать в данной задаче. Нужно написать численный метод самому. Если бы можно было пользоваться такими модулями, тогда я бы не задал такой вопрос. А вопрос конкретный, можно ли как-то преобразовать введенную информацию типа string в функцию. Например приведу на скорую руку кусок кода, который планировал писать, ну или что-то подобное.
 import numpy as np
A = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '+', '-', '^']
func = str(input('function: '))
step = 0
key = []
step = 0 
for i in range(len(func)):
    if func[i] == 'x':
        step += 1
        key.append('x' + str(step+1))  
key = A + key
.
.
.

Но к сожалению не получается создать такую функцию:
 def example(x1, x2, x3, ...)

Если изначально не знаю сколько будет переменных, а возвращать она должна вот по такому принципу:
Если мы вводим, например: 'x1^2 + x2^3 + 15x3, тогда

  return x1**2 + x2**3 + 15*x3 

А дальше соответственно я бы мог делать все, что угодно, так как x1, x2, x3 это переменные
scidam
Для динамического создания функций попробуйте следующий варинат:
 import ast
def func(strf):
   root = ast.parse(strf)
   names = sorted({node.id for node in ast.walk(root) if isinstance(node, ast.Name)})
   kwargs = {k:0 for k in names}
   _d = {'kwargs': kwargs, '_s':strf}
   exec('''def newf(**kwargs): 
               for k in kwargs:
                   locals()[k]=kwargs[k]
               return eval(_s)''',_d)
   return _d['newf']
g=func('x1*2+x2+x1**7') 
print(g(x1=1,x2=4))

Не могу сказать, что самый оптимальный, возможно реализовать иначе можно. Можно использовать и регулярные выражения для выделения используемых переменных, если имена переменных и структура выражения “не очень сложные”.
Mechisla
scidam
Для динамического создания функций попробуйте следующий варинат:
Спасибо, это мне очень поможет.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB