最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

PHP中實現(xiàn)Bloom Filter算法

 更新時間:2015年03月30日 10:22:37   投稿:junjie  
這篇文章主要介紹了PHP中實現(xiàn)Bloom Filter算法,本文直接給出實現(xiàn)代碼,代碼中給出詳細注釋,Bloom Filter算法介紹等內(nèi)容,需要的朋友可以參考下
<?php

/*Bloom Filter算法來去重過濾。


介紹下Bloom Filter的基本處理思路:申請一批空間用于保存0 1信息,再根據(jù)一批哈希函數(shù)確定元素對應的位置,如果每個哈希函數(shù)對應位置的值為全部1,說明此元素存在。相反,如果為0,則要把對應位置的值設置為1。由于不同的元素可能會有相同的哈希值,即同一個位置有可能保存了多個元素的信息,從而導致存在一定的誤判率。

如果申請空間太小,隨著元素的增多,1會越來越多,各個元素沖突的機會越來越來大,導致誤判率會越來越大。另外哈希函數(shù)的選擇及個數(shù)上也要平衡好,多個哈希函數(shù)雖然可以提供判斷的準確性,但是會降低程序的處理速度,而哈希函數(shù)的增加又要求有更多的空間來存儲位置信息。

Bloom-Filter的應用。
  Bloom-Filter一般用于在大數(shù)據(jù)量的集合中判定某元素是否存在。例如郵件服務器中的垃圾郵件過濾器。在搜索引擎領域,Bloom-Filter最常用于網(wǎng)絡蜘蛛(Spider)的URL過濾,網(wǎng)絡蜘蛛通常有一個 URL列表,保存著將要下載和已經(jīng)下載的網(wǎng)頁的URL,網(wǎng)絡蜘蛛下載了一個網(wǎng)頁,從網(wǎng)頁中提取到新的URL后,需要判斷該URL是否已經(jīng)存在于列表中。此時,Bloom-Filter算法是最好的選擇。 
  比如說,一個象 Yahoo,Hotmail 和 Gmai 那樣的公眾電子郵件(email)提供商,總是需要過濾來自發(fā)送垃圾郵件的人(spamer)的垃圾郵件。一個辦法就是記錄下那些發(fā)垃圾郵件的 email 地址。由于那些發(fā)送者不停地在注冊新的地址,全世界少說也有幾十億個發(fā)垃圾郵件的地址,將他們都存起來則需要大量的網(wǎng)絡服務器。 

  布隆過濾器是由巴頓.布隆于一九七零年提出的。它實際上是一個很長的二進制向量和一系列隨機映射函數(shù)。我們通過上面的例子來說明起工作原理。

  假定我們存儲一億個電子郵件地址,我們先建立一個十六億二進制(比特),即兩億字節(jié)的向量,然后將這十六億個二進制位全部設置為零。對于每一個電子郵件地址 X,我們用八個不同的隨機數(shù)產(chǎn)生器(F1,F2, ...,F8) 產(chǎn)生八個信息指紋(f1, f2, ..., f8)。再用一個隨機數(shù)產(chǎn)生器 G 把這八個信息指紋映射到 1 到十六億中的八個自然數(shù) g1, g2, ...,g8?,F(xiàn)在我們把這八個位置的二進制位全部設置為一。當我們對這一億個 email 地址都進行這樣的處理后。一個針對這些 email 地址的布隆過濾器就建成了。(見下圖) 現(xiàn)在,讓我們看看如何用布隆過濾器來檢測一個可疑的電子郵件地址 Y 是否在黑名單中。我們用相同的八個隨機數(shù)產(chǎn)生器(F1, F2, ..., F8)對這個地址產(chǎn)生八個信息指紋 s1,s2,...,s8,然后將這八個指紋對應到布隆過濾器的八個二進制位,分別是 t1,t2,...,t8。如果 Y 在黑名單中,顯然,t1,t2,..,t8 對應的八個二進制一定是一。這樣在遇到任何在黑名單中的電子郵件地址,我們都能準確地發(fā)現(xiàn)。 
  布隆過濾器決不會漏掉任何一個在黑名單中的可疑地址。但是,它有一條不足之處。也就是它有極小的可能將一個不在黑名單中的電子郵件地址判定為在黑名單中,因為有可能某個好的郵件地址正巧對應八個都被設置成一的二進制位。好在這種可能性很小。我們把它稱為誤識概率。在上面的例子中,誤識概率在萬分之一以下。 
  布隆過濾器的好處在于快速,省空間。但是有一定的誤識別率。常見的補救辦法是在建立一個小的白名單,存儲那些可能別誤判的郵件地址。
	 
	 
*/

// 使用php程序來描述上面的算法 


$set = array(1,2,3,4,5,6);
// 判斷5是否在$set 中 

$bloomFiter = array(0,0,0,0,0,0,0,0,0,0);

// 通過某種算法改變$bloomFiter 中位數(shù)組表示集合,這里我們使用簡單的算法,把集合中對應的value 對應到bloom中的位置變成1 

// 算法如下 


foreach($set as $key){
	
	$bloomFiter[$key] = 1 ;
}

var_dump($bloomFiter) ; 

//此時 $bloomFiter = array(1,1,1,1,1,1);

//判斷是否在集合中

 if($bloomFiter[9] ==1){
	 echo '在set 中'; 
 }else{
	 echo '不在set 中' ;
 }
 
 
 // 上面只是一個簡單的例子,實際上哈希算法需要好幾個,但另一方面,如果哈希函數(shù)的個數(shù)少,那么位數(shù)組中的0就多
 
 
 class bloom_filter {

 function __construct($hash_func_num=1, $space_group_num=1) {
  $max_length = pow(2, 25);
  $binary = pack('C', 0);

  //1字節(jié)占用8位
  $this->one_num = 8;

  //默認32m*1
  $this->space_group_num = $space_group_num;
  $this->hash_space_assoc = array();

  //分配空間
  for($i=0; $i<$this->space_group_num; $i++){
   $this->hash_space_assoc[$i] = str_repeat($binary, $max_length);
  }

  $this->pow_array = array(
   0 => 1,
   1 => 2,
   2 => 4,
   3 => 8,
   4 => 16,
   5 => 32,
   6 => 64,
   7 => 128,
  );
  $this->chr_array = array();
  $this->ord_array = array();
  for($i=0; $i<256; $i++){
   $chr = chr($i);
   $this->chr_array[$i] = $chr;
   $this->ord_array[$chr] = $i;
  }

  $this->hash_func_pos = array(
   0 => array(0, 7, 1),
   1 => array(7, 7, 1),
   2 => array(14, 7, 1),
   3 => array(21, 7, 1),
   4 => array(28, 7, 1),
   5 => array(33, 7, 1),
   6 => array(17, 7, 1),
  );

  $this->write_num = 0;
  $this->ext_num = 0;

  if(!$hash_func_num){
   $this->hash_func_num = count($this->hash_func_pos);
  }
  else{
   $this->hash_func_num = $hash_func_num;
  }
 }

 function add($key) {
  $hash_bit_set_num = 0;
// 離散key
  $hash_basic = sha1($key);
//  截取前4位,然后十六進制轉(zhuǎn)換為十進制
  $hash_space = hexdec(substr($hash_basic, 0, 4));
//  取模
  $hash_space = $hash_space % $this->space_group_num;

  for($hash_i=0; $hash_i<$this->hash_func_num; $hash_i++){
   $hash = hexdec(substr($hash_basic, $this->hash_func_pos[$hash_i][0], $this->hash_func_pos[$hash_i][1]));
   $bit_pos = $hash >> 3;
   $max = $this->ord_array[$this->hash_space_assoc[$hash_space][$bit_pos]];
   $num = $hash - $bit_pos * $this->one_num;
   $bit_pos_value = ($max >> $num) & 0x01;
   if(!$bit_pos_value){
    $max = $max | $this->pow_array[$num];
    $this->hash_space_assoc[$hash_space][$bit_pos] = $this->chr_array[$max];
    $this->write_num++;
   }
   else{
    $hash_bit_set_num++;
   }
  }
  if($hash_bit_set_num == $this->hash_func_num){
   $this->ext_num++;
   return true;
  }
  return false;
 }

 function get_stat() {
  return array(
   'ext_num' => $this->ext_num,
   'write_num' => $this->write_num,
  );
 }
}


//test
//取6個哈希值,目前是最多7個
$hash_func_num = 6;

//分配1個存儲空間,每個空間為32M,理論上是空間越大誤判率越低,注意php.ini中可使用的內(nèi)存限制
$space_group_num = 1;

$bf = new bloom_filter($hash_func_num, $space_group_num);

$list = array(
 'http://test/1',
 'http://test/2',
 'http://test/3',
 'http://test/4',
 'http://test/5',
 'http://test/6',
 'http://test/1',
 'http://test/2',
);
foreach($list as $k => $v){

 if($bf->add($v)){
  echo $v, "\n";
 }
}
print_r($bf->get_stat());

相關文章

  • PHP的runkit擴展如何使用

    PHP的runkit擴展如何使用

    PHP 運行的時候,也就是部署完成后,我們是不能修改常量的值,也不能修改方法體內(nèi)部的實現(xiàn)的。也就是說,我們編碼完成后,將代碼上傳到服務器,這時候,我們想在不修改代碼的情況去修改一個常量的值是不行的。但是,runkit 擴展卻可以幫助我們完成這個功能。
    2021-05-05
  • PHP實現(xiàn)將顏色hex值轉(zhuǎn)換成rgb的方法

    PHP實現(xiàn)將顏色hex值轉(zhuǎn)換成rgb的方法

    這篇文章主要介紹了PHP實現(xiàn)將顏色hex值轉(zhuǎn)換成rgb的方法,涉及PHP針對字符串與數(shù)組的數(shù)學運算相關操作技巧,需要的朋友可以參考下
    2016-05-05
  • PHP常量define和const的區(qū)別詳解

    PHP常量define和const的區(qū)別詳解

    這篇文章主要給大家介紹了關于PHP常量define和const區(qū)別的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用PHP具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-05-05
  • 淺析SVN常見問題及解決方法

    淺析SVN常見問題及解決方法

    本篇文章是對SVN常見問題及解決方法進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • PHP set_error_handler()函數(shù)使用詳解(示例)

    PHP set_error_handler()函數(shù)使用詳解(示例)

    本文詳細介紹PHP set_error_handler()函數(shù)的使用方法,最后還提供了一個實例
    2013-11-11
  • PHP實現(xiàn)的mysql讀寫分離操作示例

    PHP實現(xiàn)的mysql讀寫分離操作示例

    這篇文章主要介紹了PHP實現(xiàn)的mysql讀寫分離操作,簡單講述了mysql讀寫分離的原理,并結(jié)合實例形式給出了php針對mysql的讀寫sql語句操作不同數(shù)據(jù)庫的相關實現(xiàn)技巧,需要的朋友可以參考下
    2018-05-05
  • php處理文件的小例子(解壓縮,刪除目錄)

    php處理文件的小例子(解壓縮,刪除目錄)

    php處理文件的小例子(解壓縮,刪除目錄),供初學者參考
    2013-02-02
  • PHP 命名空間實例說明

    PHP 命名空間實例說明

    PHP 命名空間實例說明,需要的朋友可以參考下。
    2011-01-01
  • PHP 數(shù)據(jù)庫 常見問題小結(jié)

    PHP 數(shù)據(jù)庫 常見問題小結(jié)

    揭露 PHP 應用程序中出現(xiàn)的五個常見數(shù)據(jù)庫問題 —— 包括數(shù)據(jù)庫模式設計、數(shù)據(jù)庫訪問和使用數(shù)據(jù)庫的業(yè)務邏輯代碼 —— 以及它們的解決方案。
    2009-06-06
  • 基于PHP實現(xiàn)一個簡單的在線聊天功能

    基于PHP實現(xiàn)一個簡單的在線聊天功能

    這篇文章主要介紹了基于PHP實現(xiàn)一個簡單的在線聊天功能,對類似功能感興趣的同學,要著重看一下
    2021-04-04

最新評論

甘洛县| 霞浦县| 岳西县| 聊城市| 广水市| 虞城县| 涿鹿县| 德昌县| 宁蒗| 平罗县| 洪湖市| 贡觉县| 沂源县| 平顶山市| 玉环县| 芜湖市| 虹口区| 屏东市| 筠连县| 眉山市| 新和县| 柯坪县| 长葛市| 同江市| 小金县| 石台县| 井研县| 大关县| 沽源县| 惠州市| 时尚| 蓬溪县| 永胜县| 娄底市| 上栗县| 磴口县| 贡嘎县| 彭山县| 锡林浩特市| 桐梓县| 客服|