0

我在使用 C5 IntervalHeap 实现 C5.IPriorityQueueHandle 接口时遇到问题。我可以将堆与空句柄一起使用,使用默认的 DeleteMin() 等,但我希望以后能够通过句柄更新优先级。

下面是我的代码的简化版本,以及异常文本:

异常:C5.dll 中出现“System.InvalidCastException”类型的未处理异常

附加信息:无法将类型为“Handle`1[_8_Puzzle.Node]”的对象转换为类型“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!

        }
    }
4

1 回答 1

1

您错误地使用了 C5 库的句柄。

来自方法参数的C5文档强调我的):handleC5.IntervalHeap<T>.Add

输出时:添加项目的句柄。输入时:null 用于分配新句柄,无效句柄用于重用。重用句柄必须与此优先级队列兼容,由相同运行时类型的优先级队列创建,但不一定是相同的优先级队列对象。

您没有传入由优先级队列创建的句柄。Node您正在传递您在类的构造函数中创建的自己的句柄。

不要创建自己的IPriorityQueueHandle<T>; 而是依赖于从 C5 返回的任何句柄对象。我建议您将handle字段的类型更改NodeIPriorityQueueHandle<Node>,不要在Node构造函数中对其进行初始化,并将断行上的调用更改为

        q.Add(ref childNode.handle, childNode);

可以删除之前分配给变量的行,h您的类也可以删除Handle<T>

于 2017-01-13T21:12:43.270 回答