3D阵列最小化(优化)

发布于 2025-01-26 11:57:58 字数 1018 浏览 4 评论 0原文

假设我有以下5x5x5 3D数组,由二进制值组成:

space = [
[[0,1,0,0,1], [1,0,0,1,0], [0,1,0,1,1], [0,0,0,1,1], [0,1,1,0,1]],
[[1,1,1,0,1], [0,0,0,1,0], [0,0,1,1,1], [0,0,0,1,1], [0,1,0,0,0]],
[[0,1,0,1,0], [1,1,0,0,0], [1,0,0,1,0], [0,1,1,1,0], [0,1,1,1,1]],
[[0,1,0,1,0], [0,1,0,1,1], [1,1,0,1,0], [1,0,0,1,0], [0,0,0,0,0]],
[[1,0,0,1,1], [0,1,1,0,1], [0,1,0,1,1], [0,1,1,0,1], [1,0,1,0,0]],
]

和一个功能measure(space),该将此3D数组作为输入,并返回一个实际值。我的目标是找到最佳space配置,该配置返回最小MEATE()输出。

我如何使用 1d-array 作为输入(或您认为更适合此问题的任何其他功能/库)解决此优化问题?


编辑:要澄清,measure()函数将3D数组转换为CAD模型(其中1:solid; solid; 0 < /code>:void),然后将3D几何形状传递到电磁求解器(天线模拟器)中,以获取描述天线“效率”的结果(指标描述的效率越低,值越低,则越好天线的性能)。

Suppose I have the following 5x5x5 3D array, consisting of binary values:

space = [
[[0,1,0,0,1], [1,0,0,1,0], [0,1,0,1,1], [0,0,0,1,1], [0,1,1,0,1]],
[[1,1,1,0,1], [0,0,0,1,0], [0,0,1,1,1], [0,0,0,1,1], [0,1,0,0,0]],
[[0,1,0,1,0], [1,1,0,0,0], [1,0,0,1,0], [0,1,1,1,0], [0,1,1,1,1]],
[[0,1,0,1,0], [0,1,0,1,1], [1,1,0,1,0], [1,0,0,1,0], [0,0,0,0,0]],
[[1,0,0,1,1], [0,1,1,0,1], [0,1,0,1,1], [0,1,1,0,1], [1,0,1,0,0]],
]

and a function measure(space) which takes this 3D array as the input, and returns a real value. My goal is to find the best space configuration that returns the minimum measure() output.

How may I use scipy.optimize.minimize which takes a 1D-array as input (or any other function/library you might think is more appropriate for this problem) to solve this optimization problem?


EDIT: To clarify, the measure() function converts the 3D array into a CAD model (where 1: solid; 0: void), and passes the 3D geometry into an electromagnetic solver (antenna simulator) to get a result describing the "efficiency" of the antenna (sort of what the metric describes, except the lower the value is, the better the performance of the antenna).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不知所踪 2025-02-02 11:57:58

不要使用一维优化功能,至少有三种(肯定更多)可以采用:

  • 蛮力,在您的情况下,它将尝试2 ** 125,这似乎有点太多。

  • 使用Montecarlo,即生成随机
    解决方案,直到找到最好的或至少一个足够好的解决方案

  • 使用遗传算法足够好的

    的解决方案,这可能是您可以获得的最好的
    对于这个问题。您可以使用 pygad
    如果不是最好的话,请花很多时间获得一个好的解决方案。

在这里,我举了一个示例,您只需要指定fitness_function,在这种情况下,它可能会找到最佳解决方案。

import pygad
import numpy as np

space = [
[[0,1,0,0,1], [1,0,0,1,0], [0,1,0,1,1], [0,0,0,1,1], [0,1,1,0,1]],
[[1,1,1,0,1], [0,0,0,1,0], [0,0,1,1,1], [0,0,0,1,1], [0,1,0,0,0]],
[[0,1,0,1,0], [1,1,0,0,0], [1,0,0,1,0], [0,1,1,1,0], [0,1,1,1,1]],
[[0,1,0,1,0], [0,1,0,1,1], [1,1,0,1,0], [1,0,0,1,0], [0,0,0,0,0]],
[[1,0,0,1,1], [0,1,1,0,1], [0,1,0,1,1], [0,1,1,0,1], [1,0,1,0,0]],
]
space = np.array(space)

# I create a reference binary matrix to create a objective solution
i = np.identity(5)
ref = np.dstack([i]*5)

# flat your array to do it gen-like
space= space.flatten()
ref = ref.flatten()

def fitness_func(solution, solution_idx):
    # write here your fitness function, in my case i just compare how different two matrix are.
    fitness = np.sum(ref == solution)
    return fitness
    
fitness_function = fitness_func

num_generations = 400
num_parents_mating = 10

sol_per_pop = 14
num_genes = len(space)
init_range_low = 0
init_range_high = 1
gene_space=[0,1] # only binary solutions
parent_selection_type = "sss"
keep_parents = 8

crossover_type = "single_point" #"scattered" #
mutation_type = "random"
mutation_percent_genes = 1

ga_instance = pygad.GA(num_generations=num_generations,
                       num_parents_mating=num_parents_mating,
                       fitness_func=fitness_function,
                       sol_per_pop=sol_per_pop,
                       num_genes=num_genes,
                       init_range_low=init_range_low,
                       init_range_high=init_range_high,
                       gene_space=gene_space,
                       parent_selection_type=parent_selection_type,
                       keep_parents=keep_parents,
                       crossover_type=crossover_type,
                       mutation_type=mutation_type,
                       mutation_percent_genes=mutation_percent_genes)
                       
ga_instance.run()

solution, solution_fitness, solution_idx = ga_instance.best_solution()
print(f"Parameters of the best solution : {solution}")
print(f"Fitness value of the best solution = {solution_fitness}")

# reshape the solution 
solution = solution.reshape([5,5,5])
print(solution)

通常,不知道如何“测量”保证最佳解决方案的唯一方法是蛮力。如果您知道“测量”的外观,则使用“数学”可能是第四种方法。但是在大多数情况下,遗传算法是针对此优化问题的足够解决方案。

Don't use a 1d optimization function, there are at least three (surely more) approaches you can take:

  • Brute force, in your case that would be trying 2**125, which seems a bit too much.

  • Using MonteCarlo, i.e generating random
    solutions till finding the best, or at least one that is good enough

  • Using genetic algorithms, which will be probably the best you can get
    for this problem. You can use PyGAD for instance, and it won't
    take much time to get a good solution if not the best.

Here I put an example working where you only need to specify your fitness_function, in this case it will likely find the best solution.

import pygad
import numpy as np

space = [
[[0,1,0,0,1], [1,0,0,1,0], [0,1,0,1,1], [0,0,0,1,1], [0,1,1,0,1]],
[[1,1,1,0,1], [0,0,0,1,0], [0,0,1,1,1], [0,0,0,1,1], [0,1,0,0,0]],
[[0,1,0,1,0], [1,1,0,0,0], [1,0,0,1,0], [0,1,1,1,0], [0,1,1,1,1]],
[[0,1,0,1,0], [0,1,0,1,1], [1,1,0,1,0], [1,0,0,1,0], [0,0,0,0,0]],
[[1,0,0,1,1], [0,1,1,0,1], [0,1,0,1,1], [0,1,1,0,1], [1,0,1,0,0]],
]
space = np.array(space)

# I create a reference binary matrix to create a objective solution
i = np.identity(5)
ref = np.dstack([i]*5)

# flat your array to do it gen-like
space= space.flatten()
ref = ref.flatten()

def fitness_func(solution, solution_idx):
    # write here your fitness function, in my case i just compare how different two matrix are.
    fitness = np.sum(ref == solution)
    return fitness
    
fitness_function = fitness_func

num_generations = 400
num_parents_mating = 10

sol_per_pop = 14
num_genes = len(space)
init_range_low = 0
init_range_high = 1
gene_space=[0,1] # only binary solutions
parent_selection_type = "sss"
keep_parents = 8

crossover_type = "single_point" #"scattered" #
mutation_type = "random"
mutation_percent_genes = 1

ga_instance = pygad.GA(num_generations=num_generations,
                       num_parents_mating=num_parents_mating,
                       fitness_func=fitness_function,
                       sol_per_pop=sol_per_pop,
                       num_genes=num_genes,
                       init_range_low=init_range_low,
                       init_range_high=init_range_high,
                       gene_space=gene_space,
                       parent_selection_type=parent_selection_type,
                       keep_parents=keep_parents,
                       crossover_type=crossover_type,
                       mutation_type=mutation_type,
                       mutation_percent_genes=mutation_percent_genes)
                       
ga_instance.run()

solution, solution_fitness, solution_idx = ga_instance.best_solution()
print(f"Parameters of the best solution : {solution}")
print(f"Fitness value of the best solution = {solution_fitness}")

# reshape the solution 
solution = solution.reshape([5,5,5])
print(solution)

In general without knowing how "measure" the only approach that guarantee the best solution is brute force. If you know how "measure" looks like, using "maths" could be a fourth approach. But for most cases the genetic algorithm is a good enough solution for this optimization problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文