Showing posts with label Book Notes. Show all posts
Showing posts with label Book Notes. Show all posts

啊哈算法


解密QQ - d
新学期开始了,小哈是小哼的新同桌(小哈是个小美女哦~),小哼向小哈询问QQ 号,
小哈当然不会直接告诉小哼啦,原因嘛你懂的。所以小哈给了小哼一串加密过的数字,同时
小哈也告诉了小哼解密规则。规则是这样的:首先将第1 个数删除,紧接着将第2 个数放到
这串数的末尾,再将第3 个数删除并将第4 个数放到这串数的末尾,再将第5 个数删除……
直到剩下最后一个数,将最后一个数也删除。按照刚才删除的顺序,把这些删除的数连在一

起就是小哈的QQ 啦。现在你来帮帮小哼吧。小哈给小哼加密过的一串数是“6 3 1 7 5 8 9 2 4”。

int main()
{
  int q[102]={0,6,3,1,7,5,8,9,2,4},head,tail;
  int i;
  //初始化队列
  head=1;
  tail=10; //队列中已经有9个元素了,tail指向队尾的后一个位置
  while(head<tail) //当队列不为空的时候执行循环
  {
  //打印队首并将队首出队
  printf("%d ",q[head]);
  head++;
  //先将新队首的数添加到队尾
  q[tail]=q[head];
  tail++;
  //再将队首出队
  head++;
  }
  getchar();getchar();
  return 0;
}

纸牌游戏——小猫钓鱼
星期天小哼和小哈约在一起玩桌游,他们正在玩一个非常古怪的扑克游戏——“小猫钓
鱼”。游戏的规则是这样的:将一副扑克牌平均分成两份,每人拿一份。小哼先拿出手中的
第一张扑克牌放在桌上,然后小哈也拿出手中的第一张扑克牌,并放在小哼刚打出的扑克牌
的上面,就像这样两人交替出牌。出牌时,如果某人打出的牌与桌上某张牌的牌面相同,即
可将两张相同的牌及其中间所夹的牌全部取走,并依次放到自己手中牌的末尾。当任意一人
手中的牌全部出完时,游戏结束,对手获胜。



Book Note 1: An Introduction to Information Retrieval 读书笔记(一)


An Introduction to Information Retrieval 读书笔记(一)
这本书是 Yahoo! Labs 老大 Dr. P 合著的,近日决定泛读一下.
IR 所谓“方法”其实也就 inverted index 搞来搞去,新的东西不多,都是从别的地方借用过来的感觉。这部分我们整理第一章到第五章的内容,这是关于建立 boolean retrieval 的基本知识。大概的分块如下:
  • boolean retrieval,第 1-5 章
  • vector space model 和 evaluation,第 6-8 章
  • relevence 和几个 specific 的 retrieval 问题,第 9-12 章
  • machine learning 方法,第 13-18 章
  • web search 和 link analysis, 第 19-21 章
boolean retrieval 要解决的就是一堆“(不)含有 xxx”通过和、或连接起来的 bool 表达式下的 retrieval 问题,这最常用的 inverted index 是相对 forward index 而言:所谓前向索引就是文档编号到所包含内容(如 bag of words 表达)的关系,而倒排索引是 word 对应到哪些文档的关系。对一个较大的语料建立 inverted index 可以用一次 Map/Reduce 实现:
  • mapper 输入为 doc ID 和内容,输出为 word, doc ID 的 key/value 对;
  • reducer 拿到的是同一个 word 对应的 doc ID 序列,一般我们将其顺序存储到一个链表结构里面;
为了从 query 关联到对应的链表,我们可以用 hash table 或者 trie。剩下的就是处理两个 list 的交、并实现 and/or 的逻辑,事实上使用按照 doc ID 排序后的链表取交可以使用类似 merge sort 中 merge 的策略,类似的实现并也可如此。那么如果要实现“非”,也可以类似处理,只是判断是否出现在取非的部分。
有了这么一个概念,剩下的就是细化里面的一些步骤,比如抽取单词,这部分我们一般需要一些 NLP 的工具做 tokenize 获得一个一个的 token,然后根据语言做 stemming/lemmatization 这样一些 normalization 的步骤(如大小写转换)。对某些特定的问题,我们知道 stop words 可以在这个过程中去掉避免产生的 posting list 过长。为了加速 posting list 的遍历,往往加入所谓 skip pointers,将 list 分段,如每隔长度的算术平方根个 doc 加一个跳转。那么比较精细的做法往往会存下该词出现在某个文档中的频率甚至位置列表。加入这些东西以后可以做 proximity search(指定单词之间的距离不能超过多少)。
我们可以为某些 search 提供一个字典方便加入对含有 wildcard 类型 query 的支持,这一般会使用 search tree(通过前缀获得)。另一方面我们也会引入 edit distance(也叫 Levenshtein 距离)对输入有误的 query 进行修正。
建立好一个 index 需要动态的维护是一个相对较复杂的问题。增加我们可以继续前面类似的操作;删除一般需要维护一个删除列表,在合适的时候移除(lazy delete 策略);头疼的是更新 =.=
存放的 dictionary、index 均可以用某种方式进行压缩,因此有必要研究各种分布。通常认为语料的大小 T 与字典的大小 M 满足 heap’s law,即 M = kT^b;各个文档中间依照词频排序后对应的比例关系满足 Zipf’s 

law,即 。编码方式往往可以利用前缀性质和变长编码。

开源的 lucene为我们提供了一
套建立 boolean retrieval 的机制。我们可以使用 lucene 提供的简单的命令行为一个目录下面的文件建立 index,

java org.apache.lucene.demo.IndexFiles -docs your-docs-dir
java org.apache.lucene.demo.SearchFiles

进行搜索,如果希望修改已有的建立索引、搜索的流程,可以看看对应文件的源代码。
Please read full article from An Introduction to Information Retrieval 读书笔记(一)

Matrix Multiply - 矩阵乘法


Matrix Multiply - 矩阵乘法
     两个矩阵 A,B:A 的列数等于 B 的行数,则A、B可以相乘。即,如果 A = (aij)是一个m * n的矩阵,B =(bjk)是一个 n * p 的矩阵,则它们的乘积 C = AB 是 m * p 矩阵 C = (cik)。
    学过计算机图形学,会发现,不管是二维图形的平移,旋转,缩放,三维图形的取景变换,投影变换等都是通过矩阵乘法来实现,例如,二维点P(x,y)平移(tx,ty)后得到 P’(x’,y’),可以通过矩阵计算:
                                                   
                                              
                                             
求矩阵相乘的通用公式为:
还有一个常见用法,求斐波那契数列:               
     所以当求 Fn 时可以用求幂来快速求出,而求幂也是建立在矩阵乘法的基础上:
                        
     矩阵相乘有两种方法,普通的矩阵乘法(Matrix Multiply)和Strassen算法。
最普通的矩阵乘法
Matrix operator * (Matrix a, Matrix b) {
    Matrix ret;
    ret.init(a.n, b.m);
    for (int i = 0; i < a.n; i++) {
        for (int k = 0; k < a.m; k++) if (a.mat[i][k]) {
            for (int j = 0; j < b.m; j++) if (b.mat[k][j]) {
                ret.mat[i][j] = ret.mat[i][j] + a.mat[i][k] * b.mat[k][j]; 
                if (ret.mat[i][j] >= mod) {
                    ret.mat[i][j] %= mod;
                }//if
            }//for(j)
        }//for(k)
    }//for(i)
    return ret;
}//乘法
矩阵加法只需简单的将两个矩阵的元素相加:
Matrix operator + (Matrix a, Matrix b) {
    Matrix ret;
    ret.init(a.n, a.m);
    for (int i = 0; i < a.n; i++) {
        for (int j = 0; j < a.m; j++) {
            ret.mat[i][j] = a.mat[i][j] + b.mat[i][j];
            if (ret.mat[i][j] >= mod) {
                ret.mat[i][j] %= mod;
            }
        }
    }
    return ret;
}//加法
矩阵求幂
Matrix operator ^ (Matrix a, int b) {
    Matrix ret = a,  tmp = a;
    ret.init_e();
    for ( ; b; b >>= 1) {
        if (b & 1) {
            ret = ret * tmp;
        }
        tmp = tmp * tmp;
    }
    return ret;
}//
幂求和,即求S = A + A2 + A3 +… + Ak  ,同样的二分思想,但是利用递归,可以很快求出:
//递归幂求和
//用二分法求矩阵和,递归实现 
Matrix Power_Sum1(Matrix a, int b) {
    Matrix ret = a;
    ret.init_e();
    if (b == 1) {
        return a;
    } else if (b & 1) {
        return (a ^ b) + Power_Sum1(a, b - 1);
    } else {
        return Power_Sum1(a, b >> 1) * ((a ^ (b >> 1)) + ret);
    }
}
//非递归幂求和
Matrix Power_Sum2(Matrix a, int b) {
    int k = 0 ,ss[32];
    Matrix tp1, tp2, ret;
    tp1 = tp2 = ret = a;
    ret.init_e();
    while (b) {
        ss[k++] = b & 1;
        b >>= 1;
    }
    for (int i = k - 2; i >= 0; i--) {
        tp1 = tp1 * (tp2 + ret);
        tp2 = tp2 * tp2;
        if (ss[i]) {
            tp2 = tp2 * a;
            tp1 = tp1 + tp2;
        }
    }
    return tp1;
}




二、Strassen算法
     Strassen算法核心思想是分治,是一种递归算法,运行时间为O(nlg7) = O(n2.81),当 n 很大时,优化很明显,在普通的矩阵乘法中,C = A * B,按照:
     每计算一个元素C[i,j],需要做 n 个乘法和 n – 1 次加法。因此,求出矩阵 C 的 n个元素所需的计算时间为0(n3)。Strassen算法的分治体现在:假设 n 是 2 的幂,将将矩阵A,B和C中每一矩阵都分块成为 4 个大小相等的子矩阵,每个子矩阵都是n / 2 × n / 2的方阵。由此可将方程C = AB重写为:
   由此可得
     可以看出,进行了8次乘法,4次加法,当子矩阵的阶大于2时,为求2个子矩阵的积,可以继续将子矩阵分块,直到子矩阵的阶降为2,利用这个简单的分治策略,最后可以得出:T(n) = 8T(n / 2) + O(n2),但是这个式子的解任然为T(n)= O(n3),和普通的方法效率一样,没有任何提高,原因是上边的四个式子并没有减少矩阵乘法的次数(乘法极其耗费时间,学过底层二进制计算的,必然了解,而加减操作非常轻松),所以改进算法的关键是,减少乘法次数。
     Strassen算法的高效之处,就在于,它成功的减少了乘法次数,将8次乘法,减少到7次。不要小看这减少的一次,每递归计算一次,效率就可以提高1 / 8,比如一个大的矩阵递归5次后,(7 / 8)5 = 0.5129,效率提升一倍。不过,这只是理论值,实际情况中,有隐含开销,并不是最常用算法,《算法导论》中给出四条理由:1)隐含的常数因子比简单的O(n3)方法中的常数因子要大。2)矩阵是稀疏矩阵时,为稀疏矩阵设计的方法更快。还有两点已经被缓解,可以不考虑。所以,稠密矩阵上的快速矩阵乘法实现一般采用Strassen算法。

M1 = (A0 + A3) × (B0 + B3)

M2 = (A2 + A3) × B0

M3 = A0 × (B1 – B3)

M4 = A3 × (B2 – B0)

M5 = (A0 + A1) × B3

M6 = (A2 – A0) × (B0 + B1)

M7 = (A1 – A3) × (B2 + B3)

C0 = M1 + M4 – M5 + M7

C1 = M3 + M5

C2 = M2 + M4

C3 = M1 – M2 + M3 + M6

      求解M1,……,M7总共7次乘法,其他都是加法和减法,比如将C0扩展开后,最后结果是,C0 = A0 * B0 + A1 * B2,《算法导论》里有一句奇怪的话:“现在我们还不清楚Strassen当时是如何找出算法正常运行的关键——子矩阵乘积”,一次乘法的消失过程真的这么吊诡?
Please read full article from Matrix Multiply - 矩阵乘法

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts