Skip to content
Snippets Groups Projects
Commit 453ccdb4 authored by Alexandre's avatar Alexandre
Browse files

Add database support

parent b4b6cae6
No related branches found
No related tags found
No related merge requests found
package fr.irit.smac.amas4dc.amas;
import fr.irit.smac.amak.event.EventStore;
import fr.irit.smac.amas4dc.cluster.Cluster;
import fr.irit.smac.amas4dc.cluster.DataPoint;
import fr.irit.smac.amas4dc.cluster.DataPointFuser;
import fr.irit.smac.amas4dc.cluster.DistanceMethod;
import fr.irit.smac.amas4dc.cluster.*;
import java.util.EnumSet;
......@@ -13,9 +10,9 @@ public record MASSettings<T extends DataPoint>(
float fusionThreshold,
EnumSet<AMASOption> amasOptions,
DataPointFuser<T> dataPointFuser,
EventStore<Cluster<T>> eventStore
DataPointDatabase<T> database
) {
public MASSettings(DistanceMethod<T> distanceMethod, float fusionThreshold, EnumSet<AMASOption> amasOptions, DataPointFuser<T> dataPointFuser) {
this(distanceMethod, fusionThreshold, amasOptions, dataPointFuser, null);
this(distanceMethod, fusionThreshold, amasOptions, dataPointFuser, new DataPointDatabase<T>());
}
}
......@@ -12,8 +12,6 @@ import fr.irit.smac.amas4dc.amas.messages.RequestClusterDistanceToBeAbsorbedMess
import fr.irit.smac.amas4dc.cluster.Cluster;
import fr.irit.smac.amas4dc.cluster.DataPoint;
import fr.irit.smac.amas4dc.cluster.ExtendedCluster;
import fr.irit.smac.amas4dc.event.NewClusterEvent;
import fr.irit.smac.amas4dc.event.RemoveClusterEvent;
import lombok.Getter;
import java.text.MessageFormat;
......@@ -24,7 +22,7 @@ import java.util.logging.Logger;
public class ClusterAgent<T extends DataPoint> extends Agent<DynamicClusteringAMAS<T>, DynamicClusteringEnvironment<T>> {
@Getter
private Cluster<T> cluster;
private final Cluster<T> cluster;
private State state = State.DORMANT;
private State nextState = state;
......@@ -32,22 +30,22 @@ public class ClusterAgent<T extends DataPoint> extends Agent<DynamicClusteringAM
//region Action variables
//endregion
private final Random random = new Random();
private static final Logger logger = Logger.getLogger(ClusterAgent.class.getName());
private int amountOfCyclesWithTheSameState;
private Optional<RequestDataPointDistanceToBeAbsorbedMessage> receivedRequestDataPointDistanceToBeAbsorbedMessage = Optional.empty();
private Optional<RequestClusterDistanceToBeAbsorbedMessage> receivedRequestClusterDistanceToBeAbsorbedMessage = Optional.empty();
private Optional<InformMostSimilarMessage> receivedInformMostSimilarClusterAgentsMessage = Optional.empty();
private List<ClusterAgent<T>> requestDistanceMessageSentAgents = new ArrayList<>();
private List<ClusterAgent<T>> requestDistanceMessageSentAgents = new ArrayList<>();
protected ClusterAgent(DynamicClusteringAMAS amas, T dataPoint) {
super(amas);
if (logger.isLoggable(Level.INFO))
logger.info(this + " created");
if (amas.getMasSettings().amasOptions().contains(AMASOption.KeepAllDataPoints))
this.setCluster(new ExtendedCluster<T>(dataPoint));
cluster = new ExtendedCluster<T>(dataPoint);
else
this.setCluster(new Cluster<T>(dataPoint));
cluster = new Cluster<T>(dataPoint);
amas.getMasSettings().database().add(cluster.getRepresentative());
}
public enum State {DORMANT, WAITING_FOR_DISTANCE, DEAD}
......@@ -191,7 +189,7 @@ public class ClusterAgent<T extends DataPoint> extends Agent<DynamicClusteringAM
getCluster(),
othersSimilarClusterAgents));
destroy();
}else{
} else {
nextState = State.DORMANT;
}
}
......@@ -210,51 +208,34 @@ public class ClusterAgent<T extends DataPoint> extends Agent<DynamicClusteringAM
logger.info(this + " absorbs the data point " + otherDataPoint);
T newRepresentative = (T) amas.getMasSettings().dataPointFuser().apply(cluster.getRepresentative(), otherDataPoint);
Cluster<T> newCluster;
if (getAmas().getMasSettings().amasOptions().contains(AMASOption.KeepAllDataPoints))
newCluster = new ExtendedCluster<>(newRepresentative, otherDataPoint, cluster);
else
newCluster = new Cluster<T>(newRepresentative, otherDataPoint, cluster);
setCluster(newCluster);
cluster.setRepresentative(newRepresentative);
cluster.addDataPoint(otherDataPoint);
}
private void absorbCluster(Cluster<T> otherCluster) {
if (logger.isLoggable(Level.INFO))
logger.info(this + " absorbs the cluster " + otherCluster);
T newRepresentative = (T) amas.getMasSettings().dataPointFuser().apply(cluster.getRepresentative(), otherCluster.getRepresentative());
Cluster<T> newCluster;
if (getAmas().getMasSettings().amasOptions().contains(AMASOption.KeepAllDataPoints))
newCluster = new ExtendedCluster<>(newRepresentative, otherCluster, cluster);
else
newCluster = new Cluster<T>(newRepresentative, otherCluster, cluster);
setCluster(newCluster);
}
private void setCluster(Cluster<T> newCluster) {
if (cluster != null) {
getAmas().getEnvironment().removeFromBucket(cluster.getRepresentative().getBucketId(), this);
if (getAmas().getMasSettings().eventStore() != null)
getAmas().getMasSettings().eventStore().add(new RemoveClusterEvent(cluster));
}
cluster.setRepresentative(newRepresentative);
if (getAmas().getMasSettings().amasOptions().contains(AMASOption.KeepAllDataPoints))
((ExtendedCluster<T>) cluster).addClusterContent((ExtendedCluster<T>) otherCluster);
cluster = newCluster;
getAmas().getEnvironment().assignToBucket(cluster.getRepresentative().getBucketId(), this);
if (getAmas().getMasSettings().eventStore() != null)
getAmas().getMasSettings().eventStore().add(new NewClusterEvent(cluster));
}
@Override
protected void onDestroy() {
if (cluster != null)
if (getAmas().getMasSettings().eventStore() != null)
getAmas().getMasSettings().eventStore().add(new RemoveClusterEvent(cluster));
nextState = State.DEAD;
amas.getMasSettings().database().remove(cluster.getRepresentative());
}
private float computeDistance(T other) {
return getAmas().getMasSettings().distanceMethod().apply(this.cluster.getRepresentative(), other);
}
private float computeDistance(Cluster<T> other) {
return getAmas().getMasSettings().distanceMethod().apply(this.cluster.getRepresentative(), other.getRepresentative());
}
......
......@@ -49,6 +49,9 @@ public class DataPointAgent<T extends DataPoint> extends Agent<DynamicClustering
agent.getMailbox().receive(new RequestDataPointDistanceToBeAbsorbedMessage<T>(this, dataPoint));
requestDistanceMessageSentAgents.add(agent);
}
if (logger.isLoggable(Level.INFO))
logger.info(this + " has "+clusterAgentsRoughlySimilarOnReady.size()+" roughly similar");
}
@Override
......
......@@ -2,6 +2,7 @@ package fr.irit.smac.amas4dc.cluster;
import fr.irit.smac.amas4dc.amas.controller.MissingDataPointsException;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.ArrayList;
......@@ -12,25 +13,18 @@ import java.util.UUID;
@ToString
public class Cluster<T extends DataPoint> {
@Getter
private final String id = UUID.randomUUID().toString();
@Setter
private T representative;
@Getter
private final T representative;
@Getter
private final int size;
private int size;
public Cluster(T representative) {
this.representative = representative;
this.size = 1;
}
public Cluster(T representative, Cluster<T> c1, Cluster<T> c2) {
this.representative = representative;
this.size = c1.size + c2.size;
public void addDataPoint(T dataPoint) {
size++;
}
public Cluster(T representative, T newDataPoint, Cluster<T> c2) {
this.representative = representative;
this.size = 1 + c2.size;
}
}
package fr.irit.smac.amas4dc.cluster;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DataPointDatabase<T extends DataPoint> {
private List<T> content = new ArrayList<>();
public void add(T newDataPoint) {
content.add(newDataPoint);
}
public void remove(T dataPoint) {
content.remove(dataPoint);
}
public List<T> get() {
return Collections.unmodifiableList(content);
}
public boolean contains(T dataPoint) {
return content.contains(dataPoint);
}
}
......@@ -8,35 +8,22 @@ import java.util.List;
public class ExtendedCluster<T extends DataPoint> extends Cluster<T> {
@Getter
private final List<T> content;
private final List<T> content = new ArrayList<>();
public ExtendedCluster(T representative) {
super(representative);
this.content = Collections.singletonList(representative);
this.content.add(representative);
}
public ExtendedCluster(T representative, Cluster<T> c1, Cluster<T> c2) {
super(representative, c1, c2);
if (!(c1 instanceof ExtendedCluster<T> ec1) || !(c2 instanceof ExtendedCluster<T> ec2))
throw new ExtendedClusterException("ExtendedCluster can only be made out of two ExtendedCluster objects");
var content = new ArrayList<T>(ec1.getContent());
content.addAll(ec2.getContent());
this.content = Collections.unmodifiableList(content);
@Override
public void addDataPoint(T dataPoint) {
super.addDataPoint(dataPoint);
content.add(dataPoint);
}
public ExtendedCluster(T representative, T newDataPoint, Cluster<T> c2) {
super(representative, newDataPoint, c2);
if (!(c2 instanceof ExtendedCluster<T> ec2))
throw new ExtendedClusterException("ExtendedCluster can only be made out of an ExtendedCluster object");
var content = new ArrayList<T>();
content.add(newDataPoint);
content.addAll(ec2.getContent());
this.content = Collections.unmodifiableList(content);
public void addClusterContent(ExtendedCluster<T> otherCluster) {
for (var dp : otherCluster.getContent()) {
addDataPoint(dp);
}
}
}
package fr.irit.smac.amas4dc.event;
import fr.irit.smac.amak.event.Event;
import fr.irit.smac.amas4dc.cluster.Cluster;
import fr.irit.smac.amas4dc.cluster.DataPoint;
public record NewClusterEvent<T extends DataPoint>(Cluster<T> cluster) implements Event {
}
package fr.irit.smac.amas4dc.event;
import fr.irit.smac.amak.event.Event;
import fr.irit.smac.amas4dc.cluster.Cluster;
import fr.irit.smac.amas4dc.cluster.DataPoint;
public record RemoveClusterEvent<T extends DataPoint>(Cluster<T> cluster) implements Event {
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment