You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matlab调用Python实现的PSO算法时矩阵传递报错问题排查

问题:Matlab调用Python实现的PSO算法报错

问题背景

我有一段Matlab代码,需要调用Python写的PSO算法,其中一个参数是10×5的矩阵。这个矩阵在Python里单独跑PSO完全正常,但Matlab调用时一直报错。

Matlab代码

s = size(CurrentPop, 1);
velocity_matrix = [];
NewPop = [];

for gen = 1:gen_max
    
    NewPop, velocity_matrix = py.pso_algorithm.pso(n_chr, n_par, CurrentPop, velocity_matrix, gen);
    CurrentPop = EvaluateFirestation(NewPop, n_par, fuelmodels);

报错信息

Error using pso_algorithm>pso (line 46)
Python Error: TypeError: slice indices must be integers or None or have an index method
Python function 'pso' might not be able to accept at least one input argument at position 3. The function may require a specific data type that you can construct from the MATLAB array. For more information, see the documentation for Python function 'pso' and working with Python arrays.

报错出在Python函数的particles = particles_array[:, :n_par]这一行。

Python PSO函数代码

def pso(population, n_par, current_pop, velocity_matrix, generation):
    # Initialization
    # Population
    particles_array = np.array(current_pop)
    particles = particles_array[:, :n_par]
    # Particle's best position
    pbest_position = particles
    # Fitness
    # ULTIMA COLUNA DE CURRENT_POP
    pbest_fitness = particles_array[:, n_par]
    # Index of the best particle
    gbest_index = np.argmin(pbest_fitness)  # VAI BUSCAR O INDICE DO MENOR VALOR EM PBEST_FITNESS
    # Global best particle position
    gbest_position = pbest_position[gbest_index]
    # Velocity (starting from 0 speed)
    if generation == 1:
        velocity = [[0.0 for j in range(n_par)] for i in range(population)]
    else:
        velocity = velocity_matrix

    for n in range(population):
        # Update the velocity of each particle
        velocity[n] = update_velocity(particles[n], velocity[n], pbest_position[n], gbest_position, n_par)
        # Move the particles to new position
        particles[n] = update_position(particles[n], velocity[n])

    particles = np.insert(particles, n_par, pbest_fitness, axis=1)
    velocity = np.array(velocity)
    # print(particles)
    # print(velocity)

    return particles, velocity

问题原因与解决方法

核心问题

Matlab往Python传数据时,默认不是NumPy数组类型,而是Matlab自己的数组对象。直接用np.array(current_pop)转换这种对象,可能导致数组无法正常切片;另外,n_par这类数值参数传过去可能是Matlab的数值对象,不是Python原生整数,也会触发切片报错。

具体解决步骤

  1. 把数值参数转成Python整数
    在Matlab里,先把n_chr、n_par、gen转成Python整数类型再传:

    py_n_chr = py.int(n_chr);
    py_n_par = py.int(n_par);
    
  2. 直接把Matlab数组转成NumPy数组
    传递CurrentPop之前,用py.numpy.array()转成Python能识别的NumPy数组:

    py_CurrentPop = py.numpy.array(CurrentPop);
    
  3. 处理初始空的velocity_matrix
    Matlab里初始的空数组[]传到Python后没法直接用,改成初始化为对应形状的零矩阵:

    velocity_matrix = py.numpy.zeros(py.tuple({s, n_par}));
    
  4. Python函数里加类型兼容处理(可选)
    在Python函数开头,强制把参数转成原生类型,避免类型不兼容:

    def pso(population, n_par, current_pop, velocity_matrix, generation):
        # 转成Python原生整数
        population = int(population)
        n_par = int(n_par)
        generation = int(generation)
        # 确保current_pop是NumPy数组
        if not isinstance(current_pop, np.ndarray):
            # 先转成列表再转NumPy数组
            particles_array = np.array(current_pop.tolist())
        else:
            particles_array = current_pop
        # 后面的代码不变
    

修改后的Matlab调用示例

s = size(CurrentPop, 1);
% 初始化velocity_matrix为NumPy零矩阵
velocity_matrix = py.numpy.zeros(py.tuple({s, n_par}));
NewPop = [];

% 转换数值参数为Python整数
py_n_chr = py.int(n_chr);
py_n_par = py.int(n_par);

for gen = 1:gen_max
    py_CurrentPop = py.numpy.array(CurrentPop);
    py_gen = py.int(gen);
    NewPop, velocity_matrix = py.pso_algorithm.pso(py_n_chr, py_n_par, py_CurrentPop, velocity_matrix, py_gen);
    CurrentPop = EvaluateFirestation(NewPop, n_par, fuelmodels);
end

内容的提问来源于stack exchange,提问作者João Sousa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 19:45:49