2014-09-28 205 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

將變量名稱更改爲其他名稱,並且註釋的代碼運行正常(符號集成)!簡單:)

相關問題