您的位置:

深入浅出logistic混沌映射

混沌映射是非线性动力学中经常出现的一个重要概念,它是一种简单的模型,可以产生看起来随机的复杂性。常见的混沌映射有 Logistic 映射、Henon 映射、Ikeda 映射等等。本文将深入浅出地介绍 Logistic 混沌映射及它的一些应用。我们首先从 Logistic 函数的定义开始。

一、Logistic 函数

Logistic 函数的定义如下:

def logistic(r, x):
    return r*x*(1-x)

其中,r 为参数,用于控制复杂度,常常取值在 3.6 到 4.0 之间。x 为输入,取值范围为 [0,1]。该函数将一个输入值映射为 [0,1] 之间的新值。

下面是一个 Logistic 函数输出-输入的图像,它展示了 Logistic 函数的性质:

import matplotlib.pyplot as plt 

def show_logistic():
    r = 3.8
    x = [0.5]
    for i in range(200):
        x.append(logistic(r, x[-1]))
    fig, ax = plt.subplots()
    ax.plot(x, 'b-', label='logistic map') 
    ax.plot([0, 200], [0.5, 0.5], 'r--', label='y=0.5')
    ax.legend()
    ax.set_xlabel('time')
    ax.set_ylabel('Xt')
    plt.show()

show_logistic()

二、Logistic 映射及混沌性质

Logistic 函数可以进一步用来定义 Logistic 映射,即:使用一个初始值,通过反复使用 Logistic 函数,得到一个序列,称之为 Logistic 映射序列。

def logistic_map(r, x0, n):
    result = []
    xt = x0
    for i in range(n):
        result.append(xt)
        xt = logistic(r, xt)
    return result

下面是 Logistic 映射在不同参数下的输出结果:

def show_logistic_map():
    fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(10, 6))
    x0 = 0.2
    n = 1000
    r_values = [2.4, 2.8, 3.2, 3.6, 3.8, 4.0]
    for r, ax in zip(r_values, axes.flatten()):
        ax.plot(logistic_map(r, x0, n), 'b.', markersize=1)
        ax.set_title(f"r = {r}")
    plt.tight_layout()
    plt.show()

show_logistic_map()

可以看到,当 r 取不同的值时,序列会展现出不同的路径,部分路径会变得非常复杂。

Logistic 映射的混沌性质,体现在它的输出序列的初值敏感性上。即,微小的初始变化,可能会导致序列朝着完全不同的方向发展。例如,下面是两个 Logistic 映射序列在初始值上仅相差 0.0001 的情况下的对比:

r = 3.9 
x0_1 = 0.6
x0_2 = 0.6001

plt.plot(logistic_map(r, x0_1, 500), 'b-', label=f'x0 = {x0_1}')
plt.plot(logistic_map(r, x0_2, 500), 'r-', label=f'x0 = {x0_2}')
plt.legend()
plt.show()

这说明 Logistic 映射序列对于初始值的依赖性越来越大,进而画出的图像变得乱糟糟的。

三、应用

1. 图像加密

Logistic 映射可以广泛应用于图像加密。基本思路是,将图像像素的灰度值作为输入初始值,产生 Logistic 映射序列,然后将序列的值乘以 255 得到一组新的灰度值,至此完成加密。解密时,将新的灰度值输入到 Logistic 映射中,得到的序列再次乘以 255 就可以得到原始的灰度值。

def logistic_encryption(image, r, x0):
    rows, cols = image.shape
    data_len = rows*cols
    logistic_seq = np.array(logistic_map(r, x0, data_len))
    encryption_data = (logistic_seq * 255).reshape(rows, cols)
    encrypted_image = image ^ encryption_data.astype(np.uint8)
    return encrypted_image

def logistic_decryption(encrypted_image, r, x0):
    rows, cols = encrypted_image.shape
    data_len = rows*cols
    logistic_seq = np.array(logistic_map(r, x0, data_len))
    encryption_data = (logistic_seq * 255).reshape(rows, cols)
    decrypted_image = encrypted_image ^ encryption_data.astype(np.uint8)
    return decrypted_image

2. 人工神经元

Logistic 映射可以用于神经元,它的特点是可以在 0 和 1 之间缓慢地变化,并以某个 r 值为中心,单调减小或增加。

神经元的核心公式就是 Logistic 映射:

def logistic_neuron(w, x, theta):
    return logistic(np.dot(w, x)-theta, 1)

w = np.array([1, -2])
x = np.array([1, 0.5])
theta = 0

logistic_neuron(w, x, theta)

其中,w 和 x 是权重和输入的向量,theta 是阈值。实现代码参考下面的 Github 仓库:

https://github.com/morvanzhou/neural-networks-and-deep-learning/blob/master/contents/section2/demo/script.py

四、结束语

总结一下,我们在本文中深入阐述了 Logistic 混沌映射的本质、计算方式、应用场合等。Logistic 混沌映射为我们研究非线性动力学问题提供了简单粗暴的方法,例如模拟天气预报、地震预警等。\n我们在本文中提供了多个 Code 示例,可以直接运行并修改。