文章列表
 
您正在查看 "算法与数据结构" 分类下的文章

2010年01月13日 星期三 15:05
或者说是加权随机选取问题,问题是这样的:

n个数,每个数都有权重值,权重值高的,意即该数应该出现的概率大;要求要从n个数中根据各数的权重值随机选取m个数。例如以下10个数:
1(0.1), 2(0.2), 3(0.3), 4(0.4), 5(0.5), 6(0.6), 7(0.7), 8(0.8), 9(0.9), 10(1.0)
括号内的数字表示其权重值,要求根据各数的权重值从这10个数中随机选择3个数。

最容易想到的算法是将这些权重值累加起来,得到一根长度为a的线段,每个权重值是其中的一部分,权重值大的,则它对应的子线段的长度就长。产生随机数r(0,a),即0到a之间的随机数,然后判断这个随机数落在哪个子线段中,就将其选中。
这种思路出发点是:权重高的数,随机数r落在其对应的子线段的概率就大,因为其对应的线段较长。

但是以上算法在用计算机实现时,比较麻烦的,复杂度为m*n。如果再加一个限制,随机取出来的元素不允许重复,那时间复杂度就更高了。

后来在一个paper上看到一算法,完全是数学的方法:
http://utopia.duth.gr/~pefraimi/research/data/2007EncOfAlg.pdf
,我写成了程序,运行的效果不错。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <limits.h>

#include <vector>
#include <algorithm>

typedef long ELEM_TYPE;

#define RAND_LESS_1 (rand() / (float)INT_MAX)


using namespace std;

static bool
weigth_compare(pair<float, int>& a,
pair<float, int>& b)
{
bool ret = false;

if (a.first > b.first)
ret = true;

return ret;
}

/**                                                                                                                                                           
* weighted random sampling                                                                                                                                   
*/
void
weighted_random(ELEM_TYPE* v,
float* w,
int v_size,
vector<ELEM_TYPE>& r,
int r_size)
{
vector<pair<float, int> > vv;
r_size = r_size <= v_size ? r_size : v_size;

for(int i = 0; i < v_size; i++)
{
float u = RAND_LESS_1;
float w_i = 1 / *(w + i);
float k = pow(u, w_i);

/*                                                                                                                                                    
fprintf(stdout, "rand less 1:%f, w_i:%f, k:%f\n",                                                                                                     
u, w_i, k);                                                                                                                                   
*/

vv.push_back(make_pair(k, i));
}

partial_sort(vv.begin(),
vv.begin() + r_size,
vv.end(),
weigth_compare);

for(int i = 0; i < r_size; i++)
r.push_back(v[vv[i].second]);
}

int main(int argc, char** argv)
{
srand(time(NULL));

ELEM_TYPE v[] = {1, 2, 3, 4, 5, 6, 7, 8};
float w[] = {1, 2, 3, 4, 5, 6, 7, 8};
int v_size = 8;

vector<ELEM_TYPE> r;
int r_size = 3;

for (int i = 0; i < 30; i++)
{
r.clear();
weighted_random(v, w, v_size, r, r_size);

fprintf(stdout, "%ld, %ld, %ld\n", r[0], r[1], r[2]);
}


return 0;
}

 
2010年01月10日 星期日 23:12

http://www.google.com/search?q=%E6%9A%B4%E9%9B%AA%20hash%E7%AE%97%E6%B3%95&hl=zh-CN&rlz=1I7GGLL_zh-CN&newwindow=1&lr=&aq=f&oq=%E6%9A%B4%E9%9B%AA%20hash%E7%AE%97%E6%B3%95

看了看网上介绍的暴雪公司的hash算法。

个人觉得确切地说应该是hash方案,呵呵,暴雪应该是受了bloom filter的启发搞出来的。

 
2010年01月10日 星期日 22:47

题目:N块石头排成一行,每块石头有各自固定的位置。两个玩家依次取石头,每个玩家每次可以取其中任意一块石头,或者相邻的两块石头,石头在游戏过程中不能移动,最后能将剩下的石头依次取光的玩家获胜。

 
2008年09月05日 星期五 14:01
概率论与数理统计词汇英汉对照表


A
absolute value 绝对值

accept 接受

acceptable region 接受域

additivity 可加性

adjusted 调整的

alternative hypothesis 对立假设

analysis 分析

analysis of covariance 协方差分析

analysis of variance 方差分析

arithmetic mean 算术平均值

association 相关性

assumption 假设

assumption checking 假设检验

availability 有效度

average 均值

B
balanced 平衡的

band 带宽

bar chart 条形图

beta-distribution 贝塔分布

between groups 组间的

bias 偏倚

binomial distribution 二项分布

binomial test 二项检验

C
calculate 计算

case 个案

category 类别

center of gravity 重心

central tendency 中心趋势

chi-square distribution 卡方分布

chi-square test 卡方检验

classify 分类

cluster analysis 聚类分析

coefficient 系数

coefficient of correlation 相关系数

collinearity 共线性

column 列

compare 比较

comparison 对照

components 构成,分量

compound 复合的

confidence interval 置信区间

consistency 一致性

constant 常数

continuous variable 连续变量

control charts 控制图

correlation 相关

covariance 协方差

covariance matrix 协方差矩阵

critical point 临界点

critical value 临界值

crosstab 列联表

cubic 三次的,立方的

cubic term 三次项

cumulative distribution function 累加分布函数

curve estimation 曲线估计

D
data 数据

default 默认的

definition 定义

deleted residual 剔除残差

density function 密度函数

dependent variable 因变量

description 描述

design of experiment 试验设计

deviations 差异

df.(degree of freedom) 自由度

diagnostic 诊断

dimension 维

discrete variable 离散变量

discriminant function 判别函数

discriminatory analysis 判别分析

distance 距离

distribution 分布

D-optimal design D-优化设计

E
eaqual 相等

effects of interaction 交互效应

efficiency 有效性

eigenvalue 特征值

equal size 等含量

equation 方程

error 误差

estimate 估计

estimation of parameters 参数估计

estimations 估计量

evaluate 衡量

exact value 精确值

expectation 期望

expected value 期望值

exponential 指数的

exponential distributon 指数分布

extreme value 极值

F
factor 因素,因子

factor analysis 因子分析

factor score 因子得分

factorial designs 析因设计

factorial experiment 析因试验

fit 拟合

fitted line 拟合线

fitted value 拟合值

fixed model 固定模型

fixed variable 固定变量

fractional factorial design 部分析因设计

frequency 频数

F-test F检验

full factorial design 完全析因设计

function 函数

G
gamma distribution 伽玛分布

geometric mean 几何均值

group 组

H
harmomic mean 调和均值

heterogeneity 不齐性

histogram 直方图

homogeneity 齐性

homogeneity of variance 方差齐性

hypothesis 假设

hypothesis test 假设检验

I
independence 独立

independent variable 自变量

independent-samples 独立样本

index 指数

index of correlation 相关指数

interaction 交互作用

interclass correlation 组内相关

interval estimate 区间估计

intraclass correlation 组间相关

inverse 倒数的

iterate 迭代

K
kernal 核

Kolmogorov-Smirnov test

柯尔莫哥洛夫-斯米诺夫检验

kurtosis 峰度

L
large sample problem 大样本问题

layer 层

least-significant difference 最小显著差数

least-square estimation 最小二乘估计

least-square method 最小二乘法

level 水平

level of significance 显著性水平

leverage value 中心化杠杆值

life 寿命

life test 寿命试验

likelihood function 似然函数

likelihood ratio test 似然比检验

linear 线性的

linear estimator 线性估计

linear model 线性模型

linear regression 线性回归

linear relation 线性关系

linear term 线性项

logarithmic 对数的

logarithms 对数

logistic 逻辑的

lost function 损失函数

M
main effect 主效应

matrix 矩阵

maximum 最大值

maximum likelihood estimation 极大似然估计

mean squared deviation(MSD) 均方差

mean sum of square 均方和
measure 衡量

media 中位数

M-estimator M估计

minimum 最小值

missing values 缺失值

mixed model 混合模型

mode 众数

model 模型

Monte Carle method 蒙特卡罗法

moving average 移动平均值

multicollinearity 多元共线性

multiple comparison 多重比较

multiple correlation 多重相关

multiple correlation coefficient 复相关系数

multiple correlation coefficient 多元相关系数

multiple regression analysis 多元回归分析

multiple regression equation 多元回归方程

multiple response 多响应

multivariate analysis 多元分析

N
negative relationship 负相关

nonadditively 不可加性

nonlinear 非线性

nonlinear regression 非线性回归

noparametric tests 非参数检验

normal distribution 正态分布

null hypothesis 零假设

number of cases 个案数

O
one-sample 单样本

one-tailed test 单侧检验

one-way ANOVA 单向方差分析

one-way classification 单向分类

optimal 优化的

optimum allocation 最优配制

order 排序

order statistics 次序统计量

origin 原点

orthogonal 正交的

outliers 异常值

P
paired observations 成对观测数据

paired-sample 成对样本

parameter 参数

parameter estimation 参数估计

partial correlation 偏相关

partial correlation coefficient 偏相关系数

partial regression coefficient 偏回归系数

percent 百分数

percentiles 百分位数

pie chart 饼图

point estimate 点估计

poisson distribution 泊松分布

polynomial curve 多项式曲线

polynomial regression 多项式回归

polynomials 多项式

positive relationship 正相关

power 幂

P-P plot P-P概率图

predict 预测

predicted value 预测值

prediction intervals 预测区间

principal component analysis 主成分分析

proability 概率

probability density function 概率密度函数

probit analysis 概率分析

proportion 比例

Q
qadratic 二次的

Q-Q plot Q-Q概率图

quadratic term 二次项

quality control 质量控制

quantitative 数量的,度量的

quartiles 四分位数

R
random 随机的

random number 随机数

random number 随机数

random sampling 随机取样

random seed 随机数种子

random variable 随机变量

randomization 随机化

range 极差

rank 秩

rank correlation 秩相关

rank statistic 秩统计量

regression analysis 回归分析

regression coefficient 回归系数

regression line 回归线

reject 拒绝

rejection region 拒绝域

relationship 关系

reliability 可靠性

repeated 重复的

report 报告,报表

residual 残差

residual sum of squares 剩余平方和

response 响应

risk function 风险函数

robustness 稳健性

root mean square 标准差

row 行

run 游程

run test 游程检验

S
sample 样本

sample size 样本容量

sample space 样本空间

sampling 取样

sampling inspection 抽样检验

scatter chart 散点图

S-curve S形曲线

separately 单独地

sets 集合

sign test 符号检验

significance 显著性

significance level 显著性水平

significance testing 显著性检验

significant 显著的,有效的

significant digits 有效数字

skewed distribution 偏态分布

skewness 偏度

small sample problem 小样本问题

smooth 平滑

sort 排序

soruces of variation 方差来源

space 空间

spread 扩展

square 平方

standard deviation 标准离差

standard error of mean 均值的标准误差

standardization 标准化

standardize 标准化

statistic 统计量

statistical quality control 统计质量控制

std. residual 标准残差

stepwise regression analysis 逐步回归

stimulus 刺激

strong assumption 强假设

stud. deleted residual 学生化剔除残差

stud. residual 学生化残差

subsamples 次级样本

sufficient statistic 充分统计量

sum 和

sum of squares 平方和

summary 概括,综述

T
table 表

t-distribution t分布

test 检验

test criterion 检验判据

test for linearity 线性检验

test of goodness of fit 拟合优度检验

test of homogeneity 齐性检验

test of independence 独立性检验

test rules 检验法则

test statistics 检验统计量

testing function 检验函数

time series 时间序列

tolerance limits 容许限

total 总共,和

transformation 转换

treatment 处理

trimmed mean 截尾均值

true value 真值

t-test t检验

two-tailed test 双侧检验

U
unbalanced 不平衡的

unbiased estimation 无偏估计

unbiasedness 无偏性

uniform distribution 均匀分布

V
value of estimator 估计值

variable 变量

variance 方差

variance components 方差分量

variance ratio 方差比

various 不同的

vector 向量

W
weight 加权,权重

weighted average 加权平均值

within groups 组内的

Z
Z score Z分数
 
2008年03月31日 星期一 11:36
隐马尔科夫模型(hidden Markov model, HMM, 被我亲切的称为黑妹妹)于20世纪70年代在语音识别领域取得巨大的成功,之后被广泛应用到自然语言处理的各个领域,成为基于统计的自然语言处理的重要方法.

下面是我的学习笔记, 希望对大家有所帮助.

http://www.ponyse.com/17.html
 
2008年03月23日 星期日 21:43
本文介绍了条件随机场模型. 全文见:
http://www.ponyse.com/?p=11
 
2008年01月17日 星期四 9:38
    搜索引擎检索时,常常要将两个结果进行组合处理,例如查询“中国北京”,则需要将包含“中国”和“北京”的文档编号序列进行合并的操作。常用的算法有归并,先排序后去重等,但这些算法在大数据量的情况下,如对包含“中国”的10万个文档编号序列和包含“北京”的8万个文档编号序列进行组合时,效率比较低,无法满足搜索引擎高速的检索要求。我们引入了基于二进制数组的算法来解决这个问题。
    基于二进制数组的整数序列合并算法是一种高速的多个整数序列组合的算法。它的基本原理是将各整数序列保存在一个二进制的数组当中,然后对这些二进制数组进行并,或的运算。
    下面详细介绍一下此算法的处理过程。
    1. 将整数序列转为二进制数组。
    先申请一个二进制数组,其大小为有可能出现的最大的整数值,如500万,如图所示。
(图1)
    假设有5个整数组成的序列{2,3,200,7000,12000},则我们可以将这个序列保存在二进制数组当中,如图2所示,第n位如果为1,则表示n存在于这个序列中:
(图2)
    2. 对两个序列进行位运算。
    如果需要对两个整数序列进行并的操作,那么只需要对它们对应的二进制数组进行“并”的位运算;如果需要对两个整数序列进行或的操作,那么只需要对它们对应的二进制数组进行“或”的位运算;如果需要对两个整数序列进行NOT的操作,那么只需要对它们对应的二进制数组先进行“并”的位运算,再进行“异或”的位运算。
    计算机进行位运算的速度是最快的。在实际的程序中,我们可以以long类型为基本的位运算单位,相同位置的long型数据进行两两位运算,以提高速度。
    3. 将二进制数组转为结果整数序列。
    位运算结束后,需要将这个结果再转为整数序列。这个转换后的整数序列就是我们需要的最终结果。
    下面是一次完整的运算过程,我们需要将{2,3,300}和{2,3,200,7000,12000}这两个序列进行并的操作。如图3所示。
(图3)
    整数序列{2,3}即是我们最终所要的结果。

    (转载请说明出处)
 
2007年08月20日 星期一 9:25

这周需要用到归并算法, 于是找了找相关的资料, 整理如下:

下面的内容摘自:http://blog.csdn.net/jiaowenhao/archive/2007/02/06/1503587.aspx:

归并排序(Merge Sort)是利用"归并"技术来进行排序。归并是指将若干个已排序的子文件合并成一个有序的文件。

两路归并算法

1、算法基本思路

      设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中。

(1)合并过程
      合并过程中,设置i,j和p三个指针,其初值分别指向这三个记录区的起始位置。合并时依次比较R[i]和R[j]的关键字,取关键字较小的记录复制到R1[p]中,然后将被复制记录的指针i或j加1,以及指向复制位置的指针p加1。
      重复这一过程直至两个输入的子文件有一个已全部复制完毕(不妨称其为空),此时将另一非空的子文件中剩余记录依次复制到R1中即可。

(2)动态申请R1
      实现时,R1是动态申请的,因为申请的空间可能很大,故须加入申请空间是否成功的处理。

2、归并算法
   void Merge(SeqList R,int low,int m,int high)
     {//将两个有序的子文件R[low..m)和R[m+1..high]归并成一个有序的
      //子文件R[low..high]
      int i=low,j=m+1,p=0; //置初始值
      RecType *R1; //R1是局部向量,若p定义为此类型指针速度更快
      R1=(ReeType *)malloc((high-low+1)*sizeof(RecType));
      if(! R1) //申请空间失败
        Error("Insufficient memory available!");
      while(i<=m&&j<=high) //两子文件非空时取其小者输出到R1[p]上
        R1[p++]=(R[i].key<=R[j].key)?R[i++]:R[j++];
      while(i<=m) //若第1个子文件非空,则复制剩余记录到R1中
        R1[p++]=R[i++];
      while(j<=high) //若第2个子文件非空,则复制剩余记录到R1中
        R1[p++]=R[j++];
      for(p=0,i=low;i<=high;p++,i++)
        R[i]=R1[p];//归并完成后将结果复制回R[low..high]
     } //Merge

归并排序

      归并排序有两种实现方法:自底向上和自顶向下。

1、 自底向上的方法
(1) 自底向上的基本思想
      自底向上的基本思想是:第1趟归并排序时,将待排序的文件R[1..n]看作是n个长度为1的有序子文件,将这些子文件两两归并,若n为偶数,则得到 个长度为2的有序子文件;若n为奇数,则最后一个子文件轮空(不

参与归并)。故本趟归并完成后,前 个有序子文件长度为2,但最

后一个子文件长度仍为1;第2趟归并则是将第1趟归并所得到的 个有

序的子文件两两归并,如此反复,直到最后得到一个长度为n的有序文件为止。
      上述的每次归并操作,均是将两个有序的子文件合并成一个有序的子文件,故称其为"二路归并排序"。类似地有k(k>2)路归并排序。

(2) 一趟归并算法
分析:
       在某趟归并中,设各子文件长度为length(最后一个子文件的长度可能小于length),则归并前R[1..n]中共有 个有序的子文件:R

[1..length],R[length+1..2length],…,
注意:
      调用归并操作将相邻的一对子文件进行归并时,必须对子文件的个数可能是奇数、以及最后一个子文件的长度小于length这两种特殊情况进行特殊处理:
① 若子文件个数为奇数,则最后一个子文件无须和其它子文件归并(即本趟轮空);
② 若子文件个数为偶数,则要注意最后一对子文件中后一子文件的区间上界是n。

具体算法如下:
     void MergePass(SeqList R,int length)
      { //对R[1..n]做一趟归并排序
       int i;
       for(i=1;i+2*length-1<=n;i=i+2*length)
       Merge(R,i,i+length-1,i+2*length-1);
            //归并长度为length的两个相邻子文件
       if(i+length-1<n) //尚有两个子文件,其中后一个长度小于length
          Merge(R,i,i+length-1,n); //归并最后两个子文件
       //注意:若i≤n且i+length-1≥n时,则剩余一个子文件轮空,无须归并
      } //MergePass

(3)二路归并排序算法
   void MergeSort(SeqList R)
    {//采用自底向上的方法,对R[1..n]进行二路归并排序
      int length;
      for(1ength=1;length<n;length*=2) //做 趟归并

         MergePass(R,length); //有序段长度≥n时终止
    }

注意:
      自底向上的归并排序算法虽然效率较高,但可读性较差。

2、自顶向下的方法
      采用分治法进行自顶向下的算法设计,形式更为简洁。

(1)分治法的三个步骤
      设归并排序的当前区间是R[low..high],分治法的三个步骤是:
①分解:将当前区间一分为二,即求分裂点
                 

②求解:递归地对两个子区间R[low..mid]和R[mid+1..high]进行归并排序;
③组合:将已排序的两个子区间R[low..mid]和R[mid+1..high]归并为一个有序的区间R[low..high]。
   递归的终结条件:子区间长度为1(一个记录自然有序)。

(2)具体算法
     void MergeSortDC(SeqList R,int low,int high)
      {//用分治法对R[low..high]进行二路归并排序
        int mid;
        if(low<high){//区间长度大于1
           mid=(low+high)/2; //分解
           MergeSortDC(R,low,mid); //递归地对R[low..mid]排序
           MergeSortDC(R,mid+1,high); //递归地对R[mid+1..high]排序
           Merge(R,low,mid,high); //组合,将两个有序区归并为一个有序区
         }
      }//MergeSortDC

二、算法分析

1、稳定性

       归并排序是一种稳定的排序。

2、存储结构要求
      可用顺序存储结构。也易于在链表上实现。

3、时间复杂度
      对长度为n的文件,需进行 趟二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)。

4、空间复杂度
      需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n),显然它不是就地排序。
  注意:
      若用单链表做存储结构,很容易给出就地的归并排序


以下内容摘自:http://chian.blogdriver.com/chian/385113.html:

归并算法将两个有序的数组合并到一个数组中并使之有序,这两个数组并不一定相同大小,但需要一个额外的数组存放归并结果。算法比较两个数组相同位置的元素,将小的放入结果数组中,如此往复,如果其中一个先到达末尾,则将另外一个剩下部分放入结果数组中。

   归并排序将数组不断划分, 第一次分成两半, 第二次分成四份, 如此直到得到只有一个元素的数组返回, 假定一个元素是有序的, 然后将两个数据项归并到两个元素的有序数组中, 再次返回, 将这一对两个元素的数组归并到一个四个元素的数组中, 返回最外层的时候, 这个数组将会有两个分别有序的子数组, 再次归并则完成排序.

下面是合并两个数组的代码,其实是归并排序的一部分。

////////////////// merge sort ///////////////

// lowPtr: 第一个数组的起始索引,

//highPtr: 第二个数组的起始索引.

//upperBound: 第二个数组的最大索引.
private void merge (int lowPtr, int highPtr, int upperBound) {
   int idx = 0;          //结果数组的索引初始为0
   int lowerBound = lowPtr; //保存第一个数组的起始点
   int middle = highPtr - 1;   //第一个数组的最大索引. 因为要归并的两个数组相邻.
  

// 只要有一个数组到达末尾就结束
while (lowPtr <= middle && highPtr <= upperBound) {
   if ( array[lowPtr] < array[highPtr] ) { //哪个小就放进结果数组
     workspace[idx++] = array [lowPtr++];
    }
   else{
     workspace[idx++] = array [highPtr++];
    }
   }

  while (lowPtr <= middle) { //第二个数组先结束了
    workspace[idx++] = array[lowPtr++];
   }
  while (highPtr <= upperBound ) { //第一个数组先结束了

    workspace[idx++] = array[highPtr++];
   }

//将结果数组里的归并后元素拷回原数组

  for ( int i = 0; i

      array [lowerBound+i] = workspace [i];
   }
}

划分数组则简单地用递归的方法,下面是排序的方法.

//lowerBound: 待排序数组的起始索引

//upperBound: 待排序数组的结束索引

private void sort (int lowerBound, int upperBound) {
  if (lowerBound == upperBound) { //如果只有一个元素了就返回
    return;
   }
else {
    int mid = (lowerBound + upperBound) / 2; //找到中间位置

    sort (lowerBound, mid); //排左边
    sort (mid+1, upperBound); //排右边

    merge (lowerBound, mid+1, upperBound); //归并
   }
}

       对于N个元素的数组来说, 如此划分需要的层数是以2为底N的对数, 每一层中, 每一个元素都要复制到结果数组中, 并复制回来, 所以复制2N次, 那么对于归并排序,它的时间复杂度为O(N*logN), 而比较次数会少得多, 最少需要N/2次,最多为N-1次, 所以平均比较次数在两者之间. 它的主要问题还是在于在内存中需要双倍的空间.

 
 
   
 
 
文章分类
 
   
 
文章存档
 
     
 
最新文章评论
  

[表情]
 

问题解决,谢谢分享~
 

做了没有?
 

太长知识了,这两天我也老犯这毛病
 

非常感谢~学习了~
   
帮助中心 | 空间客服 | 投诉中心 | 空间协议
©2012 Baidu