Scipy优化最小化不可靠

时间:2018-02-20 09:08:12

标签: python optimization scipy mathematical-optimization

我的节目:

# -*- coding: utf-8 -*-

import numpy as np
import itertools
from scipy.optimize import minimize

global width
width = 0.3

def time_builder(f, t0=0, tf=300):
    return list(np.round(np.arange(t0, tf, 1/f*1000),3))

def duo_stim_overlap(t1, t2):
    """
    Function taking 2 timelines build by time_builder function in input
    and returning the ids of overlapping pulses between the 2.
    len(t1) < len(t2)
    """    
    pulse_id_t1 = [x for x in range(len(t1)) for y in range(len(t2)) if abs(t1[x] - t2[y]) < width]
    pulse_id_t2 = [x for x in range(len(t2)) for y in range(len(t1)) if abs(t2[x] - t1[y]) < width]

    return pulse_id_t1, pulse_id_t2

def optimal_delay(s):
    frequences = [20, 60, 80, 250, 500]
    t0 = 0
    tf = 150

    delay = 0                           # delay between signals, 
    timelines = list()
    overlap = dict()

    for i in range(len(frequences)):
        timelines.append(time_builder(frequences[i], t0+delay, tf))
        overlap[i] = list()
        delay += s

    for subset in itertools.combinations(timelines, 2):
        p1_stim, p2_stim = duo_stim_overlap(subset[0], subset[1])
        overlap[timelines.index(subset[0])] += p1_stim
        overlap[timelines.index(subset[1])] += p2_stim

    optim_param = 0
    for key, items in overlap.items():
        optim_param += (len(list(set(items)))/len(timelines[key]))

    return optim_param

res = minimize(optimal_delay, 1.5, method='Nelder-Mead', tol = 0.01, bounds = [(0, 5)], options={'disp': True})

所以我的目标是最小化函数optimal_delay计算的值optim_param。 首先,渐变方法不做任何事情。他们在第一次迭代时停止。 其次,我需要为最佳延迟的s值设置边界(例如在0和5之间)。我知道使用Nelder-Mead单纯形法不可能,但其他方法根本不起作用。 第三,我真的不知道如何设置终止参数tol。机器人tol = 0.01tol = 0.0000001没有给我带来好结果。 (并且非常接近)。 最后,如果我从1.8开始,最小化函数给了我一个远远不是最小值的值......

我做错了什么?

1 个答案:

答案 0 :(得分:4)

如果你绘制你的optimal_delay函数,你会发现它远离凸起。搜索只会找到靠近起点的任何本地最小值。enter image description here