這是留言板-既然來了,就留個言再走吧!
由 養花種魚數月亮賞星星 於 2029年7月22日星期日
下午2:43 發表
Mathematica教學:Simplex method in tableau form
由 戴忠淵 於 2025年8月6日星期三
上午7:41 發表

myConstrains[constrains_] :=
Block[{num, s, mycon}, num = Length[constrains];
mycon =
Table[If[Head[constrains[[i]]] === LessEqual,
constrains[[i]][[1]] + s[i] == constrains[[i]][[2]],
If[Head[constrains[[i]]] === Equal,
constrains[[i]][[1]] + R[i] == constrains[[i]][[2]],
constrains[[i]][[1]] - s[i] + R[i] ==
constrains[[i]][[2]]]], {i, num}];
mycon /. x__[y_] :> ToExpression[ToString[x] <> ToString[y]]]
LPstd[obj_, mycons_] :=
Block[{myvar, basicvars, nonbasicvars, AB, BM, c, A, B, rowindex1,
rowindex2}, myvar = Variables[mycons[[All, 1]]];
myvar =
Flatten[{Sort@
Select[myvar, Not@StringStartsQ[SymbolName[#], "s" | "R"] &],
Sort@Select[myvar, StringStartsQ[SymbolName[#], "s"] &],
Sort@Select[myvar, StringStartsQ[SymbolName[#], "R"] &]}];
AB = {Coefficient[mycons[[All, 1]], #] & /@
Select[myvar, Not@StringStartsQ[SymbolName[#], "s" | "R"] &],
Coefficient[mycons[[All, 1]], #] & /@
Select[myvar, StringStartsQ[SymbolName[#], "s"] &],
Coefficient[mycons[[All, 1]], #] & /@
Select[myvar, StringStartsQ[SymbolName[#], "R"] &]};
AB = Transpose@Flatten[AB, 1];
AB = Join[{Flatten[
Table[Select[myvar,
StringStartsQ[SymbolName[#], i] &], {i, {"x", "s", "R"}}]]},
AB];
c = Flatten[{Table[
Coefficient[obj, #] & /@
Select[myvar, StringStartsQ[SymbolName[#], i] &], {i, {"x",
"s"}}], Table[-BM, {Length[
Select[myvar, StringStartsQ[SymbolName[#], "R"] &]]}], 0}];
basicvars =
Select[AB[[All, #]] & /@ (Flatten /@
Map[Position[myvar, #] &,
Tuples[myvar, {Length[mycons]}], {2}]), #[[2 ;; -1]] ===
IdentityMatrix[Length[mycons]] &][[1, 1]];
nonbasicvars =
Flatten[Table[
Select[Complement[myvar, basicvars],
StringStartsQ[SymbolName[#], i] &], {i, {"x", "s", "R"}}]];
c = Flatten@{c[[Flatten[Position[myvar, #] & /@ nonbasicvars]]],
c[[Flatten[Position[myvar, #] & /@ basicvars]]], 0};
AB = Join[{Flatten@{nonbasicvars, basicvars}},
Flatten /@
Transpose@{AB[[2 ;; -1]][[All,
Sort[Flatten[Position[myvar, #] & /@ nonbasicvars]]]],
IdentityMatrix[Length[mycons]]}];
rowindex1 = c[[-Length[basicvars] - 1 ;; -2]];
rowindex2 = Range[Length[mycons]];
Flatten[{c -
Total[rowindex1[[#]]*
Flatten[{AB[[2 ;; -1]][[rowindex2[[#]]]],
mycons[[rowindex2[[#]], 2]]}] & /@
Range[Length@rowindex1]],
AB[[2 ;; -1]][[All,
Sort[Flatten[Position[myvar, #] & /@ nonbasicvars]]]],
IdentityMatrix[Length[mycons]], mycons[[All, 2]],
Flatten@{Sort@
Select[nonbasicvars, StringStartsQ[SymbolName[#], "x"] &],
Sort@Select[nonbasicvars,
StringStartsQ[SymbolName[#], "s"] &],
Sort@Select[nonbasicvars,
StringStartsQ[SymbolName[#], "R"] &]}, basicvars} & /@
Range[2], 1]]
simplexmethod[c_, A_, B_, b_, xnb_, xb_, cp_, Ap_, Bp_, bp_, xnbp_,
xbp_] :=
Block[{cB, nA, nB, mysymbol, pivotCol, AB, leaveVarpos, Bnew, xbnew,
xnbnew, Anew, cnew, znew, z, BM, ABp},
(*初始化變數*)
nA = Length[xnb];
nB = Length[xb];
(*建立符號變數*)
mysymbol = Flatten@{xnbp, xbp};
(*找出進入變數(最負的檢驗數)*)
pivotCol = PositionSmallest[-c[[1 ;; -2]] /. BM -> 10^6][[1]];
(*合併A和B矩陣*)
AB = Flatten /@ Transpose[{A, B}];
Print@MatrixForm@AB;
ABp = Flatten /@ Transpose[{Ap, Bp}];
leaveVarpos =
PositionSmallest[
b/(If[# <= 0, 10^-6, #] & /@ AB[[All, pivotCol]] /. BM -> 10^6) /.
x_ /; x <= 0 -> 10^6][[1]];
(*更新基變數和非基變數*)
xbnew = xb /. xb[[leaveVarpos]] -> mysymbol[[pivotCol]];
xnbnew = xnb /. mysymbol[[pivotCol]] -> xb[[leaveVarpos]];
Bnew =
ABp[[All, Flatten[Position[mysymbol, #] & /@ Flatten@{xbnew}]]];
cB = cp[[Flatten[Position[mysymbol, #] & /@ xbnew]]];
(*計算新的檢驗數和目標函數值*)
znew = Flatten[{cB . Inverse[Bnew] . Ap - cp[[1 ;; nA]],
cB . Inverse[Bnew], cB . Inverse[Bnew] . bp - cp[[-1]]}] //
FullSimplify;
(*顯示單形法表格*)
Print[Grid[
Insert[Flatten /@
Transpose[{Flatten[{z, xbnew}],
Insert[Map[Flatten,
Transpose[{Inverse[Bnew] . Ap, Inverse[Bnew],
Inverse[Bnew] . bp}]], znew, 1]}],
Flatten[{Item["BasicVariable",
Background -> Lighter[Yellow, 0.9]], mysymbol, "Solution"}],
1], Frame -> All,
Background -> {{Lighter[Gray, 0.8]}, {Lighter[Yellow, 0.9],
Lighter[Pink, 0.9]}}, ItemStyle -> Directive[FontSize -> 16],
Spacings -> {Table[5, {Length[mysymbol] + 3}], 2}]];
(*返回更新後的參數*)
{-Flatten@{cB . Inverse[Bnew] . Ap - cp[[1 ;; nA]],
cB . Inverse[Bnew]}, Inverse[Bnew] . Ap, Inverse[Bnew],
Inverse[Bnew] . bp, xnbnew, xbnew, cp, Ap, Bp, bp, xnbp, xbp} //
FullSimplify]
Nest[simplexmethod @@ # &,
LPstd[-15 x1 - 20 x2,
myConstrains[{x1 + 2 x2 >= 10, 2 x1 - 3 x2 <= 6, x1 + x2 >= 6}]], 2]
Box-Cox transformation with Mathematica
由 戴忠淵 於 2010年3月23日星期二
上午8:17 發表
y(λ)=(x^λ-1)/λ, 若λ≠0
y(λ)=Log(x), 若λ=0
Box-Cox轉換可以使資料更加符合常態分佈或類似常態分佈的假設,從而提高模型的預測能力和準確性。在實際應用中,通常需要對資料進行多次Box-Cox轉換,並選擇轉換後使資料分佈最接近正態分佈的λ值。當λ > 1時,它可以將正偏的資料變得更加對稱,而當λ < 1時,它可以將負偏的資料變得更加對稱。當λ = 0時,Box-Cox轉換即為對數轉換。
需要注意的是,Box-Cox轉換只適用於正數資料。如果數據中包含負數,則可以使用相關的技術,如Yeo-Johnson轉換。另外,Box-Cox轉換不適用於包含零值的資料。在這種情況下,可以使用對數加一(log(x+1))轉換。
data=Flatten[{#,Exp[#+RandomReal[NormalDistribution[0,1],1]]}]&/@Range[1,8,0.025];
(*畫出資料的散佈圖*)
ListPlot@data
(*計算各Lambda之R-Square*)
mymodel[n_]:=Block[{nlm,ntemp=n,datatemp},
datatemp={First@#,
If[ntemp==0,Log[Last@#],((Last@#)^ntemp-1)/ntemp]}&/@data;
nlm=LinearModelFit[datatemp,x,x];
nlm["RSquared"]
]
(*可發現當Lambda=0時,R-Square最大,所以最適轉換為取Ln*)
{#,mymodel[#]}&/@Range[-3,3,0.25]//TableForm
ListPlot[{#,mymodel[#]}&/@Range[-3,3,0.25]]
(*計算模式*)
myfun[x_]=Limit[(x^\[Lambda]-1)/\[Lambda],
\[Lambda]->SortBy[{#,mymodel[#]}&/@Range[-3,3,0.25],Last][[-1,1]]]
lm=LinearModelFit[{First@#,myfun[Last@#]}&/@data,x,x]
(*畫出轉換後之迴歸線及散佈圖*)
Plot[lm[x],{x,0,8},Epilog->{Red,Point[{First@#,myfun[Last@#]}&/@data]}]