如何使用这些约束生成随机matlab向量

时间:2013-04-10 03:44:16

标签: matlab math random inverse-kinematics

我在Matlab中创建随机向量V时遇到以下一组约束:(给定参数NDL和{ {1}})

  1. 向量theta必须为V单位长
  2. 元素的平均值必须为N
  3. 没有2个连续元素的差异可能超过+/- 10
  4. theta
  5. 我在最后一个问题上遇到的问题最多。有什么想法吗?

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

    修改
    从评论和初步答案中我想补充一些说明和初步想法。

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

    我正在尝试近似的系统是链接长度为L的N个链接链,其中链的末端在距离θ的另一端D处。

    我最初的见解是theta可以从考虑中移除直到结束,因为(2)本质上将θ添加到0均值向量V的每个元素(将均值移到theta)和(4)简单地删除再说一遍。因此,如果你能找到theta = 0的解决方案,那么问题就解决了所有的问题。

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

4 个答案:

答案 0 :(得分:1)

我首先要创建一个“有效”的向量。这应该是可能的 - 比如计算每个条目具有相同的值。

一旦你得到那个向量,我会应用一些转换来“洗牌”它。 “Rejection sampling”是关键字 - 如果随机播放违反您的某个规则,则您不会这样做。

作为转变,我想出了:

  • 切换两个条目
  • 修改一个条目的值并修改第二个条目以保持第四个条件(从理论上说,你可以随意洗牌,直到条件满足 - 但发生的可能性非常低)

但也许你可以找到更多。

经常这样做,你得到一个“有效”的随机向量。从理论上讲,你应该能够获得所有有效的向量 - 实际上你可以尝试构造几个“开始”向量,这样就不会花那么长时间。

答案 1 :(得分: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)是来自x中的统一分布的随机变量时,[0 2*pi]的预期值为2/pi(例如,请参阅here) 。暂时忽略我们的限制与[0 2*pi]不同的事实,sum(L*cos(V-theta))的预期值将简单地降低为2*N*L/pi的常数值。

你怎么能强制这等于其他常数D超出我的范围......你或许能详细说明一下吗?

答案 2 :(得分:0)

这是一种做法。很明显,并非所有θ,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充当初始化。

答案 3 :(得分: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);

现在成本只是我上面的Dtheta给出的向量与指定的Dtheta给出的向量之间的差异(即输入)。

您仍然需要强制执行10度规则的最大更改,或许只是在违反时才会使成本函数变得庞大?也许有一种更简洁的方法来指定优化算法中的序列约束(我不知道如何)。

我觉得如果你能用正确的参数找到合适的优化,那么应该可以模拟你的问题。