การบีบอัดจำนวนเต็มสองจำนวนโดยไม่สนใจคำสั่ง


20

การเปรียบเทียบคู่ที่สั่ง (x, y) กับคู่ที่ไม่ได้เรียงลำดับ {x, y} (ชุด) จากนั้นข้อมูลตามหลักเหตุผลความแตกต่างเป็นเพียงหนึ่งบิตราวกับว่า x มาก่อนหรือ y ต้องการบิตเพียงเล็กน้อยในการเป็นตัวแทน

ดังนั้นถ้าเราได้ชุด {x, y} โดยที่ x, y เป็นจำนวนเต็ม 32- บิตที่แตกต่างกันสองชุดเราสามารถแพ็คมันเป็น 63 บิต (แทนที่จะเป็น 64) ได้ไหม? คุณควรกู้คืนจำนวนเต็ม 32 บิตต้นฉบับจากผลลัพธ์ 63 บิต แต่ไม่สามารถกู้คืนคำสั่งซื้อได้

คำตอบ:


27

ใช่หนึ่งสามารถ หากให้จับคู่ชุดกับหมายเลขx<y{x,y}

f(x,y)=y(y1)/2+x.

มันง่ายที่จะแสดงว่าเป็น bijective และสามารถถอดรหัสได้อย่างมีเอกลักษณ์ นอกจากนี้เมื่อเรามีดังนั้นแผนที่นี้จะตั้งค่าเป็นจำนวน 63 บิตy) เพื่อถอดรหัสคุณสามารถใช้การค้นหาไบนารีหรือใช้ราก:ควรจะอยู่ที่ประมาณ\f0x<y<2320f(x,y)<263231{x,y}f(x,y)yy2f(x,y)


1
เหมือน 1 + 2 + 3 + ... + y + x ดีมาก!
ทรอย McClure

1
ลักษณะทั่วไปใด ๆ ของ int ที่ไม่ได้เรียงลำดับ? :) จากความคิดที่สองรูปสี่เหลี่ยมจำนวนมากที่มีอนุพันธ์บางส่วนที่มีขนาดใหญ่พอที่จะทำงาน
Troy McClure

4
คำตอบอื่นที่อาจน่าสนใจสำหรับต้นทุนการคำนวณที่ต่ำ: ถ้าxและyแตกต่างกันแน่นอนx-y-1หรือy-x-1(ทั้ง modแน่นอน) พอดีใน 31 บิต หากมีขนาดเล็กให้ต่อกันและ 31 บิตสุดท้ายของ; มิฉะนั้น concatenate และสุดท้าย 31 บิต กู้คืนหมายเลขสองโดยใช้ 32 บิตแรกเป็นหนึ่งหมายเลขและเพิ่ม 32 บิตแรก, 31 บิตสุดท้ายและค่าคงที่ 1 (mod ) เป็นหมายเลขอื่น 2 32232x-y-1yx-y-1xy-x-1232
Daniel Wagner

1
วิธีการของคุณยังคุยไว้อย่างสวยงามเพื่อเพิ่มตัวเลขมากขึ้นเป็นหมายเลขแรกคือ "มีเพียง" เพื่อให้ห่วงโซ่กระป๋อง
ทรอย McClure

4
@DW: คุณช่วยโปรดเพิ่มว่าคุณมาด้วยการเป็นตัวแทนนี้ได้อย่างไร มิฉะนั้นดูเหมือนว่าคุณจะดึงมันออกมาจากอากาศบาง ๆ
Mehrdad

9

นอกเหนือจากคำตอบของ DW โปรดทราบว่านี่เป็นกรณีพิเศษของระบบCombinatorial Numberซึ่งจะทำการแมปลำดับการลดลงของจำนวนเต็มไม่เป็นลบถึง c k > > c 1kck>>c1

N=i=1k(cii).

หมายเลขนี้มีการตีความง่าย ๆ ถ้าเราเรียงลำดับตามพจนานุกรมเหล่านี้แล้วจะนับจำนวนของลำดับที่เล็กกว่าN

ในการถอดรหัสเพียงกำหนดค่าที่ใหญ่ที่สุดเช่นและถอดรหัสเป็นผลลัพธ์( c kckN- ( ck(ckk)N (k-1)N(ckk)(k1)


4

จำนวนรวมของคู่เรียงลำดับของตัวเลขในชุดของเป็น 2 จำนวนรวมของการเรียงลำดับของคู่ที่แตกต่างกันจำนวนเป็น 2 มันต้องใช้เวลาบิตเพื่อเป็นตัวแทนของคู่ได้รับคำสั่งของตัวเลขและถ้าคุณมีหนึ่งบิตน้อยกว่าคุณสามารถแสดงองค์ประกอบของพื้นที่ขึ้นไป2/2 จำนวนคู่ที่ไม่ได้สั่งแตกต่างกันนั้นมีจำนวนมากกว่าครึ่งของจำนวนคู่ที่สั่งซื้อเล็กน้อยดังนั้นคุณจึงไม่สามารถบันทึกเล็กน้อยในการเป็นตัวแทนได้ จำนวนคู่ที่ไม่ได้เรียงลำดับจะน้อยกว่าครึ่งเล็กน้อยดังนั้นคุณสามารถบันทึกได้เล็กน้อยN ( N + 1 ) / 2 N ( N - 1 ) / 2 2 ล็อก2 ( N ) = เข้าสู่ระบบ2 ( N 2 ) N 2 / 2NN(N+1)/2N(N1)/22log2(N)=log2(N2)N2/2

สำหรับรูปแบบการปฏิบัติที่ง่ายต่อการคำนวณโดยที่เป็นพลังของ 2 คุณสามารถทำงานกับการแสดงค่าบิต ใช้ที่เป็นแฮคเกอร์ (ที่บิตพิเศษหรือ) ผู้ประกอบการ คู่สามารถกู้คืนจากทั้งหรือy) ตอนนี้เราจะค้นหาเคล็ดลับในการบันทึกหนึ่งบิตในส่วนที่สองและให้บทบาทสมมาตรกับและเพื่อไม่ให้คำสั่งซื้อคืนได้ ได้รับการ cardinality การคำนวณข้างต้นเรารู้ว่าโครงการนี้จะไม่ทำงานในกรณีที่ ya = x y { x , y } ( a , x ) ( a , y ) x y x = yNa=xy{x,y}(a,x)(a,y)xyx=y

ถ้ามีตำแหน่งบิตที่แตกต่างกันบ้าง ฉันจะเขียนสำหรับบิตของ TH (เช่น ) และเช่นเดียวกันสำหรับปีให้รับตำแหน่งบิตที่เล็กที่สุดที่และแตกต่างกัน:เป็นที่เล็กที่สุดเช่นว่าy_i เป็นเล็กที่สุดที่ : เราสามารถกู้จากได้ ให้เป็นหรือx ixyxix x = Σ ฉันx ฉัน2 ฉัน Y k x Y k ฉันx ฉันY ฉัน k ฉันฉัน = 1 k x Y k = Σ ฉัน< k x ฉัน2 ฉัน + Σ ฉัน> k x ฉัน2 i - 1 b = i < k yixx=ixi2iykxykixiyikiai=1kabxyด้วยการลบบิตที่ (เช่นหรือ ) - เพื่อให้ได้ส่วนการก่อสร้างที่รับถ้าและและเลือกถ้าและ 0 ใช้เพื่อใช้แทนของคู่ คู่เดิมสามารถกู้คืนได้โดยคำนวณบิตลำดับต่ำสุดที่กำหนดใน , แทรก 0 บิตที่ตำแหน่งนี้ใน (ให้ผลตอบแทนหนึ่งในหรือ ) และรับ xor ของตัวเลขนั้นด้วยkb=i<kxi2i+i>kxi2i1 x x k = 0 y k = 1 y x k = 1 y k = 0 ( a , b ) a b x y ab=i<kyi2i+i>kyi2i1xxk=0yk=1yxk=1yk=0(a,b)abxya (ให้ผลองค์ประกอบอื่น ๆ ของคู่)

ในการแทนค่านี้สามารถเป็นจำนวนที่ไม่ใช่ศูนย์ใด ๆ และสามารถเป็นตัวเลขใด ๆ ที่มีครึ่งหนึ่งของช่วง นี่คือการตรวจสุขภาพจิต: เราได้รับจำนวนที่คาดหวังของการเป็นตัวแทนของคู่ที่ไม่มีลำดับab

ใน pseudocode ด้วย^, &, |, <<, >>, ~เป็น C-เช่นผู้ประกอบการระดับบิต (xor และหรือซ้ายกะขวากะเติมเต็ม):

encode(x, y) =
  let a = x ^ y
  let k = lowest_set_bit_position(a)
  let low_mask = (1 << k) - 1
  let z = if x & (1 << k) = 0 then x else y
  return (a, (z & low_mask) | (z & ~low_mask) >> 1)
decode(a, b) =
  let k = lowest_set_bit_position(a)
  let low_mask = (1 << k) - 1
  let x = (b & low_mask) | ((b & ~low_mask) << 1)
  return (x, a ^ x)

0

หลักฐานที่ไม่เป็นโครงสร้าง: มีไม่มีการเรียงลำดับ คู่ของจำนวนเต็ม 32- บิตที่แตกต่างกัน(232×232232)/2=231(2321)<263

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.