2

V在 Matlab 中创建随机向量时遇到了以下一组约束:(给定参数NDLtheta

  1. 向量V必须是N单位长
  2. 元素的平均值必须为theta
  3. 没有 2 个连续元素的差异可能超过 +/-10
  4. D == sum(L*cosd(V-theta))

我对最后一个问题最多。有任何想法吗?

编辑
其他语言或方程式形式的解决方案同样可以接受。Matlab 对我来说只是一个方便的原型设计工具,但最终的算法将在 java 中。

编辑
从评论和初步答案中,我想添加一些澄清和初步想法。

我不是从任何标准发行版中寻求“真正随机”的解决方案。我想要一个伪随机生成的值序列,满足给定参数集的约束。

我试图近似的系统是链长度为 L 的 N 个链,其中链的末端在 theta 方向上远离另一端 D。

我在这里的初步见解是,可以从考虑中删除 theta 直到最后,因为(2)本质上将 theta 添加到 0 均值向量 V 的每个元素(将均值移动到 theta)并且(4)只是再次删除该均值。所以,如果你能找到 theta=0 的解决方案,那么问题就解决了所有的 theta。

根据要求,这是一个合理的参数范围(不是硬约束,而是典型值):
5<N<200
3<D<150
L==1
0 < theta < 360

4

4 回答 4

1

我将从创建一个“有效”向量开始。这应该是可能的 - 比如说为每个条目计算它以具有相同的值。

一旦你得到那个向量,我会应用一些转换来“洗牌”它。“拒绝采样”是关键字 - 如果洗牌会违反您的规则之一,您就不要这样做。

作为我想出的转换:

  • 切换两个条目
  • 修改一个条目的值并修改第二个条目以保持第 4 个条件(理论上您可以将两个随机播放直到满足条件 - 但发生的机会非常低)

但也许你可以找到更多。

经常合理地执行此操作,您将获得一个“有效”的随机向量。理论上你应该能够得到所有有效的向量——实际上你可以尝试构建几个“开始”向量,这样就不会花那么长时间。

于 2013-04-10T09:43:21.583 回答
0

因此,根据您的新要求,您实际上正在寻找的是随机角度的有序列表,角度的最大变化为 10 度(我首先将其转换为弧度),这样距离和方向从头到尾并指定链接长度和链接数量?

模拟初始猜测。它不适用于 D 和 theta 约束(即指定的 D 和指定的 theta)

angles = zeros(N, 1)

for link = 2:N
    angles (link) = theta(link - 1) + (rand() - 0.5)*(10*pi/180)
end

使用遗传算法(或其他优化)根据以下成本函数调整角度:

dx = sum(L*cos(angle));
dy = sum(L*sin(angle));

D = sqrt(dx^2 + dy^2);
theta = atan2(dy/dx);

现在,成本只是 myDthetaabove 给出的向量与指定的Dand给出的向量之间的差theta(即输入)。

您仍然必须强制执行 10 度的最大变化规则,也许如果违反它会使成本函数变得巨大?也许有一种更简洁的方法可以在优化算法中指定序列约束(我不知道如何)。

我觉得如果您可以使用正确的参数找到正确的优化,这应该能够模拟您的问题。

于 2013-04-10T12:25:13.590 回答
0

你没有给我们很多细节来处理,所以我假设如下:

  • 随机数将从[-127+theta +127-theta]
  • 所有随机数都将来自均匀分布
  • 所有随机数都是类型int8

然后,对于前 3 个要求,您可以使用以下命令:

N = 1e4;
theta = 40;
diffVal = 10;

g = @() randi([intmin('int8')+theta  intmax('int8')-theta], 'int8') + theta;
V = [g(); zeros(N-1,1, 'int8')];
for ii = 2:N
    V(ii) = g();
    while abs(V(ii)-V(ii-1)) >= diffVal
        V(ii) = g();
    end
end

内联匿名函数以提高速度。

现在,最后一个要求,

D == sum(L*cos(V-theta))

有点奇怪......cos(V-theta)是将数据重新缩放到[-1 +1]区间的特定方法,然后乘以L将缩放到[-L +L]. 乍一看,您会期望 的sum平均值为0.

cos(x)然而, when的期望值x是一个随机变量,来自于[0 2*pi]is的均匀分布(例如,2/pi参见此处)。暂时忽略我们的极限与 不同的事实[0 2*pi], 的期望值sum(L*cos(V-theta))将简单地减少为 的常数值2*N*L/pi

你怎么能强迫它等于其他一些常数D是我无法做到的......你能否再详细说明一下?

于 2013-04-10T06:55:17.760 回答
0

这是一种方法。很明显,并非所有 theta、N、L 和 D 的组合都是有效的。很明显,您正在尝试模拟非常复杂的随机对象。您可能很难展示与这些向量有关的任何有用信息。

您尝试模拟的系列似乎类似于Wiener process。所以我从那个开始,你可以从任何随机但合理的开始。然后,我将其用作尝试满足 2,3 和 4 的优化的起点。初始值越接近有效向量(满足所有条件),收敛性就越好。

function series = generate_series(D, L, N,theta)
s(1) = theta;
for i=2:N,
    s(i) = s(i-1) + randn(1,1);
end
f = @(x)objective(x,D,L,N,theta)
q = optimset('Display','iter','TolFun',1e-10,'MaxFunEvals',Inf,'MaxIter',Inf)
[sf,val] = fminunc(f,s,q);
val
series = sf;



function value= objective(s,D,L,N,theta)
a = abs(mean(s)-theta);
b = abs(D-sum(L*cos(s-theta)));
c = 0;
for i=2:N,
    u =abs(s(i)-s(i-1)) ;
    if u>10,
        c = c + u;
    end
end
value = a^2 + b^2+ c^2;

似乎您正在尝试模拟非常复杂/奇怪的东西(给定曲率的路径?),请参阅其他评论者的问题。您仍然必须使用您的领域知识将 D 和 L 与合理的 mu 和 sigma 连接起来,以便 Wiener 充当初始化。

于 2013-04-10T08:52:52.783 回答