давний тайник, впервые спрашивающий. Я делаю проект на TSP (Задача коммивояжера) на C ++, и у меня есть небольшой вопрос. Мне нужно взять два узла (в этом сценарии называемые NodeID, они являются беззнаковыми целыми) и добавить ребро между ними в методе addEdge. Подпись вместе с некоторыми заметками от моего учителя (я запишу предварительные условия позже):
/*
* Add a weighted, undirected edge between nodes u and v.
*
* Preconditions:
* u and v are legal labels (i.e. 0 <= u < G.size(), 0 <= v < G.size())
* u != v
* There is no edge between u and v.
* weight > 0
*/
void ListGraph::addEdge(NodeID u, NodeID v, EdgeWeight weight) {
/* Code here */
}
Теперь я вижу, как кодирую это, ссылаясь на список ребер и узлов в базовом классе. Однако базовый класс является абстрактным, а список закрытым. Вот и весь этот базовый класс.
ПРИМЕЧАНИЕ: ЭТОТ КЛАСС ДОЛЖЕН ОСТАВЛЯТЬСЯ КАК ЕСТЬ (это класс учителя и один из немногих в проекте, которому я должен оставаться верным и использовать, не меняя его.)
Вот:
#include <vector>
#include "Graph.h"
#pragma once
typedef std::list<NWPair> EList;
class ListGraph : public Graph {
public:
ListGraph(int numNodes);
~ListGraph();
// Modifiers
virtual void addEdge(NodeID u, NodeID v, EdgeWeight weight);
// Inspectors
virtual EdgeWeight weight(NodeID u, NodeID v) const;
virtual std::list<NWPair> getAdj(NodeID u) const;
virtual unsigned degree(NodeID u) const;
virtual unsigned size() const;
virtual unsigned numEdges() const;
private:
ListGraph() {;}
std::vector<EList> edgeList;
int num_edges;
};
Единственный способ добавить вес к ребру между узлами — это получить доступ к этому краю и изменить его. Любые предложения будут весьма полезны.
Вот все Graph.h, если это кому-то нужно:
#include <utility>
#include <list>
#pragma once
/*
* Useful typedefs, primarily for the purpose of read-ability.
*/
typedef unsigned NodeID;
typedef double EdgeWeight;
typedef std::pair<NodeID, EdgeWeight> NWPair;class Graph {
public:
virtual ~Graph() {}
/*
* Add a weighted, undirected edge between nodes u and v.
*
* Preconditions:
* u and v are legal labels (i.e. 0 <= u < G.size(), 0 <= v < G.size())
* u != v
* There is no edge between u and v.
* weight > 0
*/
virtual void addEdge(NodeID u, NodeID v, EdgeWeight weight) = 0;/*
* Get the weight between nodes u and v; return 0 if there is no edge.
*
* Preconditions:
* u and v are legal labels (i.e. 0 <= u < G.size(), 0 <= v < G.size())
*/
virtual EdgeWeight weight(NodeID u, NodeID v) const = 0;
/*
* Return a list of NodeID/EdgeWeight pairs describing the nodes adjacent to edge w.
*
* Preconditions: u is a legal label.
*/
virtual std::list<NWPair> getAdj(NodeID u) const = 0;
/*
* Return the degree (i.e. the number of neighorbs) of node u.
*
* Preconditions: u is a legal label;
*/
virtual unsigned degree(NodeID u) const = 0;
/*
* Return the number of nodes in the graph.
*/
virtual unsigned size() const = 0;
/*
* Return the number of edges in the graph.
*/
virtual unsigned numEdges() const = 0;
};
Как я уже сказал, любая помощь будет принята с благодарностью. Спасибо!
редактирование: попытка ссылки на edgeList с помощью «ListGraph :: edgeList» в методе «ListGraph :: addEdge» приводит к ошибке. Когда я удерживаю курсор, он говорит это:
Ошибка: класс «ListGraph» не имеет члена «edgeList»
редактировать 2: этот код в трех файлах.
Graph.h: неизменяемый, абстрактный; где все методы
ListGraph.h: неизменяемый, в основном абстрактный; где edgeList и num_edges (это частные)
ListGraph.cpp: где я буду помещать свой код, и, по-видимому, где я не могу получить доступ к закрытым переменным, таким как edgeList и num_edges
edit 3: Я ИДИОТ, я поместил все методы в ListGraph.cpp в класс с именем ListGraph, поэтому программа искала ListGraph.cpp, а не ListGraph.h. Извините, потраченное впустую время, удалите это, если хотите, или я скоро. Спасибо, ребята, еще раз извините.
Я думаю, что вы просто неправильно понимаете структуру здесь, или, может быть, я понимаю.
Насколько я понимаю, вы собираетесь поместить код в
addEdge()
метод в
class ListGraph
Это дает вам доступ к закрытой переменной «edgeList».
Абстрактный класс — это класс «Graph», который наследует «ListGraph». Однако закрытые переменные в ListGraph доступны для класса ListGraph.
Ваша логика в порядке, однако я думаю, что вы неправильно поняли «ПРИМЕЧАНИЕ: ЭТОТ КЛАСС
/* Code here */
в методе addEdge я уверен, что вы можете редактировать его! 🙂
В этом случае, Graph
это базовый класс, а не ListGraph
, поэтому я не уверен, что ваше описание является точным, но, насколько я понимаю, вы реализуете ListGraph::addEdge()
.. так что вы можете просто получить доступ ListGraph::edgeList
,
Базовый класс Graph
на самом деле просто указывает, что вы должны предоставить, когда вы извлекаете из него — вот почему его функции «чисто виртуальные». Класс ListGraph
где данные и где вы собираетесь определить функцию addEdge
, В этой функции у вас будет доступ на чтение / запись к edgeList
, Попробуйте, это сработает.