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

路径转角正态分布概率重叠求解:如何实现路径中心概率均匀且边缘低?

路径概率密度函数转角概率重叠问题

我正在实现路径中心分配高概率、边缘分配低概率的功能,当前使用如下代码基于正态分布计算路径概率密度函数(PDF):

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

gridPath = "resources/myGrid3/"
pathFile = "pathNorm.csv"
myFile = "myPath8.csv"

pathDf = pd.read_csv(gridPath + pathFile)
myDf = pd.read_csv(gridPath + myFile)

pathDf = pathDf.drop_duplicates(["x"])

maxXGrid = pathDf.x.max() + 2
maxYGrid = pathDf.y.max() + 2
minXGrid = pathDf.x.min() - 2
minYGrid = pathDf.y.min() - 2

dx1 = 0.1
dx2 = 0.1

x1 = np.arange(minXGrid, maxXGrid, dx1)
x2 = np.arange(minYGrid, maxYGrid, dx2)
X1, X2 = np.meshgrid(x1, x2)
X = np.column_stack((X1.flatten(), X2.flatten()))

sigma_p = 0.7

path_pdf = np.sum((1 / (np.sqrt(2 * np.pi) * sigma_p)) * np.exp(-0.5 * (1 / (sigma_p ** 2)) * (np.sqrt((X1[:, :, None] - pathDf.x.values) ** 2 + (X2[:, :, None] - pathDf.y.values) ** 2)) ** 2), axis=2)
path_pdf /= np.sum(path_pdf)  # Normalize the pdf

fig = plt.figure(3)
ax = fig.add_subplot(111)
f = ax.pcolor(X1, X2, path_pdf)
plt.colorbar(f, ax=ax)
ax.scatter(myDf.x, myDf.y, color='white', label="Path", marker="x", s=0.1)
ax.set_xlabel('$x$-axis (m)', fontsize=12)
ax.set_ylabel('$y$-axis (m)', fontsize=12)
ax.scatter(pathDf.x.iloc[0], pathDf.y.iloc[0], c='b', marker='o', label='Start')
ax.set_aspect('equal')
ax.set_title('PDF of Path')
ax.legend()

plt.show()

当前结果中,转角处因路径点密集导致概率值叠加过高,我希望路径上所有点的概率值一致,请问有没有办法避免转角处的概率重叠?


解决方案

方法1:基于路径距离场生成PDF(最直接有效)

放弃逐个路径点叠加正态分布的方式,改为计算每个网格点到整条路径的最短距离,再将距离转换为概率。这样不管路径点密度如何,概率只和到路径的距离相关,自然避免转角处的叠加问题。

修改后的核心代码如下:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

gridPath = "resources/myGrid3/"
pathFile = "pathNorm.csv"
myFile = "myPath8.csv"

pathDf = pd.read_csv(gridPath + pathFile)
myDf = pd.read_csv(gridPath + myFile)

pathDf = pathDf.drop_duplicates(["x"])
path_points = pathDf[['x', 'y']].values

maxXGrid = pathDf.x.max() + 2
maxYGrid = pathDf.y.max() + 2
minXGrid = pathDf.x.min() - 2
minYGrid = pathDf.y.min() - 2

dx1 = 0.1
dx2 = 0.1

x1 = np.arange(minXGrid, maxXGrid, dx1)
x2 = np.arange(minYGrid, maxYGrid, dx2)
X1, X2 = np.meshgrid(x1, x2)
grid_points = np.column_stack((X1.flatten(), X2.flatten()))

sigma_p = 0.7

# 计算每个网格点到路径的最短距离
def distance_to_path(grid_points, path_points):
    dists = []
    for i in range(len(path_points)-1):
        p1 = path_points[i]
        p2 = path_points[i+1]
        vec = p2 - p1
        len_sq = np.dot(vec, vec)
        if len_sq == 0:
            dist = np.linalg.norm(grid_points - p1, axis=1)
        else:
            t = np.clip(np.dot(grid_points - p1, vec) / len_sq, 0, 1)
            proj = p1 + t[:, np.newaxis] * vec
            dist = np.linalg.norm(grid_points - proj, axis=1)
        dists.append(dist)
    return np.min(np.array(dists), axis=0)

min_dists = distance_to_path(grid_points, path_points)
min_dists = min_dists.reshape(X1.shape)

# 转换为概率密度函数
path_pdf = (1 / (np.sqrt(2 * np.pi) * sigma_p)) * np.exp(-0.5 * (min_dists / sigma_p) ** 2)
path_pdf /= np.sum(path_pdf)  # 归一化

# 绘图部分和原代码一致
fig = plt.figure(3)
ax = fig.add_subplot(111)
f = ax.pcolor(X1, X2, path_pdf)
plt.colorbar(f, ax=ax)
ax.scatter(myDf.x, myDf.y, color='white', label="Path", marker="x", s=0.1)
ax.set_xlabel('$x$-axis (m)', fontsize=12)
ax.set_ylabel('$y$-axis (m)', fontsize=12)
ax.scatter(pathDf.x.iloc[0], pathDf.y.iloc[0], c='b', marker='o', label='Start')
ax.set_aspect('equal')
ax.set_title('PDF of Path (Distance Field Based)')
ax.legend()

plt.show()

方法2:对路径点进行弧长均匀采样

如果坚持用点叠加的方式,可以先对原始路径按弧长重新采样,让每个采样点之间的弧长一致,避免转角处点过于密集。

核心代码示例:

# 计算路径累计弧长
path_points = pathDf[['x', 'y']].values
diffs = np.diff(path_points, axis=0)
seg_lengths = np.linalg.norm(diffs, axis=1)
cum_lengths = np.concatenate([[0], np.cumsum(seg_lengths)])
total_length = cum_lengths[-1]

# 按固定间隔采样(比如每0.5米一个点)
sample_interval = 0.5
sample_lengths = np.arange(0, total_length, sample_interval)
sampled_points = []

for l in sample_lengths:
    seg_idx = np.searchsorted(cum_lengths, l) - 1
    if seg_idx >= len(seg_lengths):
        sampled_points.append(path_points[-1])
        continue
    seg_start = cum_lengths[seg_idx]
    seg_rel_pos = (l - seg_start) / seg_lengths[seg_idx]
    sampled_point = path_points[seg_idx] + seg_rel_pos * diffs[seg_idx]
    sampled_points.append(sampled_point)

sampled_points = np.array(sampled_points)

# 后续用采样点计算叠加PDF
path_pdf = np.sum((1 / (np.sqrt(2 * np.pi) * sigma_p)) * np.exp(-0.5 * (1 / (sigma_p ** 2)) * (np.sqrt((X1[:, :, None] - sampled_points[:,0]) ** 2 + (X2[:, :, None] - sampled_points[:,1]) ** 2)) ** 2), axis=2)
path_pdf /= np.sum(path_pdf)

方法3:路径点权重归一化

给每个原始路径点分配权重,权重与该点和相邻点的距离成反比(密集点权重低,稀疏点权重高),这样叠加后总概率均匀。

核心代码示例:

path_points = pathDf[['x', 'y']].values
# 计算每个点的权重
weights = np.ones(len(path_points))
# 首尾点权重取相邻点距离的一半
weights[0] = np.linalg.norm(path_points[0] - path_points[1]) / 2
weights[-1] = np.linalg.norm(path_points[-1] - path_points[-2]) / 2
# 中间点权重取左右相邻点距离的平均值的一半
for i in range(1, len(path_points)-1):
    left_dist = np.linalg.norm(path_points[i] - path_points[i-1])
    right_dist = np.linalg.norm(path_points[i] - path_points[i+1])
    weights[i] = (left_dist + right_dist) / 4
# 归一化权重
weights /= np.sum(weights)

# 计算PDF时乘以权重
path_pdf = np.sum(weights[None, None, :] * (1 / (np.sqrt(2 * np.pi) * sigma_p)) * np.exp(-0.5 * (1 / (sigma_p ** 2)) * (np.sqrt((X1[:, :, None] - pathDf.x.values) ** 2 + (X2[:, :, None] - pathDf.y.values) ** 2)) ** 2), axis=2)
path_pdf /= np.sum(path_pdf)

内容的提问来源于stack exchange,提问作者Park Bo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:37:03