I'm having issues implementing the C5.IPriorityQueueHandle interface with the C5 IntervalHeap. I can use the heap fine with null handles, using the default DeleteMin(), etc., but I want to be able to update the priority by the handle later.
A simplified version of my code is below, together with the exception text:
Exception: An unhandled exception of type 'System.InvalidCastException' occurred in C5.dll
Additional information: Unable to cast object of type 'Handle`1[_8_Puzzle.Node]' to type 'Handle[_8_Puzzle.Node]'.
public class Node : IComparable<Node>
{
public Board board;
public Handle<Node> handle;
public Node(Board b)
{
this.board = b;
this.handle = new Handle<Node> (b.Id);
}
...
}
public class Handle<Node> : C5.IPriorityQueueHandle<Node>
{
private int id;
public Handle(int id)
{
this.id = id;
}
}
static void doWork(Node rootNode)
{
C5.IntervalHeap<Node> q = new C5.IntervalHeap<Node>();
q.Add(rootNode); //works fine, handle is null
...
Board child = getChild(rootNode);
if (someConditionIsMet) {
Node childNode = new Node(child);
C5.IPriorityQueueHandle<Node> h = (C5.IPriorityQueueHandle<Node>)(childNode.handle);
q.Add(ref h, childNode); //breaking line!
}
}
You are using handles with the C5 library incorrectly.
From the C5 documentation for the
handle
parameter of theC5.IntervalHeap<T>.Add
method (emphasis mine):You are not passing in a handle created by a priority queue. You are passing in your own handles that you create in the
Node
class's constructor.Don't create your own implementation of
IPriorityQueueHandle<T>
; rely instead on whatever handle objects you get back from C5. I would recommend you change the type of thehandle
field withinNode
toIPriorityQueueHandle<Node>
, don't initialise it in theNode
constructor, and change the call on the breaking line toThe line before, where you assign to the variable
h
, can be deleted, as can yourHandle<T>
class.