2014-09-28 198 views
0

我在MATLAB中编写了一个小程序,使用TU游戏的多线性扩展来计算Shapley值 。但是,我运行MATLAB的符号数学工具箱时遇到了 问题。在 该程序我不得不集成一组函数来获得Shapley值 。然而,MATLAB程序内我不能使用 的INT()命令什么是matlabFunction的好替代品?

Error using sym/subsindex (line 663) Ivalid indexing or function definition. When defining a function, ensure that the body of the function is a SYM object. When indexing, the input must be numeric, logical or ':'. 

Error in ShapleyValueML (line 65)shv(jj)=int(dfy,0,1) 

因此我必须使用积分()来代替。在这种情况下,I 需要使用matlabFunction()将该组表达式转换为MATLAB函数句柄 。但是,在我访问此命令的所有Linux机器上(MATLAB R2014a) 不起作用(请参阅下面的讨论)。 作为一种解决方法,MATLAB程序将函数集 返回到当前工作空间中,使用int()命令可以计算出Shapley值 。

为了让讨论更加具体,让我们先考虑一下这个小的程序 。

function [shv,F,dfm]=ShapleyValueML(v) 

N=length(v); 
[~, n]=log2(N); 
S=1:N; 
int=0:-1:1-n; 
mat=(rem(floor(S(:)*pow2(int)),2)==1); 
cmat=(rem(floor(S(:)*pow2(int)),2)==0); 
x=sym('x',[1 n]); 
mx=1-x; 
y = sym('y'); 
vy=ones(1,n)*y; 
F=0; 
shv=zeros(1,n); 
dfm=cell(1,n); 

for ss=1:N 
    pd1=x(mat(ss,:)); 
    pd2=mx(cmat(ss,:)); 
    pd=prod(pd1)*prod(pd2)*v(ss); 
    F=pd+F; 
end 
F=expand(F); 

for jj=1:n 
    dF=diff(F,x(jj)); 
    dfy=subs(dF,x,vy); 
%% Does not work!! MATLAB bug??? 
% mf=matlabFunction(dfy); 
% shv(jj)=integral(mf,0,1); 
%% 
%% The best would be to use: 
%% 
% shv(jj)=int(dfy,0,1) 
%% but it cannot be used inside a program. 
dfm{jj}=dfy; 
end 

end 

注释的部分是不里面 程序的工作部件,但需要计算与该程序,这是它的目的Shapley值 。我测试了这个程序 多达12名球员,并且我能够通过两步程序成功计算出Shapley值。因此,上述程序 正确指出了所考虑的问题。为了更好地了解上述程序的这两步程序和功能 ,让我们专注于三人游戏。 的联盟的值由下面的数据阵列

>> v = [0,0,90,0,100,120,220]; 

注意联盟进行排序根据其独特 整数表示给出。游戏定义后,我们现在可以用 来计算 的多线性扩展和偏导数的集合 上面的程序,但不是Shapley的值。

>> [shv,F,dfm]=ShapleyValueML(v); 

所述一组偏导数的积分运行在单位立方体的对角线 ,但我们可以设置从[X1,X2,X3] 至[Y,Y,Y]中的变量,并且集成运行从0到1。

>> for k=1:3, shv(k)=int(dfm{k},0,1);end; 

一体化的解决方案是Shapley值由下式给出:

>> shv 

shv = 

    65 75 80 

检查,这确实是Shapley值可以在

>> sh_v=ShapleyValue(v) 

sh_v = 

    65 75 80 
实现的潜在功能的方式来完成

附带我的MATLAB游戏理论工具箱MatTuGames

http://www.mathworks.com/matlabcentral/fileexchange/35933-mattugames

而是用INT整合()一个也可以使用积分(), 但随后的内容就像

>> dfm{1} 

ans = 

    - 90*y^2 + 190*y 

必须matlabFunction()被改写成函数句柄。正如我上面提到的 这不适用于Linux (MATLAB R2013a,R2013b,R2014a)。看到这让我们尝试重现 的例子

>> syms x y 
>> r = sqrt(x^2 + y^2); 

从文档的URL:

http://www.mathworks.de/de/help/symbolic/generate-matlab-functions.html?searchHighlight=matlabFunction

这应该给

ht = 
@(x,y)tanh(sqrt(x.^2+y.^2)) 

,但我得到

>> ht = matlabFunction(tanh(r)) 
    Cell contents reference from a non-cell array object. 

    Error in vectorize (line 15) 
    c = cells{i}; 

    Error in sym/matlabFunction>mup2mat (line 319) 
    res = vectorize(res(2:end-1)); % remove quotes 

    Error in sym/matlabFunction>mup2matcell (line 304) 
    r = mup2mat(c{1}); 

    Error in sym/matlabFunction (line 123) 
    body = mup2matcell(funs); 

现在,这里是我的问题:存在有一个替代过程 从

>> dfm{1} 

ans = 

    - 90*y^2 + 190*y 

得到一个函数处理

>> [email protected](y) (- 90.*y.^2 + 190.*y) 

df = 

    @(y)(-90.*y.^2+190.*y) 

>> integral(df,0,1) 

ans = 

    65 

它集成或者换种方式。是否有另一种方法可用于 改变乘法运算*到元素乘法运算*和功率运算^到元素方式的功率。

当然,任何关于上述MATLAB程序 的改进建议都非常感谢。


+0

@Amro非常感谢。你是对的!!我不明白这个失败。尽管如此,遗憾的是,当变量/函数被内建函数遮蔽时,MATLAB不会显示像Mathematica这样的警告。 – 2014-09-28 15:42:37

+0

是的,那个错误信息有点神秘。我不得不通过调试器并检查调用堆栈来弄清楚发生了什么。 – Amro 2014-09-28 15:48:56

回答

1

我想我知道问题是什么;迈向ShapleyValueML功能的开始,您有一个名为int变量,它屏蔽了该内建integration function

... 

int=0:-1:1-n; %# <-- problem! 

... 

shv(jj)=int(dfy,0,1) 

... 

这也解释了从sym/subsindex传来的错误,你使用的是象征性的对象作为一个索引数值数组int

将变量名称更改为其他名称,并且注释的代码运行正常(符号集成)!简单:)

相关问题