遺傳演算法在自動組卷中的應用
遺傳演算法
遺傳演算法(Genetic Algorithm)是一種模擬自然界的進化規律-優勝劣汰演化來的隨機搜尋演算法,其在解決多種約束條件下的最優解這類問題上具有優秀的表現.
1. 基本概念
在遺傳演算法中有幾個基本的概念:基因、個體、種群和進化.基因是個體的表現,不同個體的基因序列不同;個體是指單個的生命,個體是組成種群的基礎;而進化的基本單位是種群,一個種群裡面有多個個體;進化是指一個種群進過優勝劣汰的自然選擇後,產生一個新的種群的過程,理論上進化會產生更優秀的種群.
2. 演算法流程
一個傳統的遺傳演算法由以下幾個組成部分:
- 初始化. 隨機生成一個規模為N的種群,設定最大進化次數以及停止進化條件.
- 計算適應度. 適應度被用來評價個體的質量,且適應度是唯一評判因子.計算種群中每個個體的適應度,得到最優秀的個體.
- 選擇. 選擇是用來得到一些優秀的個體來產生下一代.選擇演算法的好壞至關重要,因為在一定程度上選擇會影響種群的進化方向.常用的選擇演算法有:隨機抽取、競標賽選擇以及輪盤賭模擬法等等.
- 交叉. 交叉是兩個個體繁衍下一代的過程,實際上是子代獲取父親和母親的部分基因,即基因重組.常用的交叉方法有:單點交叉、多點交叉等.
- 變異. 變異即模擬突變過程.通過變異,種群中個體變得多樣化.但是變異是有一個概率的.
經典的遺傳演算法的流程圖如下所示:
3. java實現
為了防止進化方向出現偏差,在本演算法中採用精英主義,即每次進化都保留上一代種群中最優秀的個體。
- 個體適應度:通過比較個體與期望值的相同位置上的基因,相同則適應度加1
- 選擇策略:隨機產生一個淘汰陣列,選擇淘汰陣列中的最優秀個體作為選擇結果,即模擬優勝劣汰的過程
- 交叉策略:對於個體的每個基因,產生一個隨機數,如果隨機數小於交叉概率,則繼承父親該位置的基因,否則繼承母親的該位置的基因
- 變異策略:個體的基因序列上的每個基因都有變異的機會,如果隨機概率大於變異概率,則進行基因突變,本例中的突變策略是:隨機產生一個0或者1
計算適應度
/**
* 通過和solution比較 ,計算個體的適應值
* @param individual 待比較的個體
* @return 返回適應度
*/
public static int getFitness(Individual individual) {
int fitness = 0;
for (int i = 0; i < individual.size() && i < solution.length; i++) {
if (individual.getGene(i) == solution[i]) {
fitness++;
}
}
return fitness;
}
選擇運算元
/**
* 隨機選擇一個較優秀的個體。用於進行交叉
* @param pop 種群
* @return
*/
private static Individual tournamentSelection(Population pop) {
Population tournamentPop = new Population(tournamentSize, false);
// 隨機選擇 tournamentSize 個放入 tournamentPop 中
for (int i = 0; i < tournamentSize; i++) {
int randomId = (int) (Math.random() * pop.size());
tournamentPop.saveIndividual(i, pop.getIndividual(randomId));
}
// 找到淘汰陣列中最優秀的
Individual fittest = tournamentPop.getFittest();
return fittest;
}
交叉運算元
/**
* 兩個個體交叉產生下一代
* @param indiv1 父親
* @param indiv2 母親
* @return 後代
*/
private static Individual crossover(Individual indiv1, Individual indiv2) {
Individual newSol = new Individual();
// 隨機的從兩個個體中選擇
for (int i = 0; i < indiv1.size(); i++) {
if (Math.random() <= uniformRate) {
newSol.setGene(i, indiv1.getGene(i));
} else {
newSol.setGene(i, indiv2.getGene(i));
}
}
return newSol;
}
變異運算元
/**
* 突變個體。突變的概率為 mutationRate
* @param indiv 待突變的個體
*/
private static void mutate(Individual indiv) {
for (int i = 0; i < indiv.size(); i++) {
if (Math.random() <= mutationRate) {
// 生成隨機的 0 或 1
byte gene = (byte) Math.round(Math.random());
indiv.setGene(i, gene);
}
}
}
4. 測試結果
測試結果如下圖
遺傳演算法與自動組卷
隨著軟體和硬體技術的發展,線上考試系統正在逐漸取代傳統的線下筆試。對於一個線上考試系統而言,考試試卷的質量很大程度上代表著該系統的質量,試卷是否包含足夠多的題型、是否包含指定的知識點以及試卷整體的難度係數是否合適等等,這些都能作為評價一個線上測評系統的指標.如果單純的根據組卷規則直接從資料庫中獲取一定數量的試題組成一套試卷,由於只獲取一次,並不能保證這樣的組卷結果是一個合適的結果,而且可以肯定的是,這樣得到的結果基本不會是一個優秀的解.顯而易見,我們需要一個優秀的自動組卷演算法,遺傳演算法就非常適合解決自動組卷的問題,其具有自進化、並行執行等特點
1. 對遺傳演算法的改進
使用傳統的遺傳演算法進行組卷時會出現一些偏差,進化的結果不是非常理想.具體表現為:進化方向出現偏差、搜尋後期效率低、容易陷入區域性最優解等問題.針對這些問題,本系統對傳統的遺傳演算法做了一些改進,具體表現為:使用精英主義模式(即每次進化都保留上一代種群的最優解)、實數編碼以及選擇運算元的優化.
1.1 染色體編碼方式的改進
染色體編碼是遺傳演算法首先要解決的問題,是將個體的特徵抽象為一套編碼方案.在傳統的遺傳演算法解決方案中,二進位制編碼使用的最多,就本系統而言,二進位制編碼形成的基因序列為整個題庫,這種方案不是很合適,因為二進位制編碼按照題庫中試題的相對順序將題庫編碼成一個01字串,1代表試題出現,0代表沒有顯然這樣的編碼規模太大,對於一個優秀的題庫而言,十萬的試題總量是很常見的,對於一個長度為十萬的字串進行編碼和解碼顯然太繁瑣. 經過查閱資料,於是決定採用實數編碼作為替代,將試題的id作為基因,試卷和染色體建立對映關係,同一型別的試題放在一起.比如,要組一套java考試試卷,題目總數為15:填空3道,單選10道,主觀題2道.那麼進行實數編碼後,其基因序列分佈表現為:
1.2 初始化種群設計
初始化試卷時不採取完全隨機的方式.通過分析不難發現,組卷主要有題型、數量、總分、知識點和難度係數這五個約束條件,在初始化種群的時候,我們可以根據組卷規則隨機產生指定數量的題型,這樣在一開始種群中的個體就滿足了題型、數量和總分的約束,使約束條件從5個減少為2個:知識點和難度係數.這樣演算法的迭代次數被減少,收斂也將加快.
1.3 適應度函式設計
在遺傳演算法中,適應度是評價種群中個體的優劣的唯一指標,適應度可以影響種群的進化方向.由於在初始化時,種群中個體已經滿足了題型、數量和總分這三個約束條件,所以個體的適應度只與知識點和難度係數有關.
試卷的難度係數計算公式為:
n是組卷規則要求的題目總數,Ti,Ki分別是第i題的難度係數和分數.
本例中使用知識點覆蓋率來評價知識點.即一套試卷要求包含N個知識點,而某個體中包含的知識點數目為M(去重後的結果,M<=N),那麼該個體的知識點覆蓋率為:M/N. 因此,適應度函式為:
其中,M/N為知識點覆蓋率;EP為使用者輸入的整體期望難度,P為整體實際難度;知識點權重用t1表示,難度係數權重用t2表示.
1.4 選擇運算元與交叉運算元的改進
本例中的選擇策略為:指定一個淘汰陣列的大小(筆者使用的是5),從原種群中隨機挑選個體組成一個淘汰種群,將淘汰種群中的最優個體作為選擇運算元的結果.
交叉運算元實際上是染色體的重組.本系統中採用的交叉策略為:在(0,N)之間隨機產生兩個整數n1,n2,父親基因序列上n1到n2之間的基因全部遺傳給子代,母親基因序列上的n1到n2之外的基因遺傳給子代,但是要確保基因不重複,如果出現重複(實驗證明有較大的概率出現重複),那麼從題庫中挑選一道與重複題的題型相同、分值相同且包含的知識點相同的試題遺傳給子代.所有的遺傳都要保證基因在染色體上的相對位置不變.
1.5 變異運算元的改進
基因變異的出現增加了種群的多樣性.在本系統中,每個個體的每個基因都有變異的機會,如果隨機概率小於變異概率,那麼基因就可以突變.突變基因的原則為:與原題的同題型、同分數且同知識點的試題.有研究表明,對於變異概率的選擇,在0.1-0.001之間最佳,本例中選取了0.085作為變異概率.
1.6 組卷規則
組卷規則是初始化種群的依賴。組卷規則由使用者指定,規定了使用者期望的試卷的條件:試卷總分、包含的題型與數量、期望難度係數、期望覆蓋的知識點。在本例中將組卷規則封裝為一個JavaBean
2. java實現
2.1 試卷個體
個體,即試卷.本例中將試卷個體抽象成一個JavaBean,其有id,適應度、知識點覆蓋率、難度係數、總分、以及個體包含的試題集合這6個屬性,以及計算知識點覆蓋率和適應度這幾個方法.在計算適應度的時候,知識點權重為0.20,難度係數權重為0.80.
/**
* 計算試卷總分
*
* @return
*/
public double getTotalScore() {
if (totalScore == 0) {
double total = 0;
for (QuestionBean question : questionList) {
total += question.getScore();
}
totalScore = total;
}
return totalScore;
}
/**
* 計算試卷個體難度係數 計算公式: 每題難度*分數求和除總分
*
* @return
*/
public double getDifficulty() {
if (difficulty == 0) {
double _difficulty = 0;
for (QuestionBean question : questionList) {
_difficulty += question.getScore() * question.getDifficulty();
}
difficulty = _difficulty / getTotalScore();
}
return difficulty;
}
/**
* 計算知識點覆蓋率 公式為:個體包含的知識點/期望包含的知識點
*
* @param rule
*/
public void setKpCoverage(RuleBean rule) {
if (kPCoverage == 0) {
Set<String> result = new HashSet<String>();
result.addAll(rule.getPointIds());
Set<String> another = questionList.stream().map(questionBean -> String.valueOf(questionBean.getPointId())).collect(Collectors.toSet());
// 交集操作
result.retainAll(another);
kPCoverage = result.size() / rule.getPointIds().size();
}
}
/**
* 計算個體適應度 公式為:f=1-(1-M/N)*f1-|EP-P|*f2
* 其中M/N為知識點覆蓋率,EP為期望難度係數,P為種群個體難度係數,f1為知識點分佈的權重
* ,f2為難度係數所佔權重。當f1=0時退化為只限制試題難度係數,當f2=0時退化為只限制知識點分佈
*
* @param rule 組卷規則
* @param f1 知識點分佈的權重
* @param f2 難度係數的權重
*/
public void setAdaptationDegree(RuleBean rule, double f1, double f2) {
if (adaptationDegree == 0) {
adaptationDegree = 1 - (1 - getkPCoverage()) * f1 - Math.abs(rule.getDifficulty() - getDifficulty()) * f2;
}
}
public boolean containsQuestion(QuestionBean question) {
if (question == null) {
for (int i = 0; i < questionList.size(); i++) {
if (questionList.get(i) == null) {
return true;
}
}
} else {
for (QuestionBean aQuestionList : questionList) {
if (aQuestionList != null) {
if (aQuestionList.equals(question)) {
return true;
}
}
}
}
return false;
}
2.2 種群初始化
種群初始化。將種群抽象為一個Java類Population,其有初始化種群、獲取最優個體的方法,關鍵程式碼如下
/**
* 初始種群
*
* @param populationSize 種群規模
* @param initFlag 初始化標誌 true-初始化
* @param rule 規則bean
*/
public Population(int populationSize, boolean initFlag, RuleBean rule) {
papers = new Paper[populationSize];
if (initFlag) {
Paper paper;
Random random = new Random();
for (int i = 0; i < populationSize; i++) {
paper = new Paper();
paper.setId(i + 1);
while (paper.getTotalScore() != rule.getTotalMark()) {
paper.getQuestionList().clear();
String idString = rule.getPointIds().toString();
// 單選題
if (rule.getSingleNum() > 0) {
generateQuestion(1, random, rule.getSingleNum(), rule.getSingleScore(), idString,
"單選題數量不夠,組卷失敗", paper);
}
// 填空題
if (rule.getCompleteNum() > 0) {
generateQuestion(2, random, rule.getCompleteNum(), rule.getCompleteScore(), idString,
"填空題數量不夠,組卷失敗", paper);
}
// 主觀題
if (rule.getSubjectiveNum() > 0) {
generateQuestion(3, random, rule.getSubjectiveNum(), rule.getSubjectiveScore(), idString,
"主觀題數量不夠,組卷失敗", paper);
}
}
// 計算試卷知識點覆蓋率
paper.setKpCoverage(rule);
// 計算試卷適應度
paper.setAdaptationDegree(rule, Global.KP_WEIGHT, Global.DIFFCULTY_WEIGHt);
papers[i] = paper;
}
}
}
private void generateQuestion(int type, Random random, int qustionNum, double score, String idString,
String errorMsg, Paper paper) {
QuestionBean[] singleArray = QuestionService.getQuestionArray(type, idString
.substring(1, idString.indexOf("]")));
if (singleArray.length < qustionNum) {
log.error(errorMsg);
return;
}
QuestionBean tmpQuestion;
for (int j = 0; j < qustionNum; j++) {
int index = random.nextInt(singleArray.length - j);
// 初始化分數
singleArray[index].setScore(score);
paper.addQuestion(singleArray[index]);
// 保證不會重複新增試題
tmpQuestion = singleArray[singleArray.length - j - 1];
singleArray[singleArray.length - j - 1] = singleArray[index];
singleArray[index] = tmpQuestion;
}
}
2.3 選擇運算元與交叉運算元的實現
選擇運算元的實現:
/**
* 選擇運算元
*
* @param population
*/
private static Paper select(Population population) {
Population pop = new Population(tournamentSize);
for (int i = 0; i < tournamentSize; i++) {
pop.setPaper(i, population.getPaper((int) (Math.random() * population.getLength())));
}
return pop.getFitness();
}
交叉運算元的實現.本系統實現的運算元為兩點交叉,在演算法的實現過程中需要保證子代中不出現相同的試題.關鍵程式碼如下:
/**
* 交叉運算元
*
* @param parent1
* @param parent2
* @return
*/
public static Paper crossover(Paper parent1, Paper parent2, RuleBean rule) {
Paper child = new Paper(parent1.getQuestionSize());
int s1 = (int) (Math.random() * parent1.getQuestionSize());
int s2 = (int) (Math.random() * parent1.getQuestionSize());
// parent1的startPos endPos之間的序列,會被遺傳到下一代
int startPos = s1 < s2 ? s1 : s2;
int endPos = s1 > s2 ? s1 : s2;
for (int i = startPos; i < endPos; i++) {
child.saveQuestion(i, parent1.getQuestion(i));
}
// 繼承parent2中未被child繼承的question
// 防止出現重複的元素
String idString = rule.getPointIds().toString();
for (int i = 0; i < startPos; i++) {
if (!child.containsQuestion(parent2.getQuestion(i))) {
child.saveQuestion(i, parent2.getQuestion(i));
} else {
int type = getTypeByIndex(i, rule);
QuestionBean[] singleArray = QuestionService.getQuestionArray(type, idString.substring(1, idString
.indexOf("]")));
child.saveQuestion(i, singleArray[(int) (Math.random() * singleArray.length)]);
}
}
for (int i = endPos; i < parent2.getQuestionSize(); i++) {
if (!child.containsQuestion(parent2.getQuestion(i))) {
child.saveQuestion(i, parent2.getQuestion(i));
} else {
int type = getTypeByIndex(i, rule);
QuestionBean[] singleArray = QuestionService.getQuestionArray(type, idString.substring(1, idString
.indexOf("]")));
child.saveQuestion(i, singleArray[(int) (Math.random() * singleArray.length)]);
}
}
return child;
}
2.4 變異運算元的實現
本系統中變異概率為0.085,對種群的每個個體的每個基因都有變異機會.變異策略為:在(0,1)之間產生一個隨機數,如果小於變異概率,那麼該基因突變.關鍵程式碼如下:
/**
* 突變運算元 每個個體的每個基因都有可能突變
*
* @param paper
*/
public static void mutate(Paper paper) {
QuestionBean tmpQuestion;
List<QuestionBean> list;
int index;
for (int i = 0; i < paper.getQuestionSize(); i++) {
if (Math.random() < mutationRate) {
// 進行突變,第i道
tmpQuestion = paper.getQuestion(i);
// 從題庫中獲取和變異的題目型別一樣分數相同的題目(不包含變異題目)
list = QuestionService.getQuestionListWithOutSId(tmpQuestion);
if (list.size() > 0) {
// 隨機獲取一道
index = (int) (Math.random() * list.size());
// 設定分數
list.get(index).setScore(tmpQuestion.getScore());
paper.saveQuestion(i, list.get(index));
}
}
}
}
2.5 進化的整體流程
本系統中採用精英策略,每次進化都保留上一代最優秀個體.這樣就能避免種群進化方向發生變化,出現適應度倒退的情況.關鍵程式碼如下:
// 進化種群
public static Population evolvePopulation(Population pop, RuleBean rule) {
Population newPopulation = new Population(pop.getLength());
int elitismOffset;
// 精英主義
if (elitism) {
elitismOffset = 1;
// 保留上一代最優秀個體
Paper fitness = pop.getFitness();
fitness.setId(0);
newPopulation.setPaper(0, fitness);
}
// 種群交叉操作,從當前的種群pop 來 建立下一代種群 newPopulation
for (int i = elitismOffset; i < newPopulation.getLength(); i++) {
// 較優選擇parent
Paper parent1 = select(pop);
Paper parent2 = select(pop);
while (parent2.getId() == parent1.getId()) {
parent2 = select(pop);
}
// 交叉
Paper child = crossover(parent1, parent2, rule);
child.setId(i);
newPopulation.setPaper(i, child);
}
// 種群變異操作
Paper tmpPaper;
for (int i = elitismOffset; i < newPopulation.getLength(); i++) {
tmpPaper = newPopulation.getPaper(i);
mutate(tmpPaper);
// 計算知識點覆蓋率與適應度
tmpPaper.setKpCoverage(rule);
tmpPaper.setAdaptationDegree(rule, Global.KP_WEIGHT, Global.DIFFCULTY_WEIGHt);
}
return newPopulation;
}
3. 測試結果
組卷規則為:期望試卷難度係數0.82,共100分,20道選擇題,2分一道,10道填空題,2分一道,4道主觀題,10分一道,要求囊括6個知識點.
外在的條件為:題庫試題總量為10950,期望適應度值為0.98,種群最多迭代100次.
測試程式碼如下:
/**
* 組捲過程
*
* @param rule
* @return
*/
public static Paper generatePaper(RuleBean rule) {
Paper resultPaper = null;
// 迭代計數器
int count = 0;
int runCount = 100;
// 適應度期望值z
double expand = 0.98;
if (rule != null) {
// 初始化種群
Population population = new Population(20, true, rule);
System.out.println("初次適應度 " + population.getFitness().getAdaptationDegree());
while (count < runCount && population.getFitness().getAdaptationDegree() < expand) {
count++;
population = GA.evolvePopulation(population, rule);
System.out.println("第 " + count + " 次進化,適應度為: " + population.getFitness().getAdaptationDegree());
}
System.out.println("進化次數: " + count);
System.out.println(population.getFitness().getAdaptationDegree());
resultPaper = population.getFitness();
}
return resultPaper;
}
測試結果如下:
可以看到改進後的遺傳演算法具有較好的表現
參考資料
本文中的完整程式碼可在github上下載.
你可以通過[email protected]
聯絡我.
歡迎在github或者知乎上關注我 ^_^.
也可以訪問個人網站: https://jslixiaolin.github.io
相關推薦
遺傳演算法在自動組卷中的應用
遺傳演算法 遺傳演算法(Genetic Algorithm)是一種模擬自然界的進化規律-優勝劣汰演化來的隨機搜尋演算法,其在解決多種約束條件下的最優解這類問題上具有優秀的表現. 1. 基本概念 在遺傳演算法中有幾個基本的概念:基因、個體、種群和進化.基
遺傳算法在自動組卷中的應用
init 替代 AI log LG 2個 code 要求 cor 遺傳算法 遺傳算法(Genetic Algorithm)是一種模擬自然界的進化規律-優勝劣汰演化來的隨機搜索算法,其在解決多種約束條件下的最優解這類問題上具有優秀的表現. 1. 基本概念 在遺傳算法中有
馬爾可夫毯式遺傳演算法在基因選擇中的應用
#引用 ##LaTex @article{ZHU20073236, title = “Markov blanket-embedded genetic algorithm for gene selection”, journal = “Pattern Recogn
遺傳演算法的發展現狀與應用例項
.1 引言近年來 ,遺傳演算法 (GA)的卓越效能引起人們的關注 .對於以往難以解決的函式優化問題 ,複雜的多目標規劃問題 ,工農業生產中的配管、配線問題 ,以及機器學習 ,圖象識別 ,人工神經網路的權係數調整和網路構造等問題 ,GA是最有效的方法之一 .雖然GA在許多優化問題中都有成功的應用 ,但其本身也
遺傳演算法框架Geatpy學習之——基於網格化處理的多種群進化優化及其在含等式約束的優化問題中的應用
Geatpy是由華南理工大學、華南農業大學、德州奧斯汀公立大學學生聯合團隊開發的一款Python上的遺傳和進化演算法高效能權威框架。其效能遠高於matlab遺傳演算法工具箱及類似的諸如gatbx、GEATbx、gaot等第三方工具箱。尤其適合需要應用遺傳或其他進化演算法求解建
遺傳演算法在走迷宮遊戲中的應用
前言 遺傳(GA)演算法是一個非常有意思的演算法,因為他利用了生物進化理論的知識進行問題的求解。演算法的核心就是把擁有更好環境適應度的基因遺傳給下一代,這就是其中的關鍵的選擇操作,遺傳演算法整體的階段分為選擇,交叉和變異操作,選擇操作和變異操作在其中又是比較重要的步驟。
在delphi中XLSReadWriteII.組件的應用實例(2)
ngs rms bool specific result ron function delete utils 第三方組件:XLSReadWriteII.v.5.20.67_XE3 實例源碼如下: unit Unit1; interface uses Wi
redis集合/有序集合在電商中應用-自動補全
類似 淘寶 比如 搜尋框中輸入 :書 :下拉框中出現: '書包女士', '書包男款', '書大', '書包女贈送韓版', '書皮紙韓國小清新', '書斤', '書包女雙肩包學生簡約', '書雙肩包', '書包學生', '書籍出版' 使用者可以使用 上下箭頭 或滑鼠 選取 大致有兩種思
R語言中的遺傳演算法詳細解析
前言 人類總是在生活中摸索規律,把規律總結為經驗,再把經驗傳給後人,讓後人發現更多的規規律,每一次知識的傳遞都是一次進化的過程,最終會形成了人類的智慧。自然界規律,讓人類適者生存地活了下來,聰明的科學家又把生物進化的規律,總結成遺傳演算法,擴充套件到了更廣的領域中。 本文將帶你走進遺傳演算法的世界。 目
【演算法】遺傳演算法GA中幾種交叉運算元小結
(圖片例子來自上課時老師的PPT,不過老師說PPT是他從網上組合的,所以沒有出處) 1、Partial-Mapped Crossover (PMX) 過程: 第一步,隨機選擇一對染色體(父代)中幾個基因的起止位置(兩染色體被選位置相同): 第二
RSA演算法在Python Django中的簡單應用
說明 RSA演算法是當今使用最廣泛,安全度最高的加密演算法。 • RSA演算法的安全性理論基礎 [引]根據百科介紹,對極大整數做因數分解的難度決定了RSA演算法的可靠性。換言之,對一極大整數做因數分解愈困難,RSA演算法愈可靠。假如有人找到一種快速因數分解的演算法的話,那麼用RSA加密的資訊的可靠性就肯定會
《Kalman濾波原理及應用》學習筆記(一)——Kalman濾波演算法在溫度測量中的應用
Kalman濾波器 考慮用如下狀態空間模型描述的動態系統(1.1)X(k+1)=ΦX(k)+ΓW(k)X(k+1)=\Phi X(k)+\Gamma W(k) \tag{1.1}X(k+1)=ΦX(k)+ΓW(k)(1.1)(1.2)Y(k)=HX(k)+V(
data_structure_and_algorithm -- 雜湊演算法(下):雜湊演算法在分散式系統中有哪些應用?
今天主要看一下雜湊演算法的應用(二),主要參考:前谷歌工程師王爭的課程,感興趣可以通過下面方式微信掃碼購買: 你可能已經發現,這三個應用都跟分散式系統有關。沒錯,今天我就帶你看下,雜湊演算法是如何解決這些分散式問題的。 應用五:負載均衡 我們知道,負載均衡演算法
從整合方法到神經網路:自動駕駛技術中的機器學習演算法有哪些?
來源:機器之心 編譯:Lj Linjing、蔣思源 物聯網智庫 原創 轉載請註明來源和出處 ------ 【導讀】------ 機器學習演算法可以融合來自車體內外不同感測器的資料,從而評估駕駛員狀況或者對駕駛場景進行分類。本文將粗略講解一下各類用於自動駕駛技術的演算法。 如今,機器
資料探勘演算法與現實生活中的應用案例
如何分辨出垃圾郵件”、“如何判斷一筆交易是否屬於欺詐”、“如何判斷紅酒的品質和檔次”、“掃描王是如何做到文字識別的”、“如何判斷佚名的著作是否出自某位名家之手”、“如何判斷一個細胞是否屬於腫瘤細胞”等等,這些問題似乎都很專業,都不太好回答。但是,如果瞭解一點點資
計算機視覺:隨機森林演算法在人體識別中的應用
摘 要 人體識別是計算機視覺領域的一大類熱點問題,其研究內容涵蓋了人體的監測與跟蹤、手勢識別、動作識別、人臉識別、性別識別和行為與事件識別等,有著非常廣泛的應用價值。隨機森林以它自身固有的特點和優良的分類效果在眾多的機器學習演算法中脫穎而出。隨機森林演算法的實質是一
一致性雜湊演算法在分散式場景中的應用
文章概要 本文將會從實際應用場景出發,介紹一致性雜湊演算法(Consistent Hashing)及其在分散式系統中的應用。首先本文會描述一個在日常開發中經常會遇到的問題場景,藉此介紹一致性雜湊演算法以及這個演算法如何解決此問題;接下來會對這個演算法進行相對詳細的描述,並討論一些如虛擬節
複雜度為O(n)的取一組數中分佈最密集的部分的演算法
公司有一個檢測系統,在單位時間內將每次檢測結果儲存。由於檢測的環境受到外界干擾,會隨機地出現異常值。以前的辦法是:取得所有檢測結果的最大值作為最終值。由於異常值的出現,導致檢測結果非常不準確。於是思考在整個檢測結
2018-3-27 遺傳演算法中的輪盤賭
原出處:http://my.oschina.net/u/1412321/blog/192454一、遺傳演算法的應用函式優化(遺傳演算法的經典應用領域);組合優化(實踐證明,遺傳演算法對於組合優化中的NP完全問題,如0-1揹包問題,TSP等,非常有效);自動控制;機器人智慧控制
特徵選擇演算法在微博業務應用中的演進歷程
近年來,人工智慧與機器學習的應用越來越廣泛,尤其是在網際網路領域。在微博,機器學習被廣泛地應用於微博的各個業務,如Feed流、熱門微博、訊息推送、反垃圾、內容推薦等。 值得注意的是,深度學習作為人工智慧和機器學習的分支,尤其得到更多的重視與應用。深度學習與眾不