2013-02-13 3 views
0

PriorityQueue이 포함 된 데이터 구조를 만들려고합니다. 나는 그것의 비 제네릭 버전을 만드는 데 성공했습니다. 나는 그것이 A.I.를 해결하기 때문에 효과가 있다고 말할 수 있습니다. 내가 가진 문제.
여기 그것의 조각입니다 :암시 적으로 PriorityQueue (Scala)를 사용하여 문제가 발생했습니다.

class ProntoPriorityQueue { //TODO make generic 

implicit def orderedNode(node: Node): Ordered[Node] = new Ordered[Node] { 
    def compare(other: Node) = node.compare(other) 
} 

val hashSet = new HashSet[Node] 
val priorityQueue = new PriorityQueue[Node]() 
... 

나는 그것이 일반적인 만들려고 노력하고있어,하지만이 버전을 사용하는 경우이 문제를 해결 중지 :

class PQ[T <% Ordered[T]] { 
//[T]()(implicit val ord: T => Ordered[T]) { 
//[T]()(implicit val ord: Ordering[T] { 

val hashSet = new HashSet[T] 
val priorityQueue = new PriorityQueue[T] 
... 

나는 또한 무엇을 시도했다가

//the following def is commented out while using ProntoPriorityQueue 
implicit def orderedNode(node: Node): Ordered[Node] = new Ordered[Node] { 
    def compare(other: Node) = node.compare(other) 
} //I've also tried making this return an Ordering[Node] 

val frontier = new PQ[Node] //new ProntoPriorityQueue 
//have also tried (not together): 
val frontier = new PQ[Node]()(orderedNode) 
01 : 대신 여기

[T <% Ordered[T]]을 사용하는 주석이 PQ를 호출하는 코드입니다

나는 암시적인 def를 Node 객체로 옮겨 보았습니다. (그리고 가져 오는 것), 근본적으로 같은 문제입니다.

일반 버전에서 내가 뭘 잘못하고 있니? 어디에서 암시 적으로 넣어야합니까?


솔루션 문제는 내 내재 된 정의하지이었다. 문제는 for(...) yield(...) 문에서 자동으로 생성 된 Set에 의해 암시 적 정렬이 선택되었습니다. 이로 인해 yield 된 집합에 하나의 상태 만 포함 된 문제가 발생했습니다.

답변

1

단순히 상에 Ordering을 정의 뭐가 잘못하여 Node (Ordering[Node])와 이미 일반적인 스칼라 PriorityQueue를 사용하고 계십니까?

일반적으로 Ordering[T]으로 작업하는 것이 T <: Ordered[T] 또는 T <% Ordered[T]보다 좋습니다. 개념적으로 Ordered[T]은 유형 자체의 내장 (상속되거나 구현 된) 속성입니다. 특히, 형식은이 방식으로 정의 된 하나의 고유 한 순서 관계 만 가질 수 있습니다. Ordering[T]은 주문 관계의 외부 사양입니다. 임의의 숫자가 다를 수 있습니다 Ordering[T].

T <% U의 차이는 명목 하위 유형 관계 (실제 상속) 만 포함하는 반면, 후자는 명목상의 하위 유형 관계 (실제 상속) 형태 바운드를 따르는 값

그래서 당신은 Node <% Ordered[Node]을 사용하려는 당신이 클래스에 정의 된 compare 방법이없는 경우, 암시 적 변환은 에게 비교을 할 필요가 때마다 적용됩니다. 또한 유형이 인 경우 자체의 compare 인 경우 암시 적 변환이 적용되지 않으며 해당 "기본 제공"순서로 고정됩니다.

부록

나는 단순히 String 및 사례 불변으로 주문 구현을 캡슐화 CIString를 호출, 클래스에 따라 몇 가지 예를주지

.

/* Here's how it would be with direct implementation of `Ordered` */ 

class CIString1(val s: String) 
extends Ordered[CIString1] 
{ 
    private val lowerS = s.toLowerCase 

    def compare(other: CIString1) = lowerS.compareTo(other.lowerS) 
} 

/* An uninteresting, empty ordered set of CIString1 
    (fails without the `extends` clause) */ 
val os1 = TreeSet[CIString1]() 


/* Here's how it would look with ordering external to `CIString2` 
    using an implicit conversion to `Ordered` */ 

class CIString2(val s: String) { 
    val lowerS = s.toLowerCase 
} 

class CIString2O(ciS: CIString2) 
extends Ordered[CIString2] 
{ 
    def compare(other: CIString2) = ciS.lowerS.compareTo(other.lowerS) 
} 

implicit def cis2ciso(ciS: CIString2) = new CIString2O(ciS) 

/* An uninteresting, empty ordered set of CIString2 
    (fails without the implicit conversion) */ 
val os2 = TreeSet[CIString2]() 


/* Here's how it would look with ordering external to `CIString3` 
    using an `Ordering` */ 

class CIString3(val s: String) { 
    val lowerS = s.toLowerCase 
} 

/* The implicit object could be replaced by 
    a class and an implicit val of that class */ 
implicit 
object CIString3Ordering 
extends Ordering[CIString3] 
{ 
    def compare(a: CIString3, b: CIString3): Int = a.lowerS.compareTo(b.lowerS) 
} 

/* An uninteresting, empty ordered set of CIString3 
    (fails without the implicit object) */ 
val os3 = TreeSet[CIString3]() 
+0

내 노드에서'Ordering [Node]'를 확장하려고 시도했습니다. 'Node (노드) '와 관련된 다른 메소드 호출에서 많은 문제가 발생했습니다. 다음은 일부입니다. 그들 : - 충분하지 인수 - 유형 \t scala.collection.generic.CanBuildFrom에 대한 암시 적 확장을 발산 [main.Moves.ValueSet이 옵션은 [main.Node, 그건]이 객체의 방법 \t newCanBuildFrom로 시작하는이 \t를 SortedSet의 메서드 맵 : (암시 적 bf : \t scala.collection.generic.CanBuildFrom [main.Moves.ValueSet, 옵션 [main.Node], 그]]) 그. 지정되지 않은 값 \t 매개 변수 bf – Tombstone

+0

@ 툼 스톤 :'Node' 클래스를'Ordering [Node]'로 확장시키지 않으면'Node'의 순서 관계를 정의하는'Ordering [Node]'를 확장하는 클래스를 정의합니다. 'compare' 메소드를 정의합니다. –

+0

Ordering [Node]를 확장 한 새로운 클래스를 만들었습니다. 고맙습니다. 나는 아직도 implicits에 관한 질문이있다. 어떻게 내 이전 implicits 작동하지 않았다? '암시 데프 nodeOrderer 주문할 [노드] 새로운 순서 = [노드] { \t DEF 비교 (일부 : 노드 기타 : 기지국) = some.compare (기타) }' '암시 브로 ordN 주문할 [노드 ] – Tombstone

0

음, 하나의 가능한 문제는 Ordered[Node] 아니라고하는 Node :

implicit def orderedNode(node: Node): Ordered[Node] = new Ordered[Node] { 
    def compare(other: Node) = node.compare(other) 
} 

난 당신이 시도했지만 많은이없는 말을 대신 Ordering[Node]으로 시도 것 더 많은 정보. PQPQ[T : Ordering]으로 선언됩니다.

+0

'PQ' 정의를 'class PQ [T : Ordering] {...' }으로 바꿨고 내 암시적인 def를 다음과 같이 변경했습니다 : 'implicit def orderedNode : Ordering [Node] = 새로운 Ordering [Node] { def compare (일부 : Node, other : Node) = some.compare (other) } 여전히 작동하지 않습니다. – Tombstone

+0

알고리즘에 의존하는 알고리즘이 더 이상 작동하지 않습니다. 알고리즘의 버그로 의심됩니다. "Y를 할 때 X를하고, 대신 Z를해야합니다"라는 것이 없다면, 우리가 할 수있는 것은 추측입니다. –

+0

알고리즘에 문제가있을 수 있지만 몇 가지 이유가있을 수 있습니다. 1.) 그것은 탐색 된 집합 (LIFO, FIFO)에 대한 다른 데이터 구조와 탐색 된 집합이없는 경우에도 내 그래프 검색 알고리즘을 기반으로합니다. 최대 차이는 스택 대기열에서 우선 순위 대기열로 변경됩니다 3.) 나는 비 제네릭 (non-generic, non-generic, non-implicit) 버전의 데이터 구조를 사용하여 작업했다. 알고리즘의 모든 관련 정보를 넣으려면 수백 줄이 필요합니다. https://www.dropbox.com/s/lw63j1vq8k94mu4/tombstone%20src.zip – Tombstone

관련 문제