it.unibo.alchemist.model.sapere.actions.LsaAscendingAgent Maven / Gradle / Ivy
Show all versions of alchemist-incarnation-sapere Show documentation
/*
* Copyright (C) 2010-2023, Danilo Pianini and contributors
* listed, for each module, in the respective subproject's build.gradle.kts file.
*
* This file is part of Alchemist, and is distributed under the terms of the
* GNU General Public License, with a linking exception,
* as described in the file LICENSE in the Alchemist distribution's top directory.
*/
package it.unibo.alchemist.model.sapere.actions;
import it.unibo.alchemist.model.sapere.molecules.LsaMolecule;
import it.unibo.alchemist.model.Environment;
import it.unibo.alchemist.model.sapere.ILsaMolecule;
import it.unibo.alchemist.model.sapere.ILsaNode;
import it.unibo.alchemist.model.Neighborhood;
import it.unibo.alchemist.model.Node;
import it.unibo.alchemist.model.Position2D;
import it.unibo.alchemist.model.Reaction;
import java.util.List;
/**
* @param {@link it.unibo.alchemist.model.Position} type
*/
public final class LsaAscendingAgent
> extends SAPEREMoveNodeAgent
{
/*
* an agent can move at most of LIMIT along each axis
*/
private static final double LIMIT = 0.1;
private static final long serialVersionUID = 228276533881360456L;
private static final ILsaMolecule ACTIVE = new LsaMolecule("active");
private final Reaction> r;
private final ILsaMolecule template;
private final int gradDistPos;
private boolean firstRun = true;
private double startTimeSIMU;
private long startTimeREAL;
/**
* @param reaction
* firing reaction
* @param environment
* the current environment
* @param node
* the current node
* @param molecule
* the LSA to inspect once moving (typically a gradient)
* @param pos
* the position in the LSA of the value to read for identifying
* the new position
*/
public LsaAscendingAgent(final Reaction> reaction,
final Environment, P> environment, final ILsaNode node,
final LsaMolecule molecule, final int pos) {
super(environment, node);
this.r = reaction;
this.template = molecule;
this.gradDistPos = pos;
}
@Override
public void execute() {
double minGrad = Double.MAX_VALUE;
final Neighborhood> neigh = getLocalNeighborhood();
P targetPositions = null;
Node> bestNode = null;
for (final Node> node : neigh.getNeighbors()) {
final ILsaNode n = (ILsaNode) node;
final List gradList;
gradList = n.getConcentration(template);
if (!gradList.isEmpty()) {
for (final ILsaMolecule grad : gradList) {
final double valueGrad = getLSAArgumentAsDouble(grad, gradDistPos);
if (valueGrad <= minGrad) {
minGrad = valueGrad;
targetPositions = getPosition(n);
bestNode = n;
}
}
}
}
if (bestNode == null || bestNode.contains(ACTIVE)) {
return;
}
if (targetPositions != null) {
final P mypos = getCurrentPosition();
final double myx = mypos.getX();
final double myy = mypos.getY();
final double x = targetPositions.getX();
final double y = targetPositions.getY();
double dx = x - myx;
double dy = y - myy;
dx = dx > 0 ? Math.min(LIMIT, dx) : Math.max(-LIMIT, dx);
dy = dy > 0 ? Math.min(LIMIT, dy) : Math.max(-LIMIT, dy);
final boolean moveH = dx > 0 || dx < 0;
final boolean moveV = dy > 0 || dy < 0;
if (moveH || moveV) {
move(getEnvironment().makePosition(moveH ? dx : 0, moveV ? dy : 0));
}
}
}
/**
* @return simulated time and real time at which agent reaches the source of
* gradient
*/
protected double[] computeWalkedTime() {
double[] walkedTime = new double[2];
if (firstRun) {
startTimeSIMU = r.getTau().toDouble();
startTimeREAL = System.currentTimeMillis();
firstRun = false;
}
walkedTime[0] = r.getTau().toDouble() - startTimeSIMU;
walkedTime[1] = System.currentTimeMillis() - startTimeREAL;
return walkedTime;
}
}