1、在电脑桌面上打开MATLAB。
2、当你没有把你编辑好的子函数放入正确的文件夹时,不管你输入的程序是否有错,当你执行时,系统都会提示“没有定义”,这个时候就是没有子函数文亩慧件放到主函数库文件夹中。
3、首先,输入“editconv”这个“conv”是我准备编辑的子函数的主函数名,每个人所需的主函数名都不一样,这里可以不要那么在意。然后就可以打开相应的主函数,这是可以看到主函数所在文件夹位置。如图所示,※记住这个位置。
4、然后进行子函数的编辑,首先新建一个新的m文件,然后在编辑框中输入所要的子函数,例如我就是输入了convnem的函数,配禅这是conv的子函数。然后点击保存。
5、接下来,在“conv”所在文件位置,将位置记录下来,将子函数的文件保存到主函数所在的文件夹即可,然后在重新的将你所需的程序(含有子函数的)输入并且执行,这时你会发现原来提示的错误没有了,那么这时调用自己添加的子函数成功了。以后有相应的子函数都可以通过这样的方法进行添加子函数迅卖答。
题主并没有把问题描述清楚。
其实这是一个单一设施选址问题,其中的ai对应的是平樱桐州面上点的坐标,wi为各点的权重。所谓【f是一个特定函数】说的很含糊,其实f是所选点与各已知点距离的加权和,而迭代的目标则是让f达到最小值。
这是一个无约束优化问题,可用fminunc直接求解:
% 常数定义a1 = [2 0] a2 = [4 10] a3 = [8 3] a4 = [3 5] a5 = [5 7]
w1 = 6 w2 = 2 w3 = 7 w4 = 5 w5 = 4
e = 1e-6
% 为便于统一处理,使用数组
A = [a1 a2 a3 a4 a5]
W = [w1 w2 w3 w4 w5]
% 初值
x0 = rand(2,1) * 10
% 定义求范数和目标函数的匿名函数
n = @ (x) arrayfun( @ (i) norm( A(:,i) - x), 1:length(W) )
f = @ (x) sum( W .* n(x) )
x=fminunc(f,x0,optimset('LargeScale','off', 'display', 'off'))
如果用题主贴出的来式子编程序,代码如下:
% 常数定义a1 = [2 0] a2 = [4 10] a3 = [8 3] a4 = [3 5] a5 = [5 7]
w1 = 6 w2 = 2 w3 = 7 w4 = 5 w5 = 4
e = 1e-6
% 为便于统一处理,使用数组
A = [a1 a2 a3 a4 a5]
W = [w1 w2 w3 w4 w5]
% 初值
x0 = rand(2,1) * 10
% 定义求范数和目标函数的匿名函数
n = @ (x) arrayfun( @ (i) norm( A(:,i) - x), 1:length(W) )
f = @ (x) sum( W .* n(x) )
% 迭代
while true
N = n(x0)
x = sum( [W W] .* A ./ [N N], 2 ) / sum( W ./ N, 2 )
% 若满足精度要求,退出循环
if abs( f(x) - f(x0) ) <= f(x0) * e
break
end
x0 = x
end
x
其实,迭代的终止条件除题主所给的目标函数相对误差(TolFun)之外,常见的还有变量本身的允许误差(TolX)以及迭代次数(MaxIter)等。
下面给出一个增加了绘图示意的版本。等值线为目标函数,各已知点根据脊蔽权重以不同大小表示,动画示意轮颂了从不同初值经迭代到达最优点的过程。
% 常数定义a1 = [2 0] a2 = [4 10] a3 = [8 3] a4 = [3 5] a5 = [5 7]
w1 = 6 w2 = 2 w3 = 7 w4 = 5 w5 = 4
e = 1e-6
% 为便于统一处理,使用数组
A = [a1 a2 a3 a4 a5]
W = [w1 w2 w3 w4 w5]
% 初值(随机生成)
x0 = rand(2,1) * 10
% 定义求范数和目标函数的匿名函数
n = @ (x) arrayfun( @ (i) norm( A(:,i) - x), 1:length(W) )
f = @ (x) sum( W .* n(x) )
% 绘图
clf
ezcontour(@(x,y)arrayfun(@(x,y)f([xy]),x,y),[-3 12 -1 11])
hold on
for i = 1 : length(W)
plot(A(1,i), A(2,i), 'o', 'MarkerSize', W(i)*2, 'MarkerFace', 'c' )
text(A(1,i)+0.4, A(2,i), sprintf('(%g, %g)', A(:,i)))
end
h2 = plot(x0(1), x0(2), ':.', 'color', [1 1 1]*0.8)
h1 = plot(x0(1), x0(2), 'r*')
h3 = title('')
axis equal
colorbar
X = x0
% 迭代
while true
N = n(x0)
x = sum( [W W] .* A ./ [N N], 2 ) / sum( W ./ N, 2 )
% 更新绘图
X = [X x]
set(h2, 'XData', X(1,:), 'YData', X(2,:))
set(h1, 'XData', x(1), 'YData', x(2))
set(h3, 'str', sprintf('Current point: (%.4f, %.4f), f(x) = %.6f', x, f(x)) )
drawnow
pause(0.5)
% 若满足精度要求,退出循环,否则以新的值继续迭代
if abs( f(x) - f(x0) ) <= f(x0) * e
set(h1, 'Color', 'g', 'Marker', 'p', 'MarkerFace', 'g')
break
end
x0 = x
end
参考:
Weiszfeld 算法
1 x'-- x的转置矩阵x*x'的结果是矩阵或数值,由x的维数(x若为向量,维数就是其长度)决定
2 inv 求逆矩阵。
miu=1/(ad'*inv(R)*ad)
既然程序没有报错,那么(ad'*inv(R)*ad)就是一个数值,而
w = miu*inv(R)*ad = 1/(ad'*inv(R)*ad) * inv(R)*ad 是矩阵运算,
不能按照代数四则运算进行简单的“约分”败饥。
3 y(1,v)=w.'*a
v=v+1 这是为了记录向量y,v表液枯耐示当前值在向量中的位置。算完这一个后,位置向后移动,从v到(v+1),继续循环,算出的y值闹春就记录在(v+1)位置处
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)