350 likes | 394 Views
Learn how to represent states efficiently for graph searching and puzzles using bitwise operations, optimizing memory and runtime. Discover the power of bit manipulation in computer organization and massive calculations.
E N D
State RepresentationofState Space Searching Alan Tam Siu Lung Tam@SiuLung.com 99967891 96397999
Prerequisite • State Space Search • Pascal/C/C++ • Familiar with the data types • Mathematics
Generic GraphSearching Algorithm • c: container of states • insert start to c • while c not empty • pop an element from c (with minimum total cost) • if found goal, return • add/update some elements in c
Generic Graph Searching • Best first search: choose the node with minimum estimated total path cost = current path cost + estimated cost to goal • Uniform cost search: estimated cost to goal = 0 • Breadth first search: current path cost = depth of the node in an un-weighted graph • Depth first search: estimated total path cost = inverse of current path cost
States Storage Problem • Need to store many states • Memory is limited • Runtime is limited • Compiler is stupid • we need intelligence to represent states wisely
Operation on States • 3 operations: • Is goal? • Are these 2 states equal? • Find all neighbors. • Questions • Can some operation be slow? • Can we pre-compute? (i.e. store redundant info) • Can states be not uniquely represented?
8-puzzle • struct state { • int num[9]; • int space_pos; • }; • record state • num : array[1..9] of 0..8 • space_pos: 1..9; • end;
Entropy • Possible Different states: 181440 • Space we used? 320 bits • Using bytes? 80 bits
Missionaries and Cannibals • struct state { • int m[2], c[2]; • bool b; • }; • record state • m, c : array[1..2] of 1..3; • b : boolean • end;
Entropy • Possible Different states: 16 • Space we used? 160 bits • Using bytes? 40 bits • One side only? 24 bits
Be realistic • |{3, 2, 1, 0}|2 |{L, R}| = 32 • Store it as M + C * 4 + B * 16 • |{3M3C, 3M2C, 3M1C, 3M, 2M2C, 1M1C, 3C, 2C, 1C, }| |{L, R}| = 20
Computer Organization • x86 stores whole numbers in: • Binary Form • x86 stores negative integers in: • 2’s complement • x86 stores real numbers in: • IEEE 754 • x86 stores alphabets in: • ASCII
Integer Representation 46709394 (10) = 00000010110010001011101010010010 (2) = 0C C8 BA 92 (16) (0x0cc8ba92 in C/C++) Little Endian:
State Representation • M + C * 4 + B * 16 • M=3, C=3, B=0 • 00001111 (=15) • M=0, C=0, B=1 • 00010000 (=16) • M=2, C=2, B=1 • 00011010 (=26)
If you discovered… • M=3, C=3, B=0 • 00001111 (=15) • M=0, C=0, B=1 • 00010000 (=16) • M=2, C=2, B=1 • 00011010 (=26) • This is Bitwise Representation
Why bitwise? • It is the native language of the computer • It works extremely fast • Integer Multiplication: 4 cycles latency • Moving Bits: 1 cycle latency • Packing and unpacking is easier to code and thus less error prone
Binary << shl >> shr & and | or ^ xor Unary ~ not shift # bits left shift # bits right intersection union mutual exclusion complement Bitwise Operations
Bitmap • Shift operators and bitwise operators can be used to manage a sequence of bits of 64 elements • Operations • Get(p : 0..Size-1) : Boolean • Set(p : 0..Size-1) • Unset(p : 0..Size-1) • Toggle(p : 0..Size-1)
Using a 32-bit Integer • 00000010110010001011101010010010 • 1 << p = a number with only bit p on • value & (1 << p) != 0 Get(p) • value = value | (1 << p) Set(p) • value = value & ~(1 << p) Unset(p) • value = value ^ (1 << p) Toggle(p) Bit 0 Bit 31
Using Bitmap • Space-efficient • Runtime may be faster • Cache hit • Less copying • Or maybe slower • More calculations
Massive Calculations • Example: Count number of bits on a 16-bit integer v • v = (v & 0x5555) + ((v >> 1) & 0x5555) • v = (v & 0x3333) + ((v >> 2) & 0x3333) • v = (v & 0x0f0f) + ((v >> 4) & 0x0f0f) • v = (v & 0x00ff) + ((v >> 8) & 0x00ff)
Counting #bits • 1 0 0 1 1 1 1 1 0 0 0 1 0 0 1 0 • 01 01 10 10 00 01 00 01 • 0010 0100 0001 0001 • 00000110 00000010 • 0000000000001000 • Exercise: Do it for 32-bit
Massive Calculations • Given a bit pattern, find a bit pattern which: • only the leftmost bit of a bit group is on • E.g. • 1110101101111001 becomes1000101001000001
Answer • 1110101101111001 becomes1000101001000001 • The leftmost of a bit group means: • It is 1 • Its left is 0 • So: • value = value & ~(value >> 1)
Bit Movements • Question • 1 1 0 1 0 1 0 0becomes0101000100010000 • Solution • value = ((value & 0x00f0) << 4)) | (value & 0x000f) • value = ((value & 0x0c0c) << 2)) | (value & 0x0303) • value = ((value & 0x2222) << 1)) | (value & 0x1111) • Exercise • 1 1 0 1 0 1 0 0becomes1111001100110000 • 0 1 0 1becomes0000111100001111
Complex Bit Patterns • Othello • 11101011 (where occupied) • 10001001 (color) • You are 1, where you can play? • Solution • 11101011 & ~10001001 = 01100010 • 11101011 + 01100010 = 01001101 • 01001101 & ~11101011 = 00000100 • How about the reverse direction?
Other Uses • Store multiple values, each one assigned a bit-range • (value % 32) == (value & 31) • Storing sets of 64 elements • Union • Difference • Is Subset
switch (i) { case 1: case 3: case 4: case 7: case 8: case 10: f(); break; default: g(); } if ((1<<i) & 0x039a) f(); else g(); Multiple Comparisons
Lexicographical Ordering • Consider the 8 puzzle • Store it verbatim: 89 = 387420489 • Hash table? How large? • Calculate a mapping from the 362880 possible permutations to 0..362879
Example • What are smaller than 530841672? • 5308416[0-6]?: 1 1 • 530841[0-5]??: 1 2 • 53084[0-0]???: 0 6 • 5308[0-3]????: 2 24 • 530[0-7]?????: 5 120 • 53[^]??????: 0 720 • 5[0-2]???????: 3 5040 • [0-4]????????: 5 40320