Julia SortedSet

时间:2019-01-22 16:17:39

标签: julia

在Julia的SortedSet文档中,有对“排序对象”的引用,该引用可在构造函数中使用。我正在一个项目中,我需要在一组结构上实现自定义排序。我想为此使用函子,因为我需要进行其他状态比较。 这是我要解决的问题的简化版本。我有两个结构,Point和Edge:

struct Point{T<:Real}
    x::T
    y::T
end
struct Edge{T<:Real}
    first::Point{T}
    second::Point{T}
end

我有一个称为“优势”的,我想按其与“优势”的距离来订购。从概念上讲:

function edge_ordering(vantage::Point, e1::Edge, e2::Edge)
    d1 = distance(vantage, e1)
    d2 = distance(vantage, e2)
    return d1 < d2
end

“订购对象”函子(或仿函子)是吗?在Julia中是否有其他常规方法可以进行这种排序?

2 个答案:

答案 0 :(得分:1)

排序基于类型的方法isless。因此,例如,如果您要在b字段中进行排序。例如,您可以

struct Foo{T}
        a::T
        b::T
end

Base.:isless(x::T,y::T) where {T<:Foo} = isless(x.b,y.b)

s=[Foo(1,2),Foo(2,-1)]

res=SortedSet(s)
#SortedSet(Foo[Foo(2, -1), Foo(1, 2)],
#Base.Order.ForwardOrdering())

组也按顺序排序,因此您也可以使用 sort(s,by=x->(x.b,x.a))b排序,然后a排序,而不必为类型定义isless

答案 1 :(得分:1)

Ordering对象可以包含字段,您可以在其中存储状态。这是余数排序示例,它按余数对整数排序:

using DataStructures

struct RemainderOrdering <: Base.Order.Ordering
    r::Int
end

import Base.Order.lt
lt(o::RemainderOrdering, a, b) = isless(a % o.r, b % o.r)

SortedSet(RemainderOrdering(3), [1,2,3]) # 3, 1, 2

我不确定它与函子之间的关系,因此我可能会误解您的问题。这是定义订购函子的替代实现。我在评论中做了解释。

using DataStructures
import Base: isless, map

struct Foo # this is your structure
    x::Int
end

struct PrimaryOrdered{T, F} # this is the functor, F is the additional state.
    x::T
end

map(f::Base.Callable, x::T) where {T <: PrimaryOrdered} = T(f(x.x)) # this makes it a functor?
isless(x::PrimaryOrdered{T, F}, y::PrimaryOrdered{T, F}) where {T, F} =
    F(x.x) < F(y.x) # do comparison with your additional state, here I assume it is a closure

const OrderR3 = PrimaryOrdered{Foo, x -> x.x % 3} # a order that order by the remainder by 3

a = OrderR3(Foo(2))
f(x::Foo) = Foo(x.x + 1) # this is a Foo -> Foo
a = map(f, a) # you can map f on a OrderR3 object
a == OrderR3(Foo(33)) # true

a = map(OrderR3 ∘ Foo, [1, 2, 3])

s = SortedSet(a)

map(x->x.x, s) # Foo[3, 1, 2]

一如既往,MWE对于更好地理解一个问题很重要。您可以包含一段代码来显示如何构造和使用SortedSet,而不是模糊的“状态”和“函数”。