Algorithm 在此代码段中是否可以进行预分配?

Algorithm 在此代码段中是否可以进行预分配?,algorithm,matlab,Algorithm,Matlab,下面是蚁群优化的一段代码。我已经删除了我认为理解代码绝对不必要的内容。其余的我不确定,因为我不熟悉matlab上的编码。然而,我在500个左右的城市上运行这个算法,有500个蚂蚁和1000次迭代,与其他在matlab上实现的算法相比,代码运行速度非常慢。就我的项目而言,我只需要数据集,不需要在matlab上演示编码能力,而且我有时间限制,根本不允许我从头开始学习matlab,因为在最后期限给定时,没有考虑到这一点,也没有预料到这一点,所以我从在线来源获得了算法 Matlab建议在一个循环中预先分

下面是蚁群优化的一段代码。我已经删除了我认为理解代码绝对不必要的内容。其余的我不确定,因为我不熟悉matlab上的编码。然而,我在500个左右的城市上运行这个算法,有500个蚂蚁和1000次迭代,与其他在matlab上实现的算法相比,代码运行速度非常慢。就我的项目而言,我只需要数据集,不需要在matlab上演示编码能力,而且我有时间限制,根本不允许我从头开始学习matlab,因为在最后期限给定时,没有考虑到这一点,也没有预料到这一点,所以我从在线来源获得了算法

Matlab建议在一个循环中预先分配两个变量,因为我相信它们是改变大小的数组。但是,我不完全理解这两部分代码的目的,因此我无法做到这一点。我相信这两个数组在循环的每次迭代中都会增加一个新项,所以从技术上讲,它们都应该是零,并且可以根据for循环条件预先分配两个预期最终大小的大小,但我不确定。我已经尝试过为这两个数组预分配零,但它似乎没有解决任何问题,因为Matlab仍然显示了速度建议的预分配

在下面的预分配中,我对MATLAB推荐的两个变量添加了两条注释。如果有人能浏览一下,并告诉我是否可能,我将不胜感激

    x = 10*rand(50,1);
    y = 10*rand(50,1);
    n=numel(x);
    D=zeros(n,n);

    for i=1:n-1
        for j=i+1:n
            D(i,j)=sqrt((x(i)-x(j))^2+(y(i)-y(j))^2);
            D(j,i)=D(i,j);
        end
    end

    model.n=n;
    model.x=x;
    model.y=y;
    model.D=D;

nVar=model.n;

MaxIt=100;     
nAnt=50;

Q=1;

tau0=10*Q/(nVar*mean(model.D(:)));

alpha=1;
beta=5;
rho=0.6;

eta=1./model.D;
tau=tau0*ones(nVar,nVar);
BestCost=zeros(MaxIt,1);

empty_ant.Tour=[];
empty_ant.Cost=[];

ant=repmat(empty_ant,nAnt,1);

BestSol.Cost=inf;

for it=1:MaxIt

    for k=1:nAnt
        ant(k).Tour=randi([1 nVar]);

        for l=2:nVar
            i=ant(k).Tour(end);
            P=tau(i,:).^alpha.*eta(i,:).^beta;
            P(ant(k).Tour)=0;
            P=P/sum(P);
            r=rand;
            C=cumsum(P);
            j=find(r<=C,1,'first');
            ant(k).Tour=[ant(k).Tour j];
        end

        tour = ant(k).Tour;
        n=numel(tour);
        tour=[tour tour(1)]; %MatLab recommends preallocation here
        ant(k).Cost=0;

        for i=1:n
        ant(k).Cost=ant(k).Cost+model.D(tour(i),tour(i+1));
        end

        if ant(k).Cost<BestSol.Cost
            BestSol=ant(k);
        end

    end

    for k=1:nAnt
        tour=ant(k).Tour;
        tour=[tour tour(1)];

        for l=1:nVar
            i=tour(l);
            j=tour(l+1);
            tau(i,j)=tau(i,j)+Q/ant(k).Cost;
        end

    end

    tau=(1-rho)*tau;

    BestCost(it)=BestSol.Cost;

    figure(1);
    tour=BestSol.Tour;
    tour=[tour tour(1)];  %MatLab recommends preallocation here
    plot(model.x(tour),model.y(tour),'g.-');
end
x=10*rand(50,1);
y=10*兰特(50,1);
n=努美尔(x);
D=零(n,n);
对于i=1:n-1
对于j=i+1:n
D(i,j)=sqrt((x(i)-x(j))^2+(y(i)-y(j))^2);
D(j,i)=D(i,j);
结束
结束
模型n=n;
模型x=x;
模型y=y;
模型D=D;
nVar=型号n;
最大值=100;
nAnt=50;
Q=1;
tau0=10*Q/(nVar*平均值(模型D(:));
α=1;
β=5;
rho=0.6;
eta=1/型号D;
tau=tau0*one(nVar,nVar);
最佳成本=零(最大,1);
空_ant.Tour=[];
空成本=[];
ant=repmat(空_ant,nAnt,1);
最佳成本=inf;
for it=1:MaxIt
对于k=1:nAnt
ant(k).Tour=randi([1 nVar]);
对于l=2:nVar
i=蚂蚁(k).旅行(结束);
P=tau(i,:).^alpha.*eta(i,:).^beta;
P(ant(k).Tour)=0;
P=P/总和(P);
r=兰特;
C=总和(P);

j=find(r如果更改数组的大小,则意味着将其复制到内存中的新位置。对于小数组来说这不是一个大问题,但对于大数组来说,这会大大降低代码的速度。您使用的巡更数组的大小是固定的(在本例中为51或n+1)因此,您应该将它们预先分配为零数组。您唯一要做的就是将巡更的第一个元素再次添加到末尾,这样您所要做的就是设置数组的最后一个元素

以下是您应该更改的内容:

x = 10*rand(50,1);
y = 10*rand(50,1);
n=numel(x);
D=zeros(n,n);

for i=1:n-1
    for j=i+1:n
        D(i,j)=sqrt((x(i)-x(j))^2+(y(i)-y(j))^2);
        D(j,i)=D(i,j);
    end
end

model.n=n;
model.x=x;
model.y=y;
model.D=D;

nVar=model.n;

MaxIt=1000;     
nAnt=50;

Q=1;

tau0=10*Q/(nVar*mean(model.D(:)));

alpha=1;
beta=5;
rho=0.6;

eta=1./model.D;
tau=tau0*ones(nVar,nVar);
BestCost=zeros(MaxIt,1);

empty_ant.Tour=zeros(n, 1);
empty_ant.Cost=[];

ant=repmat(empty_ant,nAnt,1);

BestSol.Cost=inf;

for it=1:MaxIt

    for k=1:nAnt
        ant(k).Tour=randi([1 nVar]);

        for l=2:nVar
            i=ant(k).Tour(end);
            P=tau(i,:).^alpha.*eta(i,:).^beta;
            P(ant(k).Tour)=0;
            P=P/sum(P);
            r=rand;
            C=cumsum(P);
            j=find(r<=C,1,'first');
            ant(k).Tour=[ant(k).Tour j];
        end
        tour = zeros(n+1,1);
        tour(1:n) = ant(k).Tour;
        n=numel(ant(k).Tour);
        tour(end) = tour(1); %MatLab recommends preallocation here
        ant(k).Cost=0;

        for i=1:n
        ant(k).Cost=ant(k).Cost+model.D(tour(i),tour(i+1));
        end

        if ant(k).Cost<BestSol.Cost
            BestSol=ant(k);
        end

    end

    for k=1:nAnt
        tour(1:n)=ant(k).Tour;
        tour(end) = tour(1);

        for l=1:nVar
            i=tour(l);
            j=tour(l+1);
            tau(i,j)=tau(i,j)+Q/ant(k).Cost;
        end

    end

    tau=(1-rho)*tau;

    BestCost(it)=BestSol.Cost;

    figure(1);
    tour(1:n) = BestSol.Tour;
    tour(end) = tour(1);  %MatLab recommends preallocation here
    plot(model.x(tour),model.y(tour),'g.-');
end
x=10*rand(50,1);
y=10*兰特(50,1);
n=努美尔(x);
D=零(n,n);
对于i=1:n-1
对于j=i+1:n
D(i,j)=sqrt((x(i)-x(j))^2+(y(i)-y(j))^2);
D(j,i)=D(i,j);
结束
结束
模型n=n;
模型x=x;
模型y=y;
模型D=D;
nVar=型号n;
最大值=1000;
nAnt=50;
Q=1;
tau0=10*Q/(nVar*平均值(模型D(:));
α=1;
β=5;
rho=0.6;
eta=1/型号D;
tau=tau0*one(nVar,nVar);
最佳成本=零(最大,1);
空的巡回=零(n,1);
空成本=[];
ant=repmat(空_ant,nAnt,1);
最佳成本=inf;
for it=1:MaxIt
对于k=1:nAnt
ant(k).Tour=randi([1 nVar]);
对于l=2:nVar
i=蚂蚁(k).旅行(结束);
P=tau(i,:).^alpha.*eta(i,:).^beta;
P(ant(k).Tour)=0;
P=P/总和(P);
r=兰特;
C=总和(P);

j=find(r如果更改数组的大小,则意味着将其复制到内存中的新位置。对于小数组来说这不是一个大问题,但对于大数组来说,这会大大降低代码的速度。您使用的巡更数组的大小是固定的(在本例中为51或n+1)因此,您应该将它们预先分配为零数组。您唯一要做的就是将巡更的第一个元素再次添加到末尾,这样您所要做的就是设置数组的最后一个元素

以下是您应该更改的内容:

x = 10*rand(50,1);
y = 10*rand(50,1);
n=numel(x);
D=zeros(n,n);

for i=1:n-1
    for j=i+1:n
        D(i,j)=sqrt((x(i)-x(j))^2+(y(i)-y(j))^2);
        D(j,i)=D(i,j);
    end
end

model.n=n;
model.x=x;
model.y=y;
model.D=D;

nVar=model.n;

MaxIt=1000;     
nAnt=50;

Q=1;

tau0=10*Q/(nVar*mean(model.D(:)));

alpha=1;
beta=5;
rho=0.6;

eta=1./model.D;
tau=tau0*ones(nVar,nVar);
BestCost=zeros(MaxIt,1);

empty_ant.Tour=zeros(n, 1);
empty_ant.Cost=[];

ant=repmat(empty_ant,nAnt,1);

BestSol.Cost=inf;

for it=1:MaxIt

    for k=1:nAnt
        ant(k).Tour=randi([1 nVar]);

        for l=2:nVar
            i=ant(k).Tour(end);
            P=tau(i,:).^alpha.*eta(i,:).^beta;
            P(ant(k).Tour)=0;
            P=P/sum(P);
            r=rand;
            C=cumsum(P);
            j=find(r<=C,1,'first');
            ant(k).Tour=[ant(k).Tour j];
        end
        tour = zeros(n+1,1);
        tour(1:n) = ant(k).Tour;
        n=numel(ant(k).Tour);
        tour(end) = tour(1); %MatLab recommends preallocation here
        ant(k).Cost=0;

        for i=1:n
        ant(k).Cost=ant(k).Cost+model.D(tour(i),tour(i+1));
        end

        if ant(k).Cost<BestSol.Cost
            BestSol=ant(k);
        end

    end

    for k=1:nAnt
        tour(1:n)=ant(k).Tour;
        tour(end) = tour(1);

        for l=1:nVar
            i=tour(l);
            j=tour(l+1);
            tau(i,j)=tau(i,j)+Q/ant(k).Cost;
        end

    end

    tau=(1-rho)*tau;

    BestCost(it)=BestSol.Cost;

    figure(1);
    tour(1:n) = BestSol.Tour;
    tour(end) = tour(1);  %MatLab recommends preallocation here
    plot(model.x(tour),model.y(tour),'g.-');
end
x=10*rand(50,1);
y=10*兰特(50,1);
n=努美尔(x);
D=零(n,n);
对于i=1:n-1
对于j=i+1:n
D(i,j)=sqrt((x(i)-x(j))^2+(y(i)-y(j))^2);
D(j,i)=D(i,j);
结束
结束
模型n=n;
模型x=x;
模型y=y;
模型D=D;
nVar=型号n;
最大值=1000;
nAnt=50;
Q=1;
tau0=10*Q/(nVar*平均值(模型D(:));
α=1;
β=5;
rho=0.6;
eta=1/型号D;
tau=tau0*one(nVar,nVar);
最佳成本=零(最大,1);
空的巡回=零(n,1);
空成本=[];
ant=repmat(空_ant,nAnt,1);
最佳成本=inf;
for it=1:MaxIt
对于k=1:nAnt
ant(k).Tour=randi([1 nVar]);
对于l=2:nVar
i=蚂蚁(k).旅行(结束);
P=tau(i,:).^alpha.*eta(i,:).^beta;
P(ant(k).Tour)=0;
P=P/总和(P);
r=兰特;
C=总和(P);

j=find(r我认为MATLAB编辑器在这种情况下给出的警告是错误的。数组没有重复调整大小,只是调整了一次大小。原则上,
tour(end+1)=tour(1)
tour=[tour,tour(1)]
更有效,但在这种情况下,您可能不会注意到成本上的差异

如果您想加快此代码的速度,可以考虑对其某些循环进行矢量化,并减少执行的索引操作的数量。例如,本节:

tour = ant(k).Tour;
n=numel(tour);
tour=[tour tour(1)]; %MatLab recommends preallocation here
ant(k).Cost=0;

for i=1:n
   ant(k).Cost=ant(k).Cost+model.D(tour(i),tour(i+1));
end

if ant(k).Cost<BestSol.Cost
   BestSol=ant(k);
end
tour=ant(k).tour;
n=努梅尔(旅游);
tour=[tour tour(1)];%MatLab建议在此处进行预分配
蚂蚁(k)。成本=0;
对于i=1:n
ant(k).Cost=ant(k).Cost+model.D(tour(i),tour(i+1));
结束

如果ant(k).Cost我认为MATLAB编辑器在这种情况下给出的警告是错误的。数组没有重复调整大小,只是调整了一次大小。原则上,
tour(end+1)=tour(1)
tour=[tour,tour(1)]
更有效,但在这种情况下,您可能没有注意到成本上的差异

如果你想加速这个代码,你不能