嚼的自己很帅 发表于 2022-10-8 16:06:17

怎么在python中表示分段函数?

RT,用if表示再加上条件约束报错了TT

嚼的自己很帅 发表于 2022-10-8 16:14:26

{:10_269:}

wp231957 发表于 2022-10-8 16:21:45

嚼的自己很帅 发表于 2022-10-8 16:14


放文本代码

嚼的自己很帅 发表于 2022-10-8 16:24:12

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

DNA_SIZE = 24
POP_SIZE = 200
CROSSOVER_RATE = 0.8
MUTATION_RATE = 0.005
N_GENERATIONS = 50
X_BOUND = [-3, 3]
Y_BOUND = [-3, 3]


def F(x, y):
    if (-3 < x.all() < -2.5 and -3 < y.all() < -2.5) or (2.5 < x.all() < 3 and 2.5 < y.all() < 3):
      return np.sin((2 * np.pi * x) / 3) ** 2 * np.sin((2 * np.pi * y) / 3) ** 2 * np.exp((x + y) / (5 * np.pi))
    else:
      return -(np.sin((2 * np.pi * x) / 3) ** 2 * np.sin((2 * np.pi * y) / 3) ** 2 * np.exp((x + y) / (5 * np.pi)))


def plot_3d(ax):
    X = np.linspace(*X_BOUND, 100)
    Y = np.linspace(*Y_BOUND, 100)
    X, Y = np.meshgrid(X, Y)
    Z = F(X, Y)
    ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm)
    ax.set_zlim(-1, 1)
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('z')
    plt.pause(3)
    plt.show()


def get_fitness(pop):
    x, y = translateDNA(pop)
    pred = F(x, y)
    return (pred - np.min(
      pred)) + 1e-3# 减去最小的适应度是为了防止适应度出现负数,通过这一步fitness的范围为,最后在加上一个很小的数防止出现为0的适应度


def translateDNA(pop):# pop表示种群矩阵,一行表示一个二进制编码表示的DNA,矩阵的行数为种群数目
    x_pop = pop[:, 1::2]# 奇数列表示X
    y_pop = pop[:, ::2]# 偶数列表示y

    # pop:(POP_SIZE,DNA_SIZE)*(DNA_SIZE,1) --> (POP_SIZE,1)
    x = x_pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2 ** DNA_SIZE - 1) * (X_BOUND - X_BOUND) + X_BOUND
    y = y_pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2 ** DNA_SIZE - 1) * (Y_BOUND - Y_BOUND) + Y_BOUND
    return x, y


def crossover_and_mutation(pop, CROSSOVER_RATE=0.8):
    new_pop = []
    for father in pop:# 遍历种群中的每一个个体,将该个体作为父亲
      child = father# 孩子先得到父亲的全部基因(这里我把一串二进制串的那些0,1称为基因)
      if np.random.rand() < CROSSOVER_RATE:# 产生子代时不是必然发生交叉,而是以一定的概率发生交叉
            mother = pop# 再种群中选择另一个个体,并将该个体作为母亲
            cross_points = np.random.randint(low=0, high=DNA_SIZE * 2)# 随机产生交叉的点
            child = mother# 孩子得到位于交叉点后的母亲的基因
      mutation(child)# 每个后代有一定的机率发生变异
      new_pop.append(child)

    return new_pop


def mutation(child, MUTATION_RATE=0.003):
    if np.random.rand() < MUTATION_RATE:# 以MUTATION_RATE的概率进行变异
      mutate_point = np.random.randint(0, DNA_SIZE * 2)# 随机产生一个实数,代表要变异基因的位置
      child = child ^ 1# 将变异点的二进制为反转


def select(pop, fitness):# nature selection wrt pop's fitness
    idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,
                           p=(fitness) / (fitness.sum()))
    return pop


def print_info(pop):
    fitness = get_fitness(pop)
    max_fitness_index = np.argmax(fitness)
    print("max_fitness:", fitness)
    x, y = translateDNA(pop)
    print("最优的基因型:", pop)
    print("(x, y):", (x, y))


if __name__ == "__main__":
    fig = plt.figure()
    ax = Axes3D(fig)
    plt.ion()# 将画图模式改为交互模式,程序遇到plt.show不会暂停,而是继续执行
    plot_3d(ax)

    pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE * 2))# matrix (POP_SIZE, DNA_SIZE)
    for _ in range(N_GENERATIONS):# 迭代N代
      x, y = translateDNA(pop)
      if 'sca' in locals():
            sca.remove()
      sca = ax.scatter(x, y, F(x, y), c='black', marker='o');
      plt.show();
      plt.pause(0.1)
      pop = np.array(crossover_and_mutation(pop, CROSSOVER_RATE))
      # F_values = F(translateDNA(pop), translateDNA(pop))#x, y --> Z matrix
      fitness = get_fitness(pop)
      pop = select(pop, fitness)# 选择生成新的种群

    print_info(pop)
    plt.ioff()
    plot_3d(ax)

嚼的自己很帅 发表于 2022-10-8 16:25:03

wp231957 发表于 2022-10-8 16:21
放文本代码

放了。报错问题解决了,但是没有分段
页: [1]
查看完整版本: 怎么在python中表示分段函数?