python - 寻找具有最大函数值的列表的最佳组合

标签 python scipy mathematical-optimization discrete-mathematics cvxopt

假设我有 N 个列表(向量)并且我想选择其中的 x 个 1<x<[N] (x 未预先确定) 所以我将获得 func(lists) 的最大值。

例如:

l1 = [3,4,7,-2]
l2 = [0.5,3,6,2.7]
l3 = [0,5,8,3.6]
mat = [l1, l2, l3]

result = maximize(func, mat)

def func(mat):
    # doing some math between lists. For Example:
    sum_list = list(mat[0])
    for li in mat[1:]:
        sum_list = map(operator.add, sum_list, li)
    accum_min_lst = []
    for i, val in enumerate(sum_list):
        x = sum_list[:i + 1]
        accum_min_lst.append(val - max(x))
    return min(accum_min_lst)

可能的结果:

[l1], [l2], [l3], [l1,l2], [l1,l3], [l2,l3], [l1,l2,l3]  

如果我编写一个简单的解决方案并运行所有组合,它将永远花费 2^N。

我正在尝试使用 cvxpy 找到解决方案或者也许 scipy.optimize.minimize 但我发现很难理解我需要使用哪种函数来解决我的问题,我想也许我应该尝试进化算法来找到一个近似的答案, 或者我应该使用 portfolio optimization相反。

最佳答案

我选择使用我自己的 Evolutionary algorithm 版本它对我来说更直观,而且你可以玩弄人口规模、世代和突变概率:

from random import choice, random

def stack_overflow_example(self):
    def fitness(trial):
        trial_max = self.func(trial, mat)
        if trial_max > self.best_res:
            self.best_res = trial_max
            return trial_max
        else:
            return -sys.maxint

    def mutate(parent):
        mutation = []
        for p in parent:
            if random() < prob:
                mutation.append(choice([0, 1]))
            else:
                mutation.append(p)
        return mutation

    l1 = [3, 4, 7, -2]
    l2 = [0.5, 3, 6, 2.7]
    l3 = [0, 5, 8, 3.6]
    mat = [l1, l2, l3]

    max_num_of_loops = 1000
    prob = 0.075  # mutation probability
    gen_size = 10  # number of children in each generation
    self.bin_parent = [1] * len(mat)  # first parent all ones
    self.best_res = self.func(self.bin_parent, mat)  # starting point for comparison
    for _ in xrange(max_num_of_loops):
        backup_parent = self.bin_parent
        copies = (mutate(self.bin_parent) for _ in xrange(gen_size))
        self.bin_parent = max(copies, key=fitness)
        res = self.func(self.bin_parent, mat)
        if res >= self.best_res:
            self.best_res = res
            print (">> " + str(res))
        else:
            self.bin_parent = backup_parent
    print("Final result: " + str(self.best_res))
    print("Chosen lists:")
    chosen_lists = self.choose_strategies(self.bin_parent, mat)
    for i, li in enumerate(chosen_lists):
        print(">> list[{}] : values: {}".format(i, li))

def func(self, bin_list, mat):
    chosen_mat = self.bin_list_to_mat(bin_list, mat)
    if len(chosen_mat) == 0:
        return -sys.maxint
    # doing some math between lists:
    sum_list = list(chosen_mat[0])
    for li in chosen_mat[1:]:
        sum_list = map(operator.add, sum_list, li)
    accum_min_lst = []
    for i, val in enumerate(sum_list):
        x = sum_list[:i + 1]
        accum_min_lst.append(val - max(x))
    return min(accum_min_lst)

@staticmethod
def bin_list_to_mat(bin_list, mat):
    chosen_lists = []
    for i, stg in enumerate(mat):
        if bin_list[i] == 1:
            chosen_lists.append(stg)
    return chosen_lists

希望它能对某人有所帮助 :) 因为我花了一段时间才找到这个解决方案。

关于python - 寻找具有最大函数值的列表的最佳组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35158666/

相关文章:

python - FFT 低通滤波器

python - 如何拟合数据集以便它们共享一些(但不是全部)参数值

wolfram-mathematica - Mathematica 优化模块的局限性

Java 库? - 单纯形/线性规划/优化

python - 使用 os.walk 迭代文件,但无法打开和打印文本文件

python - 将 math.erf 应用于数组

python - 在 python 上使用 Tkinter 上的 Entry 时如何禁用键盘输入?

python - 带有换行符的文本文件到数据框 pandas 中

python - 如何将样条曲线拟合转换为分段函数?

wolfram-mathematica - Mathematica 中的二次规划