помогите с классами c ++, указатели такие - PullRequest
0 голосов
/ 17 июля 2011

У меня есть проект, в котором я реализую алгоритм кратчайшего пути Дейкстры с использованием классов C ++. Он использует OpenGL, но это, безусловно, отдельно от моих проблем. Мне нужно немного понять, что я делаю неправильно в моем методе класса Дейкстры. Вот мой соответствующий код:

class Node {
    public: 
        GLfloat x, y, z;
        int numLinks;
        Node *link1;
        Node *link2;
        GLfloat distance;
        Node *previous;

        Node(GLfloat x, GLfloat y, Node *link1, Node *link2);
        Node(GLfloat x, GLfloat y, Node *link1);
        Node();
        Node(GLfloat x, GLfloat y);
        ~Node();

        bool dijkstra(Node* graph[], Node *source, Node *target); //returns true if a path to target is found
        int dist(Node &n1, Node &n2);
};

int Node::dist(Node &n1, Node &n2) {
    GLfloat d = sqrt((pow((n2.x - n1.x), 2)) + (pow((n2.y - n1.y), 2)));
    return d;
}

bool Node::dijkstra(Node* graph[], Node *source, Node *target) {
    queue<Node> q;
    int i;
    for (i = 0; i < NUM_NODES; i++) {
        graph[i]->distance = INFIN;
    }
    source->distance = 0;   
    i = 0;
    q.push(*source);
    while (!q.empty()) {
        Node temp = q.front();

        GLfloat d1 = dist(temp, temp->link1);
        GLfloat d2 = dist(temp, temp->link2);
        temp.link1.distance = d1;
        temp.link1.distance = d2;

        GLfloat alt = temp.distance + temp->link1.distance;
        if (alt < temp->link1.distance) {
            temp->link1.distance = alt;
            temp->previous = temp;
        }

        alt = temp->distance + temp->link2->distance;
        if (alt < temp->link2->distance) {
            temp->link2->distance = alt;
            temp->previous = temp;
        }

        if(d1 > d2) {
            q.push(temp->link2);
            q.push(temp->link1);
        } else {
            q.push(temp->link1);
            q.push(temp->link2);
        }
        q.pop();
        i++;
    }

    return true;
}

Я предполагаю, что я использую "->" и "." операторы все неправильно. Я получаю много таких ошибок, когда пытаюсь скомпилировать:

error: base operand of ‘->’ has non-pointer type ‘Node’

Моя реализация алгоритма Дейкстры несколько модифицирована для удовлетворения моих потребностей и, вероятно, ошибочна, но мне нужно это скомпилировать, чтобы я мог отладить его.

Указанный код - единственный код, вызывающий у меня горе, но если вы хотите увидеть другую его часть, просто спросите. Будем весьма благодарны за хорошее объяснение того, что я делаю неправильно.

Ответы [ 2 ]

0 голосов
/ 17 июля 2011

Некоторые вопросы по вашему дизайну:

dijkstra действительно метод, который можно применить к узлу?

Кажется, что это операция, которая применяется к графу какцелое.

class Graph
{
    std::vector<NodeId> dijkstra(NodeId const& start, NodeId const& target);
};

Что такое previous?

Кажется, что узел имеет некоторый внутренний указатель, который просто используется для алгоритма Node *previous; Узел не должен содержать информацию такого типа.

Line1 / Link2

Означает ли это, что узлы могут связываться только с двумя другими узлами.Не похоже, что это график, но больше похож на дерево?

class Node
{
    std::vector<LinkId>   links;
};

Итак, моя отправная точка будет такой:

class Graph
{
    class Link
    {
          NodeId   src;
          NodeId   dst;
          float    dist; // only calculate once for each link
    };
    class Node
    {
          float   x,y;
          std::vector<boost::shard_ptr<Link> >   links;
    };
    typedef  std::vector<Node>   GraphContainer;
    GraphContainer   graphPoints;

    public:
       typedef GraphContainer::size_type  NodeId;

       NodeId   addNode(float x, float y);
       void     link(NodeId& p1, NodeId& p2);

       std::vector<NodeId> dijkstra(NodeId const& start, NodeId const& target);
};

Теперь все должно быть намного проще писать чисто.

0 голосов
/ 17 июля 2011

Вы должны использовать оператор «->» при доступе к данным через указатель.В противном случае вы должны использовать «.»opearator.

Например, следующие строки идентичны

Node *node = &q.front();

(*node).link1->distance = 1;
node1->link1->distance = 1;

Что касается ваших проблем компиляции, проблема в том, как вы обращаетесь к temp.temp объявлен как

Node temp = q.front();

. Это означает, что temp является копией узла в начале очереди и не является указателем на него.Вот почему компилятор жалуется, когда вы пытаетесь получить к нему доступ, как к указателю.Например:

temp->link1.distance = alt;

должно выглядеть как

temp.link1->distance = alt;

, потому что temp не указатель, а link1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...