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

A language for binary tree based programming is Lisp, which is based upon solely that (yet complete programs can be written using it).

Mathematica has infinite List type and evaluation of List elements as functions or data, in a way mm can do the job of Lisp albeit a little differently; not so rigidly. you have to study Lisp to know what I mean.

guide/DiscreteMathematics shows ways to create, use, traverse binary and also complex trees

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