2012-06-10 14 views
4

我有一個算法,找到Rn函數/ n的最小值。我有一個約束流形,它是以一種奇異立方體圖像的形式給出的。將奇異立方體內部空間映射到Rn,更重要的是反過來也是相當平凡的,並且可以使用from_R_to_01應用於每個座標的unar函數來完成。如何在Erlang中創建變量的函數?

所以我想要做的是取我的目標函數F的某些arity,並做出另一個相同的功能,這將是相同的F,除了它的座標是從Rn映射到約束多方面的人。因此,我可以將它提供給我的最小化算法,在Rn中獲得一對座標,然後將它們映射到同一個流形以獲得「真實世界」座標。因此將非線性規劃任務減少到無約束優化。

那麼,回到問題。我有這段代碼爲2個案例工作。

minn_man2(F, Man) -> 
    OnRn = fun (X, Y) -> # this is the limiting part 
     OnMan = Man(from_R_to_01(X), from_R_to_01(Y)), 
     apply(F, OnMan) 
    end, 
    [X | [ Y | []]] = minn(OnRn), 
    Man(from_R_to_01(X), from_R_to_01(Y)). 

我該如何使它更通用?最難的部分是製作一個匿名功能的Fs'arity。不知道如何做到這一點。

+0

使用'list'或更好,'proplist'。 –

回答

1

想想我明白了!如果我需要爲每個特定的元素明確聲明OnRn,爲什麼我不製作它們。

首先,我手動爲unar和binar Mans在單個'case MA'語句中編寫了兩個單獨的聲明。然後我懶得用Python來生成一大堆這些。然後我尋找了一些eval來讓Erlang生成並評估運行時的適當聲明。在這裏。奇蹟般有效。

minn_man(F, Man) -> 
    MA = proplists:get_value(arity, erlang:fun_info(Man)), 
    R1 = fun (X) -> from_R_to_01(X) end, 

    XiStr = string:join(["X" ++ integer_to_list(I) || I <- lists:seq(1, MA)], ", "), 
    RiXiStr = string:join(["R1(X" ++ integer_to_list(I) ++ ")" || I <- lists:seq(1, MA)], ", "), 
    FunStr = "fun (" ++ XiStr ++ ") -> apply(F, Man(" ++ RiXiStr ++")) end.", 

    {ok, Tokens, _} = erl_scan:string(FunStr), 
    {ok, [Form]} = erl_parse:parse_exprs(Tokens), 
    Binding1 = erl_eval:add_binding('F', F, erl_eval:new_bindings()), 
    Binding2 = erl_eval:add_binding('Man', Man, Binding1), 
    Binding3 = erl_eval:add_binding('R1', R1, Binding2), 
    {value, OnRn, _} = erl_eval:expr(Form, Binding3), 

    XY = minn(OnRn), 
    apply(Man, lists:map(fun from_R_to_01/1, XY)). 
4

只能通過給它們一個列表的單個參數來模擬具有變量arity的函數(匿名或不)。然後你可以使用apply/2來評估它。

你的例子可以(未測試,要麼在所有優化)類似

minn_man(F, Man) -> 
    OnRn = fun (L) -> 
     OnMan = apply(Man, [from_R_to_01(X) || X<-L]), 
     apply(F, OnMan) 
    end, 
Man([from_R_to_01(X) || X<-minn(OnRn)). 

當然,人類應該以適當的格式返回值了。

相關問題