我在使用C5 IntervalHeap实现C5.IPriorityQueueHandle接口时遇到问题。我可以使用null句柄,使用默认的DeleteMin()等来使用堆精细,但我希望以后能够通过句柄更新优先级。
下面是我的代码的简化版本,以及异常文本:
例外: 类型' System.InvalidCastException'的未处理异常发生在C5.dll
附加信息:无法转换类型' Handle`1 [_8_Puzzle.Node]'输入'处理[_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!
}
}
答案 0 :(得分:1)
您正在使用C5库的句柄错误。
来自handle
方法的C5.IntervalHeap<T>.Add
参数的C5 documentation(强调我的):
输出:添加项目的句柄。输入:null用于分配新句柄,无效句柄用于重用。 重用句柄必须与此优先级队列兼容,方法是由相同运行时类型的优先级队列创建,但不一定是相同的优先级队列对象。
您没有传入优先级队列创建的句柄。您正在传递自己在Node
类构造函数中创建的句柄。
不要创建自己的IPriorityQueueHandle<T>
实现;而是依赖于从C5返回的任何句柄对象。我建议您将handle
中Node
字段的类型更改为IPriorityQueueHandle<Node>
,不要在Node
构造函数中初始化它,并更改打破行
q.Add(ref childNode.handle, childNode);
您可以删除分配给变量h
的行之前的行,Handle<T>
类也可以删除。