用于重排二维数组使相邻元素值相似的Python实现算法求荐
二维数组结构化重排(聚类分布)的Python解决方案
核心算法选型
针对保留原数组值分布、让相邻元素值相近的需求,以下三种算法最实用:
- 排序后分块填充:最简单易实现,适合快速生成结构化分布;
- 模拟退火算法:通过迭代优化生成自然聚类,精度更高;
- 力导向布局:将元素视为带引力的粒子,相似值相互吸引,适合精细控制的场景。
实现示例
1. 排序分块法(快速版)
先对数组元素排序,再按蛇形填充减少行间差异,代码简洁高效:
import numpy as np def structured_rearrange_simple(arr): # 扁平化并排序数组 sorted_vals = np.sort(arr.flatten()) # 恢复原形状 reshaped = sorted_vals.reshape(arr.shape) # 蛇形反转偶数行,降低相邻行的元素差值 for i in range(1, arr.shape[0], 2): reshaped[i] = reshaped[i][::-1] return reshaped # 测试用例 random_arr = np.random.rand(5, 5) structured_arr = structured_rearrange_simple(random_arr) print("原数组:\n", random_arr) print("\n结构化数组:\n", structured_arr)
2. 模拟退火算法(高精度版)
通过随机交换元素并评估相邻相似度,逐步优化到聚类状态,结果更自然:
import numpy as np import random def calculate_cost(arr): # 计算相邻元素总差值(上下左右邻居) cost = 0 rows, cols = arr.shape for i in range(rows): for j in range(cols): current = arr[i, j] # 累加与上下左右邻居的差值绝对值 if i > 0: cost += abs(current - arr[i-1, j]) if i < rows - 1: cost += abs(current - arr[i+1, j]) if j > 0: cost += abs(current - arr[i, j-1]) if j < cols - 1: cost += abs(current - arr[i, j+1]) return cost def simulated_annealing_rearrange(arr, max_iter=10000, initial_temp=100, cooling_rate=0.999): current_arr = arr.copy() current_cost = calculate_cost(current_arr) rows, cols = arr.shape temp = initial_temp for _ in range(max_iter): # 随机选两个位置交换 i1, j1 = random.randint(0, rows-1), random.randint(0, cols-1) i2, j2 = random.randint(0, rows-1), random.randint(0, cols-1) current_arr[i1,j1], current_arr[i2,j2] = current_arr[i2,j2], current_arr[i1,j1] new_cost = calculate_cost(current_arr) # 判断是否接受当前交换 if new_cost < current_cost: current_cost = new_cost else: # 按概率接受较差解,温度越低概率越小 accept_prob = np.exp((current_cost - new_cost) / temp) if random.random() > accept_prob: # 撤销交换 current_arr[i1,j1], current_arr[i2,j2] = current_arr[i2,j2], current_arr[i1,j1] temp *= cooling_rate if temp < 1e-5: break return current_arr # 测试用例 random_arr = np.random.rand(5, 5) sa_arr = simulated_annealing_rearrange(random_arr) print("原数组:\n", random_arr) print("\n模拟退火结构化数组:\n", sa_arr)
算法选择建议
- 若追求快速实现,优先用排序分块法;
- 若需要更自然的聚类效果,选择模拟退火算法,可通过调整
max_iter、initial_temp参数平衡速度与精度; - 力导向布局可基于节点间相似度构建引力网络,实现更灵活的聚类,但编码复杂度较高,适合有进阶需求的场景。
内容的提问来源于stack exchange,提问作者bajotupie
相关产品推荐
相关产品推荐

