混沌映射是非线性动力学中经常出现的一个重要概念,它是一种简单的模型,可以产生看起来随机的复杂性。常见的混沌映射有 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 仓库:
四、结束语
总结一下,我们在本文中深入阐述了 Logistic 混沌映射的本质、计算方式、应用场合等。Logistic 混沌映射为我们研究非线性动力学问题提供了简单粗暴的方法,例如模拟天气预报、地震预警等。\n我们在本文中提供了多个 Code 示例,可以直接运行并修改。