#pragma once
#include <string>
template<typename T>
class Vertex
{
private:
int Index;
T _data;
public:
Vertex();
Vertex(T data);
~Vertex();
int IndexGet();
void IndexSet(int index);
T Data();
std::string toString();
};
template<typename T>
Vertex<T>::Vertex()
{
}
template<typename T>
Vertex<T>::Vertex(T data)
{
_data = data;
Index = -1;
}
template<typename T>
Vertex<T>::~Vertex()
{
}
template<typename T>
int Vertex<T>::IndexGet()
{
return Index;
}
template<typename T>
void Vertex<T>::IndexSet(int index)
{
Index = index;
}
template<typename T>
T Vertex<T>::Data()
{
return _data;
}
template<typename T>
std::string Vertex<T>::toString()
{
return "{Vertex} " + _data;
}
=======================================
#pragma once
#include <vector>
class AdjacencyMatrix
{
private:
int _size;
std::vector<std::vector<float> > _matrix;
public:
AdjacencyMatrix() {};
AdjacencyMatrix(int size=0);
~AdjacencyMatrix();
int Size();
void AddDirectedEdge(int from, int to , float weight);
void AddUndirectedEdge(int v1, int v2, float weight);
float GetEdgeWeight(int x, int y);
std::vector<int> GetAdjacencyList(int sourceIndex);
};
AdjacencyMatrix::AdjacencyMatrix(int size) :_size(size)
{
std::vector< std::vector<float> > tmpVec(size, std::vector<float>(size));
_matrix = tmpVec;
}
AdjacencyMatrix::~AdjacencyMatrix()
{
}
int AdjacencyMatrix::Size()
{
return _size;
}
void AdjacencyMatrix::AddDirectedEdge(int from, int to, float weight)
{
_matrix[from][to] = weight;
}
void AdjacencyMatrix::AddUndirectedEdge(int v1, int v2, float weight)
{
_matrix[v1][v2] = weight;
_matrix[v2][v1] = weight;
}
float AdjacencyMatrix::GetEdgeWeight(int x, int y)
{
return _matrix[x][y];
}
std::vector<int> AdjacencyMatrix::GetAdjacencyList(int sourceIndex)
{
std::vector<int> adjacenceList;
for (int i = 0; i < _size; i++) {
if (_matrix[sourceIndex][i] != 0) {
adjacenceList.push_back(i);
}
}
return adjacenceList;
}
==================================================
#pragma once
class AdjacencyMatrix;
template<typename T>
class Graph
{
private:
std::vector<Vertex<T>*> _vertices;
AdjacencyMatrix* _adjacencyMatrix;
public:
Graph() {};
Graph(std::vector<Vertex<T>*> vertices);
~Graph();
std::vector<Vertex<T>*> Vertices();
void CreateDirectedEdge(int fromIndex, int toIndex, float weight);
void CreateDirectedEdge(Vertex<T> from, Vertex<T> to, float weight);
void CreateUndirectedEdge(int v1, int v2, float weight);
void CreateUndirectedEdge(Vertex<T> v1, Vertex<T> v2, float weight);
std::vector<Vertex<T>*> GetAdjacentVertices(int sourceIndex);
std::vector<Vertex<T>*> GetAdjacentVertices(Vertex<T> source);
float GetEdgeWeight(Vertex<T> v1, Vertex<T> v2);
std::string toString();
};
#include <vector>
#include <string>
#include "AdjacencyMatrix.h"
#include "Vertex.h"
//#include "Graph.h"
template<typename T>
Graph<T>::Graph(std::vector<Vertex<T>*> vertices)
{
_vertices = vertices;
for (int i = 0; i < _vertices.size(); i++) {
_vertices.at(i)->IndexSet(i);
}
_adjacencyMatrix = new AdjacencyMatrix(_vertices.size());
}
template<typename T>
Graph<T>::~Graph()
{
delete _adjacencyMatrix;
}
template<typename T>
std::vector<Vertex<T>*> Graph<T>::Vertices()
{
return _vertices;
}
template<typename T>
void Graph<T>::CreateDirectedEdge(int fromIndex, int toIndex, float weight) {
if (weight == 0) {
weight = 1;
}
_adjacencyMatrix->AddDirectedEdge(fromIndex, toIndex, weight);
}
template<typename T>
void Graph<T>::CreateDirectedEdge(Vertex<T> from, Vertex<T> to, float weight) {
if (weight == 0) {
weight = 1;
}
this->CreateDirectedEdge(from.IndexGet(), to.IndexGet(), weight);
}
template<typename T>
void Graph<T>::CreateUndirectedEdge(int v1, int v2, float weight) {
if (weight == 0) {
weight = 1;
}
_adjacencyMatrix->AddUndirectedEdge(v1, v2, weight);
}
template<typename T>
void Graph<T>::CreateUndirectedEdge(Vertex<T> v1, Vertex<T> v2, float weight) {
if (weight == 0) {
weight = 1;
}
this->CreateUndirectedEdge(v1.IndexGet(), v2.IndexGet(), weight);
}
template<typename T>
std::vector<Vertex<T>*> Graph<T>::GetAdjacentVertices(int sourceIndex) {
std::vector<int> adjacentIndices = _adjacencyMatrix->GetAdjacencyList(sourceIndex);
std::vector<Vertex<T>*> adjacentVertices;
for (int vertexIndex : adjacentIndices) {
adjacentVertices.push_back(_vertices.at(vertexIndex));
}
return adjacentVertices;
}
template<typename T>
std::vector<Vertex<T>*> Graph<T>::GetAdjacentVertices(Vertex<T> source) {
return GetAdjacentVertices(source.IndexGet());
}
template<typename T>
float Graph<T>::GetEdgeWeight(Vertex<T> v1, Vertex<T> v2) {
return _adjacencyMatrix->GetEdgeWeight(v1.IndexGet(), v2.IndexGet());
}
template<typename T>
std::string Graph<T>::toString() {
std::string sb;
sb.append("Graph: \n");
for (Vertex<T>* vertex : _vertices) {
sb.append(vertex->Data());
sb.append("\t");
std::vector<Vertex<T>*> adjacentVertices = GetAdjacentVertices(*vertex);
if (adjacentVertices.size() > 0) {
sb.append("Edge to: ");
for (Vertex<T>* adjVertex : adjacentVertices) {
sb.append(adjVertex->Data());
sb.append("(w=");
sb.append(std::to_string(GetEdgeWeight(*vertex, *adjVertex)));
sb.append(") ");
}
}
else {
sb.append("No outgoing edges");
}
sb.append("\n");
}
return sb;
}
=============================================
#include <iostream>
#include <vector>
#include <string>
#include "Vertex.h"
#include "Graph.h"
int main()
{
std::cout << "Graphs" << std::endl;
//auto* v1 = new Vertex<std::string>("v1");
//std::string xxx = v1->toString();
//std::cout << xxx << std::endl;
Vertex<std::string>* v1 = new Vertex<std::string>("v1");
Vertex<std::string>* v2 = new Vertex<std::string>("v2");
Vertex<std::string>* v3 = new Vertex<std::string>("v3");
Vertex<std::string>* v4 = new Vertex<std::string>("v4");
std::vector<Vertex<std::string>*> vertices;
vertices.push_back(v1);
vertices.push_back(v2);
vertices.push_back(v3);
vertices.push_back(v4);
Graph<std::string>* graph = new Graph<std::string>(vertices);
graph->CreateDirectedEdge(*v1, *v2, 3);
graph->CreateDirectedEdge(*v4, *v1, 1);
graph->CreateDirectedEdge(*v2, *v3, 1);
graph->CreateDirectedEdge(*v2, *v4, -5);
std::cout << graph->toString() << std::endl;
std::cout << "End " << std::endl;
delete graph;
return 0;
}
Graph:
v1 Edge to: v2(w=3.0)
v2 Edge to: v3(w=1.0) v4(w=-2.0)
v3 No edges
v4 Edge to: v1(w=1.0)