You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
4.6 KiB
C++

/*
* graph implementation
*
* Copyright (C) Dorit Borrmann, Jan Elseberg, Kai Lingemann, Andreas Nuechter
*
* Released under the GPL version 3.
*
*/
/**
* @file
* @brief The implementation of a graph
* @author Dorit Borrman. Institute of Computer Science, University of Osnabrueck, Germany.
* @author Jan Elseberg. Institute of Computer Science, University of Osnabrueck, Germany.
* @author Kai Lingemann. Institute of Computer Science, University of Osnabrueck, Germany.
* @author Andreas Nuechter. Institute of Computer Science, University of Osnabrueck, Germany.
*/
#include "slam6d/graph.h"
#include "slam6d/scan.h"
#include "slam6d/globals.icc"
#include <fstream>
using std::ifstream;
#include <iostream>
using std::cout;
using std::cerr;
using std::endl;
/**
* Constructor to create an empty graph
*/
Graph::Graph()
{
nrScans = 0;
start = 0;
}
/**
* Constructor to read a Graph from a file.
* The file must have the the number of scans in the first line,
* the number of links to be read in the second and the links in
* the links in the third and fourth line
*
* Example:
* 4
* 3
* 0 1
* 1 2
* 3 4
* 4 0
*
* @param netfile Filename of the file to read
*/
Graph::Graph(const string &netfile)
{
nrScans = 0;
start = 0;
int local_nrScans, local_nrLinks;
cout << "Reading network " << netfile;
ifstream file(netfile.c_str());
file >> local_nrScans
>> local_nrLinks;
int f, t;
for(int j = 0; j < local_nrLinks; j++) {
if (!file.good()) {
cerr << "Error while reading network structure" << endl;
exit(1);
}
file >> f >> t;
cout << f << " " << t << endl;
addLink(f, t);
}
cout << " structure done." << endl;
}
/**
* Constructor to build a minimally connected Graph with a given number of scans.
* The loop can optionally be closed, so that the first will be connected to the last scan.
*
* @param nScans The number of Scans
* @param loop Specifies whether the first and last scan should be linked
*/
Graph::Graph(int nScans, bool loop)
{
int nrLinks = 0;
start = 0;
nrScans = nScans;
if (loop) {
nrLinks = nScans;
} else {
nrLinks = nScans - 1;
}
for(int i = 0 ;i < nrLinks; i++){
from.push_back(i);
if (loop) {
to.push_back(i != nrLinks - 1 ? i + 1 : 0) ;
} else {
to.push_back(i + 1);
}
}
}
Graph::Graph(int nodes, double cldist2, int loopsize)
{
// nodes + 1
start = 0;
nrScans = nodes;
int nrLinks = nodes - 1;
for(int i = 0; i < nrLinks; i++){
from.push_back(i);
to.push_back(i + 1);
}
// nodes
for (int j = 0; j < nodes; j++) {
for (int k = j + 1; k < nodes; k++) {
if ((abs(k-j) > loopsize) &&
(Dist2(Scan::allScans[j]->get_rPos(), Scan::allScans[k]->get_rPos()) < cldist2)) {
addLink(j, k);
}
}
}
}
/**
* Returns the specified link
*
* @param i The i-th link
* @param fromTo 0 is the outgoing node and 1 the ingoing
* @return An integer for the node
*/
int Graph::getLink(int i, int fromTo)
{
if (i >= 0 && i < (int)from.size()) {
if (fromTo == 0) return from[i];
else return to[i];
}
return 0;
}
/**
* adds a link to a graph
*
* @param i from node
* @param j to node
*/
void Graph::addLink(int i, int j)
{
int present = 0;
for (unsigned int iterator = 0; iterator < from.size(); iterator++) {
if (from[iterator] == i) present++;
if (to[iterator] == i) present++;
}
if (present == 0) nrScans++;
present = 0;
for (unsigned int iterator = 0; iterator < from.size(); iterator++) {
if (from[iterator] == j) present++;
if (to[iterator] == j) present++;
}
if (present == 0) nrScans++;
from.push_back(i);
to.push_back(j);
}
/**
* Returns the number of links
* @return number of links
*/
int Graph::getNrLinks()
{
return from.size();
}
/**
* Returns the number of scans
* @return number of scans
*/
int Graph::getNrScans()
{
return nrScans;
}
/**
* sets the number of scans
* @param number of scans
*/
void Graph::setNrScans(int _nrScans)
{
nrScans = _nrScans;
}
/**
* Returns the number of the first scan
* @return number of the first scan
*/
int Graph::getStart()
{
return start;
}
/**
* Returns the number of the last scan
* @return number of the last scan
*/
int Graph::getEnd()
{
return start+nrScans - 1;
}
/**
* Prints out the Graph nicely formatted
* @param os the stream to print to
* @param gr which Graph to print
* @return the resulting output stream
*/
ostream& operator<<(ostream& os, Graph* gr)
{
for(int i = 0; i < (int)gr->from.size() ; i++){
os << "( " << gr->getLink(i,0) << " - " << gr->getLink(i,1) << " )" << endl;
}
return os;
}