Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 网格上癌细胞的模型划分_Matlab_Loops_Recursion_While Loop_Simulation - Fatal编程技术网

Matlab 网格上癌细胞的模型划分

Matlab 网格上癌细胞的模型划分,matlab,loops,recursion,while-loop,simulation,Matlab,Loops,Recursion,While Loop,Simulation,我有一个5000x5000网格,我正试图在MATLAB中实现一个简单的癌症分割模型。最初,它选择一个随机点(x,y)并使该细胞成为癌细胞。在第一次迭代中,它会分裂-父单元停留在它的位置,子单元被随机分配到任何相邻单元。 到目前为止很容易 我的问题是:在连续的迭代中,子细胞通常会被分配给已经有癌细胞的细胞。在本例中,我希望子单元取代它的位置,并将已经存在的单元“碰撞”到相邻单元。如果相邻单元为空,则填充该单元并停止该过程。如果没有,则已在该位置的单元格将被碰撞,依此类推,直到最后一个单元格找到一个

我有一个5000x5000网格,我正试图在MATLAB中实现一个简单的癌症分割模型。最初,它选择一个随机点(x,y)并使该细胞成为癌细胞。在第一次迭代中,它会分裂-父单元停留在它的位置,子单元被随机分配到任何相邻单元。
到目前为止很容易

我的问题是:在连续的迭代中,子细胞通常会被分配给已经有癌细胞的细胞。在本例中,我希望子单元取代它的位置,并将已经存在的单元“碰撞”到相邻单元。如果相邻单元为空,则填充该单元并停止该过程。如果没有,则已在该位置的单元格将被碰撞,依此类推,直到最后一个单元格找到一个空白,并且进程停止

这应该很简单,但我不知道如何编写代码以及使用哪种循环

我是一个物理科学家而不是一个程序员,所以请把我当作一个傻瓜

这是我拼凑的一个函数,大致符合您提供的规范

随着癌细胞数量的增加,我的速度确实变慢了

基本上我有几个变量,NxN矩阵表示单元位置的网格(我称之为
,因为网格是现有matlab函数的名称)

我可以快速迭代的点向量。我选择一个种子位置,然后运行while循环,直到网格已满

在每次循环迭代中,我对每个单元格执行以下操作:

  • 生成一个随机数以确定该单元格是否应分割
  • 生成要分割的随机方向
  • 找到该方向上的第一个开板位置
  • 填充该位置
我还没有对它进行广泛的测试,但它似乎很有效

function simulateCancer(plateSize, pDivide)

plate = zeros(plateSize, plateSize);
nCells = 1;
cellLocations = zeros(plateSize*plateSize,2);

initX = randi(plateSize);
initY = randi(plateSize);

cellLocations(nCells,:) = [initX, initY];

plate(initX, initY) = 1;

f = figure;
a = axes('Parent', f);
im = imagesc(plate, 'Parent', a);


while(nCells < (plateSize * plateSize))
    currentGeneration = currentGeneration+1;
    for i = 1:nCells
        divide = rand();
        if divide <= pDivide
            divideLocation = cellLocations(i,:);
            divideDir = randi(4);
            [x, y, v] = findNewLocation(divideLocation(1), divideLocation(2), plate, divideDir);
            if (v==1)
                nCells = nCells+1;
                plate(x,y) = 1;
                cellLocations(nCells,:) = [x,y];
            end
        end
    end
    set(im,'CData', plate);
    pause(.1);
end

end

function [x,y, valid] = findNewLocation(xin, yin, plate, direction)   
    x = xin;
    y = yin;
    valid = 1;
    % keep looking for new spot if current spot is occupied
    while( plate(x, y) == 1)
       switch direction
            case 1 % divide up
                y = y-1;
            case 2 % divide down
                y = y+1;
            case 3 % divide left
                x = x-1;
            case 4 % divide down
                x = x+1;
            otherwise
            warning('Invalid direction')
            x = xin;
            y = yin;
        return;
       end

       %if there has been a collision with a wall then just quit
       if y==0 || y==size(plate,2)+1 || x==0 || x==size(plate,1)+1 % hit the top
           x = xin; %return original values to say no division happend
           y = yin;
           valid = 0;
           return;
       end

    end


end
功能模拟癌症(平板大小,pDivide)
板材=零(板材尺寸,板材尺寸);
NCELL=1;
单元位置=零(plateSize*plateSize,2);
initX=randi(板材尺寸);
initY=兰迪(平板尺寸);
单元位置(nCells,:)=[initX,initY];
板(initX,initY)=1;
f=数字;
a=轴(“父轴”,f);
im=图像SC(板‘母’,a);
而(nCells<(平板尺寸*平板尺寸))
currentGeneration=currentGeneration+1;
对于i=1:nCells
除法=兰德();
如果divide受an的启发,我想到了使用图像处理技术来实现这个模拟。特别是我们可以用它来扩散癌细胞

其想法是使用如下结构元素放大每个像素:

1 0 0
0 1 0
0 0 0
中心固定,另一个
1
随机放置在其余八个位置之一。这将有效地在该方向上扩展像素

执行膨胀的方法是创建一个空白图像,只设置一个像素,然后使用简单的OR操作累积所有结果

为了加快速度,我们不需要考虑每一个像素,而只需要在癌细胞群形成的当前块周围的那些像素上。内部的像素已经被癌细胞包围,如果放大就没有效果

为了进一步加快速度,我们在一次调用中对所有选择在同一方向上扩展的像素执行膨胀。因此,每次迭代,我们最多执行8次膨胀操作

这使得代码相对较快(我测试了1000x1000网格)。此外,它在所有迭代中保持相同的计时(不会随着网格开始填满而减慢)

以下是我的实现:

%# initial grid
img = false(500,500);

%# pick 10 random cells, and set them as cancerous
img(randi(numel(img),[10 1])) = true;

%# show initial image
hImg = imshow(img, 'Border','tight', 'InitialMag',100);

%# build all possible structing elements
%# each one dilates in one of the 8 possible directions
SE = repmat([0 0 0; 0 1 0; 0 0 0],[1 1 8]);
SE([1:4 6:9] + 9*(0:7)) = 1;

%# run simulation until all cells have cancer
BW = false(size(img));
while ~all(img(:)) && ishandle(hImg)
    %# find pixels on the perimeter of all "blocks"
    on = find(bwperim(img,8));

    %# percentage chance of division
    on = on( rand(size(on)) > 0.5 );    %# 50% probability of cell division
    if isempty(on), continue; end

    %# decide on a direction for each pixel
    d = randi(size(SE,3),[numel(on) 1]);

    %# group pixels according to direction chosen
    dd = accumarray(d, on, [8 1], @(x){x});

    %# dilate each group of pixels in the chosen directions
    %# to speed up, we perform one dilation for all pixels with same direction
    for i=1:8
        %# start with an image with only those pixels set
        BW(:) = false;
        BW(dd{i}) = true;

        %# dilate in the specified direction
        BW = imdilate(BW, SE(:,:,i));

        %# add results to final image
        img = img | BW;
    end

    %# show new image
    set(hImg, 'CData',img)
    drawnow
end
我还创建了一个500x500网格上的模拟动画,其中包含10个随机初始癌细胞(警告:.gif图像大小约为1MB,因此根据您的连接可能需要一些时间加载)


如果你有一个已经是3x3的癌细胞块,并且该块中心的细胞分裂,那么放置子细胞的规则(或规则)是什么?听起来像是一个适合递归解决方案而不是循环的问题。如果该块接触网格的边缘会发生什么,比如说左手边)中间的一个细胞向左分裂?该单元是否丢失或强制向右除法?@slayton关于递归:虽然编码可能比循环更容易,但对于大型网格来说,速度可能非常慢。是否需要跟踪每个单元产生于哪一代?或者它们都是等价的?如果它们都是等效的,您可以直接将新的子单元放置在blob的边缘。否则,它确实会变得更复杂。看起来太棒了-只是想让它现在运行-请原谅我的无知,但是我是否必须将plateSize定义为网格(即:5000)以及什么是pDivide?如果你想要一个5000x5000的网格,那么
plateSize
就是5000
pDivide
是一个给定单元将每代分割的概率。如果将其设置为1,则每个单元格将始终分割。如果将其设置为.1,则每个单元格将有10%的机会划分每一代。干杯-进展非常顺利,只是它一直告诉我“If divide>=pDivide”行上没有足够的输入参数。有什么想法吗?您需要向它传递两个输入参数,即
simulateCancer(5000,1)创建一个名为simulateCancer.m的文件,将我的代码粘贴到其中,然后从matlab的命令窗口中使用
simulateCancer(5000,1)
执行代码