104 lines
4.1 KiB
C++
104 lines
4.1 KiB
C++
#include "cluster.hpp"
|
|
#include <iostream>
|
|
int cluster::counter = 0;
|
|
cluster::cluster() {
|
|
_id = ++counter;
|
|
}
|
|
|
|
cluster::cluster(
|
|
int label, cluster* parent, double birthLevel,
|
|
int numPoints) //: Label(label), Parent(parent), _birthLevel(birthLevel), _numPoints(numPoints)
|
|
{
|
|
_id = ++counter;
|
|
_deathLevel = 0;
|
|
|
|
_propagatedStability = 0;
|
|
_numConstraintsSatisfied = 0;
|
|
_propagatedNumConstraintsSatisfied = 0;
|
|
|
|
Parent = parent;
|
|
Label = label;
|
|
_birthLevel = birthLevel;
|
|
_numPoints = numPoints;
|
|
HierarchyPosition = 0;
|
|
Stability = 0;
|
|
PropagatedLowestChildDeathLevel = std::numeric_limits<double>::max();
|
|
|
|
if (Parent != NULL)
|
|
Parent->HasChildren = true;
|
|
HasChildren = false;
|
|
PropagatedDescendants.resize(0);
|
|
}
|
|
bool cluster ::operator==(const cluster& other) const {
|
|
return (this->_id == other._id);
|
|
}
|
|
void cluster::detachPoints(int numPoints, double level) {
|
|
_numPoints -= numPoints;
|
|
Stability += (numPoints * (1 / level - 1 / _birthLevel));
|
|
|
|
if (_numPoints == 0)
|
|
_deathLevel = level;
|
|
else if (_numPoints < 0)
|
|
throw std::invalid_argument("Cluster cannot have less than 0 points.");
|
|
}
|
|
|
|
void cluster::propagate() {
|
|
if (Parent != NULL) {
|
|
if (PropagatedLowestChildDeathLevel == std::numeric_limits<double>::max())
|
|
PropagatedLowestChildDeathLevel = _deathLevel;
|
|
if (PropagatedLowestChildDeathLevel < Parent->PropagatedLowestChildDeathLevel)
|
|
Parent->PropagatedLowestChildDeathLevel = PropagatedLowestChildDeathLevel;
|
|
if (!HasChildren) {
|
|
Parent->_propagatedNumConstraintsSatisfied += _numConstraintsSatisfied;
|
|
Parent->_propagatedStability += Stability;
|
|
Parent->PropagatedDescendants.push_back(this);
|
|
} else if (_numConstraintsSatisfied > _propagatedNumConstraintsSatisfied) {
|
|
Parent->_propagatedNumConstraintsSatisfied += _numConstraintsSatisfied;
|
|
Parent->_propagatedStability += Stability;
|
|
Parent->PropagatedDescendants.push_back(this);
|
|
} else if (_numConstraintsSatisfied < _propagatedNumConstraintsSatisfied) {
|
|
Parent->_propagatedNumConstraintsSatisfied += _propagatedNumConstraintsSatisfied;
|
|
Parent->_propagatedStability += _propagatedStability;
|
|
Parent->PropagatedDescendants.insert(Parent->PropagatedDescendants.end(),
|
|
PropagatedDescendants.begin(),
|
|
PropagatedDescendants.end());
|
|
} else if (_numConstraintsSatisfied == _propagatedNumConstraintsSatisfied) {
|
|
// Chose the parent over descendants if there is a tie in stability:
|
|
if (Stability >= _propagatedStability) {
|
|
Parent->_propagatedNumConstraintsSatisfied += _numConstraintsSatisfied;
|
|
Parent->_propagatedStability += Stability;
|
|
Parent->PropagatedDescendants.push_back(this);
|
|
} else {
|
|
Parent->_propagatedNumConstraintsSatisfied += _propagatedNumConstraintsSatisfied;
|
|
Parent->_propagatedStability += _propagatedStability;
|
|
Parent->PropagatedDescendants.insert(Parent->PropagatedDescendants.end(),
|
|
PropagatedDescendants.begin(),
|
|
PropagatedDescendants.end());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void cluster::addPointsToVirtualChildCluster(std::set<int> points) {
|
|
for (std::set<int>::iterator it = points.begin(); it != points.end(); ++it) {
|
|
_virtualChildCluster.insert(*it);
|
|
}
|
|
}
|
|
bool cluster::virtualChildClusterConstraintsPoint(int point) {
|
|
return (_virtualChildCluster.find(point) != _virtualChildCluster.end());
|
|
}
|
|
|
|
void cluster::addVirtualChildConstraintsSatisfied(int numConstraints) {
|
|
_propagatedNumConstraintsSatisfied += numConstraints;
|
|
}
|
|
|
|
void cluster::addConstraintsSatisfied(int numConstraints) {
|
|
_numConstraintsSatisfied += numConstraints;
|
|
}
|
|
|
|
void cluster::releaseVirtualChildCluster() {
|
|
_virtualChildCluster.clear();
|
|
}
|
|
|
|
int cluster::getClusterId() {
|
|
return this->_id;
|
|
}
|