Group Abstract Group Abstract

Message Boards Message Boards

[WSS18] Min-Heap Implementation

Attachments:
9 Replies

enter image description here - Congratulations! This post is now a Staff Pick as distinguished by a badge on your profile! Thank you, keep it coming!

POSTED BY: EDITORIAL BOARD

Did you do large-scale time tests? The function HInsert looks like it has an O(n) component due to the AppendTo.

I would recommend starting with a list of fixed length maxLength and perhaps initialized e.g. ConstantArray[0,maxLength], a currentLength counter, and a function that makes a new list of length say 1.4*prior length whenever currentLength hits the current maxLength (which of course also gets modified at that point).

[Not sure if I should show this, but there already exist spelunking tools that one could use to find it.] Here is some internal code we have used for heaps. First step is to force autoload of some integer linear programming code (because I know already there is some heap code in there).

Reduce[{x - 3 y == 7, x >= -10, y <= 20}, {x, y}, Integers];

Now find out what available functionality is related to heaps.

?? *`*Heap*

(* CalculateUnits`UnitCommonSymbols`
HeapedBushels   MetricHeapedBushels

 Combinatorica`
Heapify

 NIntegrate`
Heap    HeapElements   HeapInsert    HeapMerge
HeapDelete  HeapEmptyQ   HeapLookup    HeapTopElement

 System`IntegerLinearDump`
HeapAdd HeapGet *)

So we have some stuff in the context "System``IntegerLinearDump``" (apologies for the doubled back-ticks, I don't know how to format them to get proper single ones). We'll put that on the context path and then have a look at Information.

AppendTo[$ContextPath, "System`IntegerLinearDump`"];

?? HeapAdd

(* System`IntegerLinearDump`HeapAdd
Attributes[HeapAdd]={HoldFirst}

HeapAdd[h_,a_,k_]:=Block[
  {hole=k+1,parent,val=a[[1]]},
  parent=Floor[hole/2];
  While[parent!=0&&h[[parent,1]]>val,
    h[[hole]]=h[[parent]];
    hole=parent;
    parent=Floor[hole/2]];
  h[[hole]]=a] *)

?? HeapGet

(* System`IntegerLinearDump`HeapGet
Attributes[HeapGet]={HoldFirst} 

HeapGet[h_,k_]:=Block[
  {ans=h[[1]],hole=1,c1=2,c2,val=h[[k,1]]},
  While[c1<k,
  c2=c1+1;
  If[c2<k,If[h[[c1,1]]<h[[c2,1]],If[h[[c1,1]]<val,
    h[[hole]]=h[[c1]];hole=c1;c1=2 hole,c1=k],
    If[h[[c2,1]]<val,h[[hole]]=h[[c2]];hole=c2;c1=2 hole,c1=k]],
    If[h[[c1,1]]<val,h[[hole]]=h[[c1]];hole=c1;c1=2 hole,c1=k]]];
   h[[hole]]=h[[k]];ans] *)

The callers of HeapAdd are responsible for checking that the length requirement is met. When exceeded, they double the heap by using Join to a List of same size, with all zeros for elements. In typical usage this will be a packed array if elements are in the machine integer range.

POSTED BY: Daniel Lichtblau

Hey, I only large scale tested the functions I ended up using on the project. I didn't know AppendTo was so slow. Many thanks for the suggestions though!

It's nice to see Mathematica used to learn/teach computer science concepts.

I just have a suggestion for wrapping up your functions into a package. Do take a look at the standard packages structure:

Issues with your package:

  • It can't be loaded with Needs["MinHeap`"] because the package filename does not match the context name
  • It creates symbols like n (and other private symbols) in the public MinHeap` context. Never export unnecessary symbols or there will be conflicts. I'm sure that trying to add some of these common symbols (n, x, etc.) to a heap will now cause trouble.
  • Being["`Private`"] must have a backtick at the start too—you missed it.

Some questions:

  • Why are you restricting functions like HInsert to work with assigned symbols only, and not with lists? E.g. why is it necessary to do HInsert[someSymbol, element] instead of HInset[{...}, element]?
  • I didn't fully understand the role of the dcount global variable. It seems to be used for all heaps. Or is the package able to work only with a single heap?
POSTED BY: Szabolcs Horvát

Thanks for the suggestions & issues. I'll fix them at the next opportunity.

To address your questions,

  • I didn't know how to modify in-place arguments of functions, without using HoldAll/HoldFirst or Unevaluated. With HoldAll, the heap argument can't be unassigned symbols (or at least I couldn't figure out how).
  • My mistake. I essentially took the packing project code and put it in a package, where I only used a single heap. I'll think of a solution next opportunity I have as well.
Anonymous User
Anonymous User
Posted 8 years ago

mathematica as you now know is a great tool for testing computer science, algorithms, more. some have the theory an OS could be run by it - though no one has show this "actually tried" yet

POSTED BY: Anonymous User
Anonymous User
Anonymous User
Posted 8 years ago

there is a problem with the Big O notation in "school text books": they never asked Intel

for example: the old textbooks count sorting a[i] as a single index and a[i][j] as double (killing the O, making it a slow sort)

but Intel chips do the [i][j] in a single clock now (a feature to help bad code written by big companies?): so the O is wrong in the textbooks

POSTED BY: Anonymous User
Anonymous User
Anonymous User
Posted 8 years ago
POSTED BY: Anonymous User

Pretty cool!

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard