离散化
离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。
概述
离散化是程序设计中一个非常常用的技巧,它可以有效的降低时间复杂度。其基本思想就是在众多可能的情况中“只考虑我需要用的值”。离散化可以改进一个低效的算法,甚至实现根本不可能实现的算法。要掌握这个思想,必须从大量的题目中理解此方法的特点。
举例解释
[1] 如果说OIBH问得最多的问题是二分图,那么“现在”问得最多的算是离散化了。对于“什么是离散化”,搜索帖子你会发现有各种说法,比如“排序后处理”、“对坐标的近似处理”等等。哪个是对的呢?哪个都对。关键在于,这需要一些例子和不少的讲解才能完全解释清楚。
离散化是程序设计中一个非常常用的技巧,它可以有效的降低时间和空间复杂度。其基本思想就是在众多可能的情况中“只考虑我需要用的值”。下面我将用三个例子说明,如何运用离散化改进一个低效的,甚至根本不可能实现的算法。
《算法艺术与信息学竞赛》中的计算几何部分,黄亮举了一个经典的例子,我认为很适合用来介绍离散化思想。这个问题是UVA10173题目意思很简单,给定平面上n个点的坐标,求能够覆盖所有这些点的最小矩形面积。这个问题难就难在,这个矩形可以倾斜放置(边不必平行于坐标轴)。
这里的倾斜放置很不好处理,因为我们不知道这个矩形最终会倾斜多少度。假设我们知道这个矩形的倾角是α,那么答案就很简单了:矩形面积最小时四条边一定都挨着某个点。也就是说,四条边的斜率已经都知道了的话,只需要让这些边从外面不断逼近这个点集直到碰到了某个点。你不必知道这个具体应该怎么实现,只需要理解这可以通过某种方法计算出来,毕竟我们的重点在下面的过程。
我们的算法很显然了:枚举矩形的倾角,对于每一个倾角,我们都能计算出最小的矩形面积,最后取一个最小值。
这个算法是否是正确的呢?我们不能说它是否正确,因为它根本不可能实现。矩形的倾角是一个实数,它有无数种可能,你永远不可能枚举每一种情况。我们说,矩形的倾角是一个“连续的”变量,它是我们无法枚举这个倾角的根本原因。我们需要一种方法,把这个“连续的”变量变成一个一个的值,变成一个“离散的”变量。这个过程也就是所谓的离散化。
我们可以证明,最小面积的矩形不但要求四条边上都有一个点,而且还要求至少一条边上有两个或两个以上的点。试想,如果每条边上都只有一个点,则我们总可以把这个矩形旋转一点使得这个矩形变“松”,从而有余地得到更小的矩形。于是我们发现,矩形的某条边的斜率必然与某两点的连线相同。如果我们计算出了所有过两点的直线的倾角,那么α的取值只有可能是这些倾角或它减去90度后的角(直线按“\”方向倾斜时)这么C(n,2)种。我们说,这个“倾角”已经被我们“离散化”了。虽然这个算法仍然有优化的余地,但此时我们已经达到了本文开头所说的目的。
对于某些坐标虽然已经是整数(已经是离散的了)但范围极大的问题,我们也可以用离散化的思想缩小这个规模。搞模拟赛Vijos似乎火了一把,我就拿两道Vijos的题开刀。
VOJ1056[2] 永远是离散化的经典问题。大意是给定平面上的n个矩形(坐标为整数,矩形与矩形之间可能有重叠的部分),求其覆盖的总面积。平常的想法就是开一个与二维坐标规模相当的二维Boolean数组模拟矩形的“覆盖”(把矩形所在的位置填上True)。可惜这个想法在这里有些问题,因为这个题目中坐标范围相当大(坐标范围为-10^8到10^8之间的整数)。但我们发现,矩形的数量n<=100远远小于坐标范围。每个矩形会在横纵坐标上各“使用”两个值,100个矩形的坐标也不过用了-10^8到10^8之间的200个值。也就是说,实际有用的值其实只有这么几个。这些值将作为新的坐标值重新划分整个平面,省去中间的若干坐标值没有影响。我们可以将坐标范围“离散化”到1到200之间的数,于是一个200*200的二维数组就足够了。实现方法正如本文开头所说的“排序后处理”。对横坐标(或纵坐标)进行一次排序并映射为1到2n的整数,同时记录新坐标的每两个相邻坐标之间在离散化前实际的距离是多少。这道题同样有优化的余地。
最后简单讲一下计算几何以外的一个运用实例(实质仍然是坐标的离散)。VOJ1238[3] 中,标程开了一个与时间范围一样大的数组来储存时间段的位置。这种方法在空间上来看十分危险。一旦时间取值范围再大一点,盲目的空间开销将导致Memory Limit Exceeded。我们完全可以采用离散化避免这种情况。我们对所有给出的时间坐标进行一次排序,然后同样用时间段的开始点和结束点来计算每个时刻的游戏数,只是一次性加的经验值数将乘以排序后这两个相邻时间点的实际差。这样,一个1..n的数组就足够了。
离散化的应用相当广泛,以后你会看到还有很多其它的用途。
以上内容转自百度百科http://baike.baidu.com/view/3392254.htm?fr=aladdin
那么,使用离散化到底有什么好处呢?
离散化指把连续型数据切分为若干“段”,也称bin,是数据分析中常用的手段。切分的原则有等距,等频,优化,或根据数据特点而定。在营销数据挖掘中,离散化得到普遍采用。究其原因,有这样几点:
①算法需要。例如决策树,NaiveBayes等算法本身不能直接使用连续型变量,连续型数据只有经离散处理后才能进入算法引擎。这一点在使用具体软件时可能不明显。因为大多数数据挖掘软件内已经内建了离散化处理程序,所以从使用界面看,软件可以接纳任何形式的数据。但实际上,在运算决策树或NaiveBayes模型前,软件都要在后台对数据先作预处理。
②离散化可以有效地克服数据中隐藏的缺陷:使模型结果更加稳定。例如,数据中的极端值是影响模型效果的一个重要因素。极端值导致模型参数过高或过低,或导致模型被虚假现象“迷惑”,把原来不存在的关系作为重要模式来学习。而离散化,尤其是等距离散,可以有效地减弱极端值和异常值的影响,
③有利于对非线性关系进行诊断和描述:对连续型数据进行离散处理后,自变量和目标变量之间的关系变得清晰化。如果两者之间是非线性关系,可以重新定义离散后变量每段的取值,如采取0,1的形式,由一个变量派生为多个哑变量,分别确定每段和目标变量间的联系。这样做,虽然减少了模型的自由度,但可以大大提高模型的灵活度。
即使在连续型自变量和目标变量之间的关系比较明确,例如可以用直线描述的情况下,对自变量进行离散处理也有若干优点。一是便于模型的解释和使用,二是可以增加模型的区别能力。
等距:将连续型变量的取值范围均匀划成n等份,每份的间距相等。例如,客户订阅刊物的时间是一个连续型变量,可以从几天到几年。采取等距切分可以把1年以下的客户划分成一组,1-2年的客户为一组,2-3年为一组..,以此类分,组距都是一年。
等频:把观察点均匀分为n等份,每份内包含的观察点数相同。还取上面的例子,设该杂志订户共有5万人,等频分段需要先把订户按订阅时间按顺序排列,排列好后可以按5000人一组,把全部订户均匀分为十段。
等距和等频在大多数情况下导致不同的结果。等距可以保持数据原有的分布,段落越多对数据原貌保持得越好。等频处理则把数据变换成均匀分布,但其各段内观察值相同这一点是等距分割作不到的。
优化离散:需要把自变量和目标变量联系起来考察。切分点是导致目标变量出现明显变化的折点。常用的检验指标有卡方,信息增益,基尼指数,或WOE(要求目标变量是两元变量)
离散连续型数据还可以按照需要而定。比如,当营销的重点是19-24岁的大学生消费群体时,就可以把这部分人单独划出。
离散化处理不免要损失一部分信息。很显然,对连续型数据进行分段后,同一个段内的观察点之间的差异便消失了。同时,进行了离散处理的变量有了新值。比如现在可以简单地用1,2,3..这样一组数字来标志杂志订户所处的段落。这组数字和原来的客户订阅杂志的时间没有直接的联系,也不再具备连续型数据可以运算的关系。例如,使用原来的数据,我们可以说已有两年历史的客户订阅时间是只有一年历史客户的两倍,但经过离散处理后,我们只知道第2组的客户的平均订阅时间高于第一组客户,但无法知道两组客户之间的确切差距。
以上内容转自http://blog.sina.com.cn/s/blog_652090850100ynds.html