只允许每个图块中的固定数量的随机点

时间:2016-03-07 11:44:00

标签: matlab

跟进上一个问题,我认为我的代码应该限制总图块每个象限中随机生成的点数;但它没有用。

n = 4;
used = [];
k = 0;
a1_count = 0;
a2_count = 0;
a3_count = 0;
a4_count = 0;
min = 1;
max = 1;

while k<n
    x = rand*2;
    y = rand*2;

    notvalid = 0;

    if (0 <= x) && (x <= 1) && (0 <= y) && (y <= 1)
        a1_count = a1_count + 1;
    end
    if (1 < x) && (x <= 2) && (0 <= y) && (y <= 1)
        a2_count = a2_count + 1;
    end
    if (0 <= x) && (x <= 1) && (1 < y) && (y <= 2)
        a3_count = a3_count + 1;
    end
    if (1 < x) && (x <= 2) && (1 < y) && (y <= 2)
        a4_count = a4_count + 1;
    end
    %%%
    if (min <= a1_count) && (a1_count <= max) && (min <= a2_count) && (a2_count <= max)...
            && (min <= a3_count) && (a3_count <= max) && (min <= a4_count) && (a4_count <= max)
        notvalid=1;
    end

    if notvalid
        continue
    end

    used(end+1,:) = [x;y];
    k = k+1;


end

我希望生成4个随机点,并且在总面积的每个象限中都有一个。为此,我在每个象限中有一个最大和最小点数(在这种情况下为1),并且if语句用于检查每个图块的计数是否在最小值和最大值之内。如果它没有,那么notvalid = 0和循环应该重新开始。然而,这个函数似乎不起作用,因为循环总共有4个点完成并且是完全随机的(所有计数应该= 1)。

有人可以找到我出错的地方吗?

1 个答案:

答案 0 :(得分:2)

我可能会遗漏一些东西,但最简单的方法可能就像

  1. 在第一个网格单元格的x / y范围内选择N个随机数
  2. 对所有网格单元重复
  3. 以下是一些应该为每个网格单元创建N个随机x / y点的基本代码

    % Define the grid (for demonstration purposes)
    dx = 1; dy = 1;
    xrange = 0:dx:2;
    yrange = 0:dy:2;
    
    % Number of points per cell
    N = 1;
    
    [lowerx, lowery] = meshgrid(xrange(1:end-1), yrange(1:end-1));
    
    % Store all those random numbers in a cell
    data = cell(size(lowerx));
    
    for k = 1:numel(lowerx);
        % Generate 4 random points within the x/y range
        xcoord = (rand(N, 1) * dx) + lowerx(k);
        ycoord = (rand(N, 1) * dy) + lowery(k);
    
        data{k} = [xcoord, ycoord];
    end
    
    disp(data)
    
    data =
    
        [1x2 double]    [1x2 double]
        [1x2 double]    [1x2 double]
    

    修改

    要使用您提供的代码直接解决 的问题,问题代码中的逻辑有点不稳定。我已经重写了你的while循环,以便更清楚一点,所以我们可以通过它进行讨论。

    while k < n
        x = rand * 2;
        y = rand * 2;
    
        if y >= 0 && y < 1
            if x >= 0 && x < 1
                a1_count = a1_count + 1;
            else
                a2_count = a2_count + 1;
            end
        else
            if x >= 0 && x < 1
                a3_count = a3_count + 1;
            else
                a4_count = a4_count + 1;
            end
        end
    
        counts = [a1_count, a2_count, a3_count, a4_count];
        notValid = all(counts >= minimum) && all(counts <= maximum);
    
        if notValid
            continue;
        end
    
        used(end+1,:) = [x;y];
        k = k+1;
    end
    

    最重要的是你的notValid检查。如果您实际查看了您正在检查的内容(所有*_count变量都在预先指定的限制范围内),我相信如果所有这些条件都为真,那么当前点有效;但是你说的正好相反。

    然后你基本上说,如果当前x y 有效,那么将其添加到used列表中。那么这个逻辑很好,除非你像我之前所说的那样向后定义有效性。

    好的,除此之外,当你认为一个点有效时,让我们看看。好吧,那么你(正确地)进入下一次迭代,但你永远不会减少*_count变量。所以说你已经在象限1中有1点,而第二次迭代通过循环再次在象限1中。好吧,你要在a1_count添加1,然后看到它有效(a1_count超过max)并转到下一个循环,但是{{1} 保持为2,尽管真的只有1,因为你刚刚拒绝它。

    现在,所有这一切都放在一边。让我们通过循环考虑第一次时间并查看您的有效性检查。由于您只添加一个点。您的有效性检查可以从不传递(如果正确实施),因为所有 a1_count变量除了刚刚增加的变量将小于最小值。

    所以我认为发生了什么事情你可能首先正确地进行了有效性检查,最后得到了一个infite while循环,然后否定了那个检查,没有得到无限循环,但结果得到了错误解。

    您目前获得的解决方案,由于逻辑错误,实际上是通过while循环的前4次。

    如果您真的喜欢当前的方法,我们可以将代码清理干净。

    *_count