演算法難點
❶ 人臉識別演算法的難點
人臉識別演算法研究已久,在背景簡單的情形下,大部分演算法都能很好的處理。但是,人臉識別的應用范圍頗廣,僅是簡單圖像測試,是遠遠不能滿足現實需求的。所以人臉識別演算法還是存在很多的難點。
光照
光照問題是機器視覺中的老問題,在人臉識別中的表現尤為明顯,演算法未能達到完美使用的程度。
姿態
與光照問題類似,姿態問題也是人臉識別研究中需要解決的一個技術難點。針對姿態的研究相對比較少,多數的人臉識別演算法主要是針對正面,或接近正面的人臉圖像,當發生俯仰或者左右側而比較厲害的情況下,人臉識別演算法的識別率也將會急劇下降。
遮擋
對於非配合情況下的人臉圖像採集,遮擋問題是一個非常嚴重的問題,特別是在監控環境下,往往被監控對象都會帶著眼鏡﹑帽子等飾物,使得被採集出來的人臉圖像有可能不完整,從而影響了後面的特徵提取與識別,甚至會導致人臉識別演算法的失效。
年齡變化
隨著年齡的變化,面部外觀也在變化,特別是對於青少年,這種變化更加的明顯。對於不同的年齡段,人臉識別演算法的識別率也不同。
圖像質量
人臉圖像的來源可能多種多樣,由於採集設備的不同,得到的人臉圖像質量也不同,特別是對於那些低解析度﹑雜訊大﹑質量差的人臉圖像如何進行有效的人臉識別是個需要關注的問題。同樣的,對於高分辨圖像,對人臉識別演算法的影響也需要進一步研究。
樣本缺乏
基於統計學習的人臉識別演算法是人臉識別領域中的主流演算法,但是統計學習方法需要大量的培訓。由於人臉圖像在高維空間中的分布是一個不規則的流行分布,能得到的樣本只是對人臉圖像空間中的一個極小部分的采樣,如何解決小樣本下的統計學習問題有待進一步的研究。
海量數據
傳統人臉識別演算法如PCA、LDA等在小規模數據中可以很容易進行訓練學習。但是對於海量數據,這些方法其訓練過程難以進行,甚至有可能崩潰。
大規模人臉識別
隨著人臉資料庫規模的增長,人臉演算法的性能將呈現下降。
❷ 各種編程語言的難點
我只能跟你詳細說一說pascal的難點,但C和C++那些沒有怎麼學過,不太會,pascal的難點個人覺得第一個初學者在數組方面可能不太懂這個「下標」的意思,但看多幾遍就懂了,第二個就是接觸了過程和函數之後的遞歸和遞推,其實遞推就是干某件事用同樣的方法去做,找到一個遞推的公式就行了,之後的遞歸是很難搞懂的,必須去一遍一遍的摸索,才能搞懂,而且遞歸必須要很多的練習才能搞懂,搞懂遞歸之後就是指針與鏈表了,這個指針的用處不是很大,但鏈表的用處就大了,到時你學的時候自然會明白。當然還有必不可少的貪心演算法,這也是一大難點,幾乎現在的NOIP或者是NOI比賽絕大部分的題目都是考到貪心的,{所以很多人都說貪心應該就是計算機編程的用處}。
另外還有二叉樹啊,動態規劃啊,圖論演算法等等。。。。這些都是pascal編程的難點,學pascal不能急,必須一步一步來,學完這些之後在學一些fp提供的牛逼函數,例如調用math,調用crt等等。。。。而C和C++這些也都是這樣的,並不會說C++就還會多了一些什麼高級演算法,這些都是差不多的。只不過少C++更加的開放,簡單罷了。{但並不易懂,覺沒有pascal易懂。}
最後祝你能學好編程!
❸ 和演算法上有哪些技術原理及難點
RSA加密演算法是一種典型的非對稱加密演算法,它基於大數的因式分解數學難題,它也是應用最廣泛的非對稱加密演算法,於1978年由美國麻省理工學院(MIT)的三位學著:Ron Rivest、Adi Shamir 和 Leonard Adleman 共同提出。 它的原理較為簡單,假設有消息發送方A和消息接收方B,通過下面的幾個步驟,就可以完成消息的加密傳遞:消息發送方A在本地構建密鑰對,公鑰和私鑰;消息發送方A將產生的公鑰發送給消息接收方B;B向A發送數據時,通過公鑰進行加密,A接收到數據後通過私鑰進行解密,完成一次通信;反之,A向B發送數據時,通過私鑰對數據進行加密,B接收到數據後通過公鑰進行解密。 由於公鑰是消息發送方A暴露給消息接收方B的,所以這種方式也存在一定的安全隱患,如果公鑰在數據傳輸過程中泄漏,則A通過私鑰加密的數據就可能被解密。 如果要建立更安全的加密消息傳遞模型,需要消息發送方和消息接收方各構建一套密鑰對,並分別將各自的公鑰暴露給對方,在進行消息傳遞時,A通過B的公鑰對數據加密,B接收到消息通過B的私鑰進行解密,反之,B通過A的公鑰進行加密,A接收到消息後通過A的私鑰進行解密。 當然,這種方式可能存在數據傳遞被模擬的隱患,但可以通過數字簽名等技術進行安全性的進一步提升。由於存在多次的非對稱加解密,這種方式帶來的效率問題也更加嚴重。
❹ 廣度優先搜索有什麼難點
廣度優先搜索難點在於每一種演算法的不同,樹的遍歷。
擴展知識:
廣度優先搜索演算法又譯作寬度優先搜索,或橫向優先搜索,是一種圖形搜索演算法。簡單的說,BFS是從根節點開始,沿著樹的寬度遍歷樹的節點。如果所有節點均被訪問,則演算法中止。廣度優先搜索的實現一般採用open-closed表。
廣度優先搜索演算法主要有四個特性:
空間復雜度:由於對空間的大量需求,因此BFS並不適合解非常大的問題,對於類似的問題,應用IDDFS已達節省空間的效果。
時間復雜度:最差情形下,BFS必須查找所有到可能節點的所有路徑。
完全性:廣度優先搜索演算法具有完全性。這意指無論圖形的種類如何,只要目標存在,則BFS一定會找到。然而,若目標不存在,且圖為無限大,則BFS將不收斂(不會結束)。
最佳解:若所有邊的長度相等,廣度優先搜索演算法是最佳解——亦即它找到的第一個解,距離根節點的邊數目一定最少;但對一般的圖來說,BFS並不一定回傳最佳解。
❺ 演算法分析的兩個主要方面是什麼
空間復雜性和時間復雜性。
時間復雜度和空間復雜度是衡量演算法好差的重要指標,正確性和簡潔性、可讀性和可運行性是從軟體工程角度要求系統實現的目標。
一個演算法應包含有限的操作步驟,而不能是無限的,事實上有窮性往往是在合理的范圍之內,如果讓計算機執行一個歷時1000年才結束的演算法,這雖然是有窮的,但超過了合理的限度,不能將其視為有效演算法。
演算法分析注意事項:
循環結構是演算法教學的重點和難點,要注意分散此難點,做到循序漸進,逐層深入,例如在教演算法含義時先滲透一點循環結構的知識,在教演算法3 種基本結構時可先給出循環結構的一些簡單的例子,到了教條件語句和循環語句時再逐步加深。
輸入數據的長度(通常考慮任意大的輸入,沒有上界),值域通常是執行步驟數量(時間復雜度)或者存儲器位置數量(空間復雜度)。演算法分析是計算復雜度理論的重要組成部分。
❻ 高中數學的演算法,程序框圖
其實你把課好好聽、作業認真完成都搞懂就可以了,不要這么緊張。我經驗是最後考試題目非常簡單。要注重培養邏輯思維,模仿計算機按步驟辦事計算。有問題再問我好了。
附上:對高中數學中演算法的幾點認識(網上找的,意義不大)
演算法屬於新教材的新增內容,筆者結合自己的教學體會,談談對演算法的理解和認識,供各位同仁參考:
1、演算法的內容
(1)自然語言(2)程序框圖(3)演算法語句,其中,在每種語言中有各自的結構,如:順序結構、循環結構、條件結構等。
2、演算法在高中課程中的地位:
演算法內容的設計分為兩部分。
一部分主要介紹演算法的基礎知識,可以稱作演算法的「三基」:演算法基本思想,演算法基本結構,演算法基本語句。通過一些具體的案例介紹演算法的基本思想,使學生了解:為了解決一個問題,設計出解決問題的系列步驟,任何人實施這些步驟就可以解決問題,這就是解決問題的一個演算法。這是對演算法的一種廣義的理解。對演算法的理解,更多地是與計算機聯系在一起,計算機可以完成這些步驟。
演算法的基本結構一般有三種:順序結構,分叉結構,循環結構。前兩種結構很容易理解,循環結構稍微有點難,這里用到函數思想,難在理解反映循環過程的循環變數。在教學過程中,一定要通過具體的案例,結合具體的情境引入概念,會使問題變得很簡單。
介紹演算法語句的時候,要區分演算法語言和基本的演算法語句。我們知道,現在使用的演算法語言是很多的,例如,basic 語言,q-basic 語言,c-語言,等等。在高中的數學課程中,不要求介紹演算法語言,僅僅需要了解基本語句,例如,輸入語句,輸出語句,賦值語句,條件語句,循環語句,等等。在不同的語言中,這些語句的表示可能不一樣,數學課程要求採用公認的統一表示,稱為偽代碼。很容易把偽代碼翻譯成任何一種演算法語言。
描述演算法有三種語言:自然語言、框圖語言、基本演算法語句。
演算法的另一部分設計,是把演算法的思想融入相關數學內容中。實際上,演算法思想是貫穿在高中數學課程始終的基本思想。例如,二分法求方程的解;點到直線的距離、點到平面的距離、直線到直線距離;立體幾何性質定理的證明過程;一元二次不等式;線性規劃;等等內容中,都運用了演算法思想。
用演算法思想學習和認識數學對於提高數學素養是很有用的,希望老師予以重視。
3、理解賦值語句:
賦值是演算法中的難點之一,理解賦值對於理解演算法是非常重要的。
賦值就是把數值賦予給定的變數。例如,a:=5,就表示變數a被賦予的值是5,即a=5,這個被賦值的變數可以與其他的值進行運算。對於被賦值的變數a,還可以賦予其它的值取代原來的值。我們可以用磁帶錄音來比喻賦值,在我們錄音時,是把磁帶上舊的錄音材料沖掉之後,才能把新的錄音材料載入上去。同樣的道理,我們這里的賦值也是先把原來的值清零之後,再把新的值賦上去。下面我們通過一個例子來說明如何設置變數和給變數賦值。
例:設計一個演算法,從4個不同的數中找出最大數。
解:記這5個不同的數分別為a1,a2,a3,a4,a5,演算法步驟如下:
1、比較a1與a2將較大的數記作b.
(在這一步中,b表示的是前2個數中的最大數)
2、再將b與a3進行比較,將較大的數記作b.
(執行完這一步後,b的值就是前3個數中的最大數)
3、再將b與a4進行比較,將較大的數記作b.
(執行完這一步後,b的值就是前4個數中的最大數)
4、輸出b,b的值即為所求得最大數。
分析:上述演算法的4個步驟中,每步都要與上一步中得到的最大數b進行比較,得出新的最大數。b可以取不同的值,b就稱之為變數。在第1步到第3步的演算法過程中,我們都把比較後的較大數記作b,即把值賦予了b,這個過程就是賦值的過程,這個過程有兩個功能,第一,我們可以不斷地對b的值進行改變,即把數值放入b中;第二,b的值每變化一次都是為下一步的比較服務。
4、函數在循環結構中的作用:
(1)循環結構是演算法的一種基本結構。
例如,設計演算法,輸出1000以內能被3和5整除的所有正整數。解決這個問題,我們首先要引入變數a表示待輸出的數,則a=15n (n=1,2,3,…,66).n從n從1變到66,反復輸出a,就能輸出1000以內的所有能被3和5整除的正整數。像這樣的演算法結構稱為循環結構,其中反復執行的部分稱為循環體。變數n控制著循環的開始和結束,稱為循環變數。
(2)循環結構是理解演算法的另一個難點,難點在於對於循環變數的理解。
循環結構中的循環變數分為兩種形式,一種是控制循環次數的變數,例如,輸出1000以內能被3和5整除的所有正整數這個循環結構中,n就是控制循環次數的循環變數。另一種是控制結果精確度的變數,例如用二分法演算法求方程f(x)=0在區間[0,1]上的一個近似解的流程圖,要求精確度為。在這個演算法過程中,精確度就是控制結果精確度的循環變數。
循環變數使得循環體得以「循環」,循環變數控制了循環的「開始」和「結束」,是刻畫循環結構的關鍵。
以上幾點是對演算法的粗淺認識,不當之處,請批評指正!
❼ 演算法與建模的困難在於數學還是技術,或是感想
以語音識別的演算法及建模為例,來看看會遇到哪些現實難點。
語音如一段很短的樂曲。
音高可以變化,D調上不去就改C調,
絕對音高變化了,而相對音高依然穩定不變。
依然可以判斷出,這兩段音高不同的樂曲,確是同一段樂曲。
音色也可以變化,小提琴《梁祝》與電子琴《梁祝》,音色差別很大,
但依然可以得出判斷:是同一段樂曲。
音量變化更不影響判斷其是同。
語音識別的演算法及建模所依賴的,就是這個相對性現象。
充分理解後,就叫做音階相對性原理。
音階相對關系不變,固定了樂曲。並可實現重復。
語音也如此。
理解了這個之後,就有了解決語音識別問題的大致方向——
1、找到機器可識別的最小的音階。
2、發現語音中固定的音階相對變化順序。
3、發現音階的三維現象。
4、音階三維數碼化。
這樣就實現了固定其音。
上述4條顯然不需要很高深的數學水平。
高中數學做演算法就足夠了。數學不是難點。
技術,肯定需要。聲AD轉碼需要探索出適應新演算法的新技術。但這並不很難。
感想?是的,需要感想。
思考上述四條語音問題方向應得出如下感想:
必須對聲音開始到結束的全部詳細過程,有清晰的數碼化認識。
這就是最大的難點。
❽ 算術表達式求值演算法實現的難點剖析
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#define TRUE 1
#define FALSE 0
#define Stack_Size 50
char ops[7]={'+','-','*','/','(',')','#'}; /*運算符數組*/
int cmp[7][7]={{2,2,1,1,1,2,2}, /*用來進行比較運算符優先順序的矩陣,3代表'=',2代表'>',1代表'<',0代表不可比*/
{2,2,1,1,1,2,2},
{2,2,2,2,1,2,2},
{2,2,2,2,1,2,2},
{1,1,1,1,1,3,0},
{2,2,2,2,0,2,2},
{1,1,1,1,1,0,3}};
typedef struct
{
char elem[Stack_Size];
int top;
}SeqStack; /*運算符棧的定義*/
typedef struct
{
int elem[Stack_Size];
int top;
}nSeqStack; /* 運算數棧的定義*/
void InitStack(SeqStack *S) /*初始化運算符棧*/
{
S->top =-1;
}
void InitStackn(nSeqStack *S) /*初始化運算數棧*/
{
S->top =-1;
}
int IsEmpty(SeqStack *S) /*判斷棧S為空棧時返回值為真,反之為假*/
{
return(S->top==-1?TRUE:FALSE);
}
int IsEmptyn(nSeqStack *S) /*判斷棧S為空棧時返回值為真,反之為假*/
{
return(S->top==-1?TRUE:FALSE);
}
/*判棧滿*/
int IsFull(SeqStack *S) /*判斷棧S為滿棧時返回值為真,反之為假*/
{
return(S->top==Stack_Size-1?TRUE:FALSE);
}
int IsFulln(nSeqStack *S) /*判斷棧S為滿棧時返回值為真,反之為假*/
{
return(S->top==Stack_Size-1?TRUE:FALSE);
}
int Push(SeqStack *S, char x) /*運算符棧入棧函數*/
{
if (S->top==Stack_Size-1)
{
printf("Stack is full!\n");
return FALSE;
}
else
{
S->top++;
S->elem[S->top]=x;
return TRUE;
}
}
int Pushn(nSeqStack *S, int x) /*運算數棧入棧函數*/
{
if (S->top==Stack_Size-1)
{
printf("Stack is full!\n");
return FALSE;
}
else
{
S->top++;
S->elem[S->top]=x;
return TRUE;
}
}
int Pop(SeqStack *S, char *x) /*運算符棧出棧函數*/
{
if (S->top==-1)
{
printf("運算符棧空!\n");
return FALSE;
}
else
{
*x=S->elem[S->top];
S->top--;
return TRUE;
}
}
int Popn(nSeqStack *S, int *x) /*運算數棧出棧函數*/
{
if (S->top==-1)
{
printf("運算符棧空!\n");
return FALSE;
}
else
{
*x=S->elem[S->top];
S->top--;
return TRUE;
}
}
char GetTop(SeqStack *S) /*運算符棧取棧頂元素函數*/
{
if (S->top ==-1)
{
printf("運算符棧為空!\n");
return FALSE;
}
else
{
return (S->elem[S->top]);
}
}
int GetTopn(nSeqStack *S) /*運算數棧取棧頂元素函數*/
{
if (S->top ==-1)
{
printf("運算符棧為空!\n");
return FALSE;
}
else
{
return (S->elem[S->top]);
}
}
int Isoperator(char ch) /*判斷輸入字元是否為運算符函數,是返回TRUE,不是返回FALSE*/
{
int i;
for (i=0;i<7;i++)
{
if(ch==ops[i])
return TRUE;
}
return FALSE;
}
/*
int isvariable(char ch)
{ if (ch>='a'ch<='z')
return true;
else
return false;
}*/
char Compare(char ch1, char ch2) /*比較運算符優先順序函數*/
{
int i,m,n;
char pri; /*保存優先順序比較後的結果'>'、'<'、'='*/
int priority; /*優先順序比較矩陣中的結果*/
for(i=0;i<7;i++) /*找到相比較的兩個運算符在比較矩陣里的相對位置*/
{
if(ch1==ops[i])
m=i;
if (ch2==ops[i])
n=i;
}
priority = cmp[m][n];
switch(priority)
{
case 1:
pri='<';
break;
case 2:
pri='>';
break;
case 3:
pri='=';
break;
case 0:
pri='$';
printf("表達式錯誤!\n");
break;
}
return pri;
}
int Execute(int a, char op, int b) /*運算函數*/
{
int result;
switch(op)
{
case '+':
result=a+b;
break;
case '-':
result=a-b;
break;
case '*':
result=a*b;
break;
case '/':
result=a/b;
break;
}
return result;
}
int ExpEvaluation()
/*讀入一個簡單算術表達式並計算其值。optr和operand分別為運算符棧和運算數棧,OPS為運算符集合*/
{
int a,b,v,temp;
char ch,op;
char *str;
int i=0;
SeqStack optr; /*運算符棧*/
nSeqStack operand; /*運算數棧*/
InitStack(optr);
InitStackn(operand);
Push(optr,'#');
printf("請輸入表達式(以#結束):\n"); /*表達式輸入*/
str =(char *)malloc(50*sizeof(char));
gets(str); /*取得一行表達式至字元串中*/
ch=str[i];
i++;
while(ch!='#'||GetTop(optr)!='#')
{
if(!Isoperator(ch))
{
temp=ch-'0'; /*將字元轉換為十進制數*/
ch=str[i];
i++;
while(!Isoperator(ch))
{
temp=temp*10 + ch-'0'; /*將逐個讀入運算數的各位轉化為十進制數*/
ch=str[i];
i++;
}
Pushn(operand,temp);
}
else
{
switch(Compare(GetTop(optr),ch))
{
case '<':
Push(optr,ch);
ch=str[i];
i++;
break;
case '=':
Pop(optr,op);
ch=str[i];
i++;
break;
case '>':
Pop(optr,op);
Popn(operand,b);
Popn(operand,a);
v=Execute(a,op,b); /* 對a和b進行op運算 */
Pushn(operand,v);
break;
}
}
}
v=GetTopn(operand);
return v;
}
void main() /*主函數*/
{
int result;
result=ExpEvaluation();
printf("\n表達式結果是%d\n",result);
}
❾ 闡述提高場景文字檢測演算法性能的難點
1、圖像輸入、預處理:
圖像輸入:對於不同的圖像格式,有著不同的存儲格式,不同的壓縮方式。預處理:主要包括二值化,雜訊去除,傾斜較正等
2、二值化:
對攝像頭拍攝的圖片,大多數是彩色圖像,彩色圖像所含信息量巨大,對於圖片的內容,我們可以簡單的分為前景與背景,為了讓計算機更快的,更好的識別文字,我們需要先對彩色圖進行處理,使圖片只前景信息與背景信息,可以簡單的定義前景信息為黑色,背景信息為白色,這就是二值化圖了。
3、雜訊去除:
對於不同的文檔,我們對燥聲的定義可以不同,根據燥聲的特徵進行去燥,就叫做雜訊去除
4、傾斜較正:
由於一般用戶,在拍照文檔時,都比較隨意,因此拍照出來的圖片不可避免的產生傾斜,這就需要文字識別軟體進行較正。
版面分析:5、將文檔圖片分段落,分行的過程就叫做版面分析,由於實際文檔的多樣性,復雜性,因此,目前還沒有一個固定的,最優的切割模型。
6、字元切割:
由於拍照條件的限制,經常造成字元粘連,斷筆,因此極大限制了識別系統的性能,這就需要文字識別軟體有字元切割功能。
7、字元識別:
這一研究,已經是很早的事情了,比較早有模板匹配,後來以特徵提取為主,由於文字的位移,筆畫的粗細,斷筆,粘連,旋轉等因素的影響,極大影響特徵的提取的難度。
8、版面恢復:
人們希望識別後的文字,仍然像原文檔圖片那樣排列著,段落不變,位置不變,順序不變,的輸出到word文檔,pdf文檔等,這一過程就叫做版面恢復。
9、後處理、校對:
根據特定的語言上下文的關系,對識別結果進行較正,就是後處理。
開發一個OCR文字識別軟體[2]系統,其目的很簡單,只是要把影像作一個轉換,使影像內的圖形繼續保存、有表格則表格內資料及影像內的文字,一律變成計算機文字,使能達到影像資料的儲存量減少、識別出的文字可再使用及分析,當然也可節省因鍵盤輸入的人力與時間。從影像到結果輸出,須經過影像輸入、影像前處理、文字特徵抽取、比對識別、最後經人工校正將認錯的文字更正,將結果輸出。