在人臉表情動畫的研究中,大部分工作都是通過採集每一時刻的面部運動資料,並求出該資料在表情基中的線性組合。而這個計算問題是乙個典型的二次規劃問題,如下面的式子所示。
通過上述問題求出的結果(即每個表情基對應的權重)作用與各個表情基上就能實現逼真的表情動畫了,而求解二次規劃的方法有很多,下面重點介紹有效集方法的理論並進行相應的**實現。
一般的二次規劃的形式如下:
下面是matlab實現的有效集解法:
function [x,lamk,exitflag,output]=qpact(h,c,ae,be,ai,bi,x0)
% 功能: 用有效集方法解一般約束二次規劃問題:
% min f(x)=0.5*x'*h*x+c'*x,
% s.t. a'_i*x-b_i=0,(i=1,...,l),
% a'_i*x-b_i>=0,(i=l+1,...,m)
%輸入: x0是初始點, h, c分別是目標函式二次型矩陣和向量;
% ae=(a_1,...,a_l)', be=(b_1,...,b_l)';
% ai=(a_,...,a_m), bi=(b_,...,b_m)'.
%輸出: x是最優解, lambda是對應的乘子向量;output是結構
% 變數, 輸出極小值f(x), 迭代次數k等資訊, exitflag是演算法終止型別
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 初始化
%epsilon 是乙個很小的數,用於輔助不等式判斷,
%如在進行 >= 的判斷時,往往是 x>=b+epsilon,err也是乙個類似的量
epsilon=1.0e-9; err=1.0e-6;
k=0; x=x0; %k為迭代次數,x0為初始點
n=length(x); kmax=1.0e3; %kmax最大迭代次數
ne=length(be); ni=length(bi); lamk=zeros(ne+ni,1);
index=ones(ni,1);
for (i=1:ni)
if(ai(i,:)*x>bi(i)+epsilon), index(i)=0; end
end%演算法主程式
while (k<=kmax)
%求解子問題
aee=[ ];
if(ne>0), aee=ae; end
for(j=1:ni) %不等式約束的個數
if(index(j)>0), aee=[aee; ai(j,:)]; end %將不等式約束和等式約束的稀疏矩陣合併
end% min f(x)=0.5*x'*h*x+c'*x,
% s.t. a'_i*x-b_i=0,(i=1,...,l,l+1,...,m),
% 將不等式約束改為等式約束求解子問題。
gk=h*x+c;
[m1,n1] = size(aee);
[dk,lamk]=qsubp(h,gk,aee,zeros(m1,1)); %計算出極小點dk和拉格朗日乘子向量lamk
if(norm(dk)<=err) %dk為0的時候轉入第二步
y=0.0;
if(length(lamk)>ne)
[y,jk]=min(lamk(ne+1:length(lamk))); %確定有效集中lamda的最小元素。
endif(y>=0)
exitflag=0; %如果每個lamda都大於零,這dk為全域性極小點,
else %否則減去lamda對應的有效集元素,形成新的有效集
exitflag=1;
for(i=1:ni)
if(index(i) & (ne+sum(index(1:i)))==jk) %如果lamda對應的有效集位置為jk,且索引為1,則將索引置0
index(i)=0; break; %確保在之後的計算中,不在計算當前不等式約束。
endend
endk=k+1;
else %如果dk不等於0,轉入第三步
exitflag=1; %確定步長alpha
%求步長
alpha=1.0; tm=1.0;
for(i=1:ni)
if((index(i)==0)&(ai(i,:)*dk<0))
tm1=(bi(i)-ai(i,:)*x)/(ai(i,:)*dk); %alpha的計算見第三步的具體公式
動態規劃演算法學習
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 在上面的數字三角形中尋找一條從頂部到底邊的路徑,使得路徑 上所經過的數字之和最大。路徑上的每一步都只能往左下或右下走。只需要求出這個最大和即可,不必給出具體路徑。解決思路是採用遞迴演算法,每個節點只加上,左下和右下兩個資料,即 int x ...
路徑規劃演算法 路徑規劃演算法學習Day3
2.函式解讀 演算法原理 參考路徑規劃演算法學習day1 路徑規劃演算法學習day1 此方法會結合網路占用法 柵格法來進行實現 總所周知 柵格法生成地圖常規是的自己乙個乙個打,這樣既麻煩還浪費時間 這裡介紹幾種方法 way1 在命令框中碼 map rand k 0.7 k代表多少維地圖 way2 在...
路徑規劃演算法學習Day1
解決最短路徑問題的演算法有很多,dijkstra演算法是其中最為有效的一種。它是於1959年荷蘭計算機科學家edsger dijkstra提出的 能夠解決 單結點 所有結點 間的最短路徑問題。首先以某一結點 源結點 作為出發點,在與其相連且尚未被加入的結點裡,選擇加入離出發點距離最短的結點,並且通過...