JuliaCollections / JuliaCollections/DataStructures.jl

Heaps with Tuples broken

Open
#786 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Julia
Stars
745
Forks
261
PR merge metrics
No merged PRs in 30d

Description

17 Jan 2022
Expected: (per the Documentation)

Using alternate orderings
Heaps can also use alternate orderings apart from the default one defined by Base.isless. This is accomplished by passing an instance of Base.Ordering as the first argument to the constructor. The top of the heap will then be the element that comes first according to this ordering.

The following example uses 2-tuples to track the index of each element in the original array, but sorts only by the data value:

data = collect(enumerate(["foo", "bar", "baz"]))

h1 = BinaryHeap(data) # Standard lexicographic ordering for tuples
first(h1)             # => (1, "foo")

h2 = BinaryHeap(Base.By(last), data) # Order by 2nd element only
first(h2)                            # => (2, "bar")

Obtained:

julia> using DataStructures

julia> data = collect(enumerate(["foo", "bar", "baz"]))
3-element Vector{Tuple{Int64, String}}:
 (1, "foo")
 (2, "bar")
 (3, "baz")

julia> h1 = BinaryHeap(data)
ERROR: MethodError: no method matching BinaryHeap(::Vector{Tuple{Int64, String}})
Closest candidates are:
  BinaryHeap(::Base.Order.Ordering, ::AbstractVector{T}) where T at E:\ProgramFiles\Julia\.julia\packages\DataStructures\vSp4s\src\heaps\binary_heap.jl:47
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

using Julia 1.7.1 Windows10 (also occurs in Julia 1.6.5)

UPDATE 03 Feb 2022
What works
BinaryHeap with Base.By

julia> data = collect(enumerate(["foo", "bar", "baz"]));
julia> h1 = BinaryHeap(Base.By(first), data);
julia> first(h1)
(1, "foo")
julia> h2 = BinaryHeap(Base.By(last), data);
julia> first(h2)
(2, "bar")

OR
BinaryMinHeap, but switching order in the Tuple

julia> data1 = collect(enumerate(["foo", "bar", "baz"]));
julia> h1 = BinaryMinHeap(data1);
julia> first(h1)
(1, "foo")
julia> data2 = collect(zip(1:3, "foo", "bar", "baz"]));
julia> h2 = BinaryMinHeap(data2);
julia> first(h2)
("bar", 2)

What doesn't work

BinaryHeap(data)
BinaryMinHeap(Base.By(first), data)

Suggestion
Update documentation to reflect this.
Also it is unclear that BinaryHeap is a minheap.
So it is also unclear how to create a BinaryMaxHeap which orders on the second element of the Tuple.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the heaps documentation linked in the issue and compare its tuple examples with the reported BinaryHeap and BinaryMinHeap behavior. Update the examples to match the working constructors and clarify how BinaryHeap orders elements, including how to create a max-heap ordered by a tuple element.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
data
Issue type
Documentation
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.