169it科技资讯
169it -->


当前位置:  编程技术>综合
本页文章导读:
    ▪secureMRT Linux命令汉字出现乱码      把  选项-》会话选择-》终端-》外观-》字符编码,改成UTF-8即可。 作者:dongpanshan 发表于2013-1-14 11:41:30 原文链接 阅读:35 评论:0 查看评论 ......
    ▪把C++类成员方法直接作为线程回调函数       我以前写线程时要么老老实实照着声明写,要么使用C++类的静态成员函数来作为回调函数,经常会因为线程代码而破坏封装.之前虽然知道类成员函数的展开形式,但从没想过利用过它,昨......
    ▪weak-and算法原理演示(wand)      推荐一个在信息检索中用到的weak-and算法,这个算法在广告系统中有成熟的应用。   简单来说,一般我们在计算文本相关性的时候,会通过倒排索引的方式进行查询,通过倒排索引已经要......
      最新IT科技资讯推荐: -1

[1]secureMRT Linux命令汉字出现乱码
    来源: 互联网  发布时间: 2014-02-18
把  选项-》会话选择-》终端-》外观-》字符编码,改成UTF-8即可。
作者:dongpanshan 发表于2013-1-14 11:41:30 原文链接
阅读:35 评论:0 查看评论

    
[2]把C++类成员方法直接作为线程回调函数
    来源: 互联网  发布时间: 2014-02-18

我以前写线程时要么老老实实照着声明写,要么使用C++类的静态成员函数来作为回调函数,经常会因为线程代码而破坏封装.之前虽然知道类成员函数的展开形式,但从没想过利用过它,昨天看深入ATL时无意中学会了这一招:) 

类成员方法是一个比较特殊的函数,它在编译时会被转化成普通函数,比如有TMyClass类:
class TMyClass

{
    void Func();
};

这个TMyClass::Func最终会转化成 void Func(TMyClass *this); 也就是说在原第一个参数前插入指向对象本身的this指针。

我们可以利用这个特性写一个非静态类成员方法来直接作为线程回调函数,先看_beginthread函数的定义:
unsigned long _RTLENTRY _EXPFUNC _beginthread (void (_USERENTRY *__start)(void *),unsigned __stksize, void *__arg);
其中的第一个参数就是作为线程执行主体的回调函数。它的原型是:void Func(void *),这个void*参数是作为自定义数据传入的。对比一下上面所说的TMyClass::Func的最终形式,它正好可以符合这里的要求。

现在做个实验:


#include <stdio.h>
#include <process.h>

class TMyClass

{
    int m_nCount;
    int m_nId;
public:
    TMyClass(int nId,int nCount)
        :m_nId(nId),m_nCount(nCount)
    { }

    void _USERENTRY ThreadProc()            // 类成员方法
    {
        for(int i=0; i<m_nCount; i++)       // 根据m_nCount成员打印一排数字
        {
            printf("Class%d : %d\n",m_nId,i);
        }
    }
};

int main(int argc, char* argv[])
{

// 联合类,用于转换类成员方法指针到普通函数指针(试过编译器不允许在这两种函数之间强制转换),不知道有没有更好的方法。

    union { 
        void (_USERENTRY *ThreadProc)(void *);
        void (_USERENTRY TMyClass::*MemberProc)();
    } Proc;     // 尽管联合里的两种函数类型现在看起来有很大不同,但它们的最终形式是相同的。


    TMyClass MyClass1(1,10),MyClass2(2,5); // 产生两个TMyClass对象

    Proc.MemberProc = &TMyClass::ThreadProc;   // 转换,Proc.ThreadProc就是对应的普通函数指针了

    _beginthread(Proc.ThreadProc,4096,&MyClass1);   // 开始线程,这里的Proc.ThreadProc实际上是TMyClass::ThreadProc, 它要的this指针是我们给的&MyClass1。
    _beginthread(Proc.ThreadProc,4096,&MyClass2);
    system("pause");
    return 0;
}

运行!神奇吧?:-)

其实不止线程回调函数,其实只要是形如Func(void*,...)的回调函数都可以用这种方法直接使用类成员方法。(前提是第一个void*是自定义数据,也就是说它不能有其它功能)。

作者:lmh12506 发表于2013-1-14 11:39:13 原文链接
阅读:31 评论:0 查看评论

    
[3]weak-and算法原理演示(wand)
    来源: 互联网  发布时间: 2014-02-18
推荐一个在信息检索中用到的weak-and算法,这个算法在广告系统中有成熟的应用。
 
简单来说,一般我们在计算文本相关性的时候,会通过倒排索引的方式进行查询,通过倒排索引已经要比全量遍历节约大量时间,但是有时候仍然很慢。
原因是很多时候我们其实只是想要top n个结果,一些结果明显较差的也进行了复杂的相关性计算,而weak-and算法通过计算每个词的贡献上限来估计文档的相关性上限,从而建立一个阈值对倒排中的结果进行减枝,从而得到提速的效果。
 
从我实际测试的结果看,对于短文本的效果不如长文本的明显,但是在视频的电影数据上面看,仍然减少了50%的耗时(top 100),并且该算法可以通过牺牲精度来进一步提升速度,非常不错。
 
以下代码是一个算法原理演示,实现了主要的算法逻辑以验证算法的有效性,供大家参考,该实现优化了原始算法的一些逻辑尽量减少了无谓的循环

#!/usr/bin/python
#wangben updated 20130108

class WAND:
	'''implement wand algorithm'''
	def __init__(self, InvertIndex, last_docid):
		self.invert_index = InvertIndex #InvertIndex: term -> docid1, docid2, docid3 ...
		self.current_doc = 0
		self.current_invert_index = {}
		self.query_terms = []
		self.threshold = 2

		self.sort_terms = []
		self.LastID = 2000000000 #big num
		self.debug_count = 0
		self.last_docid = last_docid

	def __InitQuery(self, query_terms):
		'''check terms len > 0'''
		self.current_doc = -1
		self.current_invert_index.clear()
		self.query_terms = query_terms
		self.sort_terms[:] = []
		self.debug_count = 0

		for term in query_terms:
			#initial start pos from the first position of term's invert_index
			self.current_invert_index[term] = [ self.invert_index[term][0], 0 ] #[ docid, index ]
	
	def __SortTerms(self):
		if len(self.sort_terms) == 0:
			for term in self.query_terms:
				if term in self.current_invert_index:
					doc_id = self.current_invert_index[term][0]
					self.sort_terms.append([ int(doc_id), term ])
		self.sort_terms.sort()
			

	def __PickTerm(self, pivot_index):
		return 0

	def __FindPivotTerm(self):
		score = 0
		for i in range(0, len(self.sort_terms)):
			score += 1
			if score >= self.threshold:
				return [ self.sort_terms[i][1], i]

		return [ None, len(self.sort_terms) ]

	def __IteratorInvertIndex(self, change_term, docid, pos):
		'''move to doc id > docid'''
		doc_list = self.invert_index[change_term]
		i = 0
		for i in range(pos, len(doc_list)):
			if doc_list[i] >= docid:
				pos = i
				docid = doc_list[i]
				break

		return [ docid, pos ]

	def __AdvanceTerm(self, change_index, docid ):
		change_term = self.sort_terms[change_index][1]
		pos = self.current_invert_index[change_term][1]
		(new_doc, new_pos) = \
			self.__IteratorInvertIndex(change_term, docid, pos)
		
		self.current_invert_index[change_term] = \
			[ new_doc , new_pos ]
		self.sort_terms[change_index][0] = new_doc
		
		
	def __Next(self):
		if self.last_docid == self.current_doc:
			return None
			
		while True:
			self.debug_count += 1
			#sort terms by doc id
			self.__SortTerms()
			
			#find pivot term > threshold
			(pivot_term, pivot_index) = self.__FindPivotTerm()
			if pivot_term == None:
				#no more candidate
				return None
			
			#debug_info:
			for i in range(0, pivot_index + 1):
				print self.sort_terms[i][0],self.sort_terms[i][1],"|",
			print ""
				

			pivot_doc_id = self.current_invert_index[pivot_term][0]
			if pivot_doc_id == self.LastID: #!!
				return None

			if pivot_doc_id <= self.current_doc:
				change_index = self.__PickTerm(pivot_index)
				self.__AdvanceTerm( change_index, self.current_doc + 1 )
			else:
				first_docid = self.sort_terms[0][0]
				if pivot_doc_id == first_docid:
					self.current_doc = pivot_doc_id
					return self.current_doc
				else:
					#pick all preceding term
					for i in range(0, pivot_index):
						change_index = i
						self.__AdvanceTerm( change_index, pivot_doc_id )
	
	def DoQuery(self, query_terms):
		self.__InitQuery(query_terms)
		
		while True:
			candidate_docid = self.__Next()
			if candidate_docid == None:
				break
			print "candidate_docid:",candidate_docid
			#insert candidate_docid to heap
			#update threshold
		print "debug_count:",self.debug_count
		

if __name__ == "__main__":
	testIndex = {}
	testIndex["t1"] = [ 0, 1, 2, 3, 6 , 2000000000]
	testIndex["t2"] = [ 3, 4, 5, 6, 2000000000 ]
	testIndex["t3"] = [ 2, 5, 2000000000 ]
	testIndex["t4"] = [ 4, 6, 2000000000 ]

	w = WAND(testIndex, 6)
	w.DoQuery(["t1", "t2", "t3", "t4"])

输出结果中会展示next中循环的次数,以及最后被选为candidate的docid
这里省略了建立堆的过程,使用了一个默认阈值2作为doc的删选条件,候选doc和query doc采用重复词的个数计算UB,这里只是一个算法演示,实际使用的时候需要根据自己的相关性公式进行调整
作者:yihucha166 发表于2013-1-14 11:38:28 原文链接
阅读:35 评论:0 查看评论

    
最新技术文章:
▪error while loading shared libraries的解決方法    ▪版本控制的极佳实践    ▪安装多个jdk,多个tomcat版本的冲突问题
▪简单选择排序算法    ▪国外 Android资源大集合 和个人学习android收藏    ▪.NET MVC 给loading数据加 ajax 等待loading效果
▪http代理工作原理(3)    ▪关注细节-TWaver Android    ▪Spring怎样把Bean实例暴露出来?
▪java写入excel2007的操作    ▪http代理工作原理(1)    ▪浅谈三层架构
▪http代理工作原理(2)    ▪解析三层架构……如何分层?    ▪linux PS命令
▪secureMRT Linux命令汉字出现乱码    ▪把C++类成员方法直接作为线程回调函数    ▪weak-and算法原理演示(wand)
▪53个要点提高PHP编程效率    ▪linux僵尸进程    ▪java 序列化到mysql数据库中
▪利用ndk编译ffmpeg    ▪活用CSS巧妙解决超长文本内容显示问题    ▪通过DBMS_RANDOM得到随机
▪CodeSmith 使用教程(8): CodeTemplate对象    ▪android4.0 进程回收机制    ▪仿天猫首页-产品分类
▪从Samples中入门IOS开发(四)------ 基于socket的    ▪工作趣事 之 重装服务器后的网站不能正常访    ▪java序列化学习笔记
▪Office 2010下VBA Addressof的应用    ▪一起来学ASP.NET Ajax(二)之初识ASP.NET Ajax    ▪更改CentOS yum 源为163的源
▪ORACLE 常用表达式    ▪记录一下,AS3反射功能的实现方法    ▪u盘文件系统问题
▪java设计模式-观察者模式初探    ▪MANIFEST.MF格式总结    ▪Android 4.2 Wifi Display核心分析 (一)
▪Perl 正则表达式 记忆方法    ▪.NET MVC 给loading数据加 ajax 等待laoding效果    ▪java 类之访问权限
▪extjs在myeclipse提示    ▪xml不提示问题    ▪Android应用程序运行的性能设计
▪sharepoint 2010 自定义列表启用版本记录控制 如    ▪解决UIScrollView截获touch事件的一个极其简单有    ▪Chain of Responsibility -- 责任链模式
▪运行skyeye缺少libbfd-2.18.50.0.2.20071001.so问题    ▪sharepoint 2010 使用sharepoint脚本STSNavigate方法实    ▪让javascript显原型!
▪kohana基本安装配置    ▪MVVM开发模式实例解析    ▪sharepoint 2010 设置pdf文件在浏览器中访问
▪spring+hibernate+事务    ▪MyEclipse中文乱码,编码格式设置,文件编码格    ▪struts+spring+hibernate用jquery实现数据分页异步加
▪windows平台c++开发"麻烦"总结    ▪Android Wifi几点    ▪Myeclipse中JDBC连接池的配置
▪优化后的冒泡排序算法    ▪elasticsearch RESTful搜索引擎-(java jest 使用[入门])    ▪MyEclipse下安装SVN插件SubEclipse的方法
▪100个windows平台C++开发错误之七编程    ▪串口转以太网模块WIZ140SR/WIZ145SR 数据手册(版    ▪初识XML(三)Schema
▪Deep Copy VS Shallow Copy    ▪iphone游戏开发之cocos2d (七) 自定义精灵类,实    ▪100个windows平台C++开发错误之八编程
▪C++程序的内存布局    ▪将不确定变为确定系列~Linq的批量操作靠的住    ▪DIV始终保持在浏览器中央,兼容各浏览器版本
▪Activity生命周期管理之三——Stopping或者Restarti    ▪《C语言参悟之旅》-读书笔记(八)    ▪C++函数参数小结
▪android Content Provider详解九    ▪简单的图片无缝滚动效果    ▪required artifact is missing.
▪c++编程风格----读书笔记(1)    ▪codeforces round 160    ▪【Visual C++】游戏开发笔记四十 浅墨DirectX教程
▪【D3D11游戏编程】学习笔记十八:模板缓冲区    ▪codeforces 70D 动态凸包    ▪c++编程风格----读书笔记(2)
▪Android窗口管理服务WindowManagerService计算Activity    ▪keytool 错误: java.io.FileNotFoundException: MyAndroidKey.    ▪《HTTP权威指南》读书笔记---缓存
▪markdown    ▪[设计模式]总结    ▪网站用户行为分析在用户市场领域的应用
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2017,169IT.COM,E-mail:www_169it_com#163.com(请将#改为@)

浙ICP备11055608号