Skip to content

Commit

Permalink
move the deactivation strategy from comparator- to evaluator-based
Browse files Browse the repository at this point in the history
because we need to ensure a stable sort and our FAD evaluation might
be noisy (e.g. in the case of the non-reliable fish-value calculator)
  • Loading branch information
nicolaspayette committed Mar 11, 2024
1 parent 81f888d commit 3bfe855
Show file tree
Hide file tree
Showing 15 changed files with 301 additions and 279 deletions.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* POSEIDON, an agent-based model of fisheries
* Copyright (C) 2024 CoHESyS Lab [email protected]
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/

package uk.ac.ox.oxfish.fisher.purseseiner.fads;

import java.util.Map.Entry;
import java.util.function.ToDoubleFunction;

import static java.util.Comparator.comparingDouble;
import static java.util.stream.Collectors.toList;
import static uk.ac.ox.poseidon.common.core.Entry.entry;

public class EvaluatorBasedFadDeactivationStrategy extends FadDeactivationStrategy {
private static final long serialVersionUID = -2818076865902570581L;
private final ToDoubleFunction<? super Fad> fadEvaluator;

@SuppressWarnings("WeakerAccess")
public EvaluatorBasedFadDeactivationStrategy(final ToDoubleFunction<? super Fad> fadEvaluator) {
this.fadEvaluator = fadEvaluator;
}

@Override
protected void deactivate(final int numberOfFadsToDeactivate) {
getFadManager()
.getDeployedFads()
.stream()
// it's important to evaluate the FADs before sorted because the value might be noisy and
// then something like `comparingDouble(fadEvaluator)` wouldn't be a stable comparison
.map(fad -> entry(fad, fadEvaluator.applyAsDouble(fad)))
.sorted(comparingDouble(Entry::getValue))
.map(Entry::getKey)
.limit(numberOfFadsToDeactivate)
.collect(toList())
.forEach(fad -> getFadManager().loseFad(fad));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* POSEIDON, an agent-based model of fisheries
* Copyright (C) 2024 CoHESyS Lab [email protected]
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/

package uk.ac.ox.oxfish.fisher.purseseiner.fads;

import uk.ac.ox.poseidon.common.api.ComponentFactory;
import uk.ac.ox.poseidon.common.api.ModelState;

import java.util.function.ToDoubleFunction;

public class EvaluatorBasedFadDeactivationStrategyFactory implements ComponentFactory<FadDeactivationStrategy> {

private ComponentFactory<ToDoubleFunction<Fad>> fadEvaluator;

@SuppressWarnings("unused")
public EvaluatorBasedFadDeactivationStrategyFactory() {
}

public EvaluatorBasedFadDeactivationStrategyFactory(final ComponentFactory<ToDoubleFunction<Fad>> fadEvaluator) {
this.fadEvaluator = fadEvaluator;
}

@SuppressWarnings("unused")
public ComponentFactory<ToDoubleFunction<Fad>> getFadEvaluator() {
return fadEvaluator;
}

@SuppressWarnings("unused")
public void setFadEvaluator(final ComponentFactory<ToDoubleFunction<Fad>> fadEvaluator) {
this.fadEvaluator = fadEvaluator;
}

@Override
public FadDeactivationStrategy apply(final ModelState modelState) {
return new EvaluatorBasedFadDeactivationStrategy(fadEvaluator.apply(modelState));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* POSEIDON, an agent-based model of fisheries
* Copyright (C) 2024 CoHESyS Lab [email protected]
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/

package uk.ac.ox.oxfish.fisher.purseseiner.fads;

import com.google.auto.service.AutoService;
import uk.ac.ox.poseidon.common.api.FactorySupplier;
import uk.ac.ox.poseidon.common.core.BasicFactorySupplier;

@AutoService(FactorySupplier.class)
public class EvaluatorBasedFadDeactivationStrategyFactorySupplier
extends BasicFactorySupplier<EvaluatorBasedFadDeactivationStrategyFactory> {
public EvaluatorBasedFadDeactivationStrategyFactorySupplier() {
super(
EvaluatorBasedFadDeactivationStrategyFactory.class,
"Evaluator-based FAD deactivation strategy"
);
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
/*
* POSEIDON, an agent-based model of fisheries
* Copyright (C) 2020 CoHESyS Lab [email protected]
* POSEIDON, an agent-based model of fisheries
* Copyright (C) 2024 CoHESyS Lab [email protected]
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/

package uk.ac.ox.oxfish.fisher.purseseiner.fads;
Expand Down Expand Up @@ -144,6 +141,13 @@ public FadManager(
biomassLostMonitor.ifPresent(observer -> registerObserver(BiomassLostEvent.class, observer));
}

public <T> void registerObserver(
final Class<T> observedClass,
final Observer<? super T> observer
) {
observers.register(observedClass, observer);
}

public static FadManager getFadManager(
final Fisher fisher
) {
Expand All @@ -158,6 +162,21 @@ public static Optional<FadManager> maybeGetFadManager(
return maybeGetPurseSeineGear(fisher).map(PurseSeineGear::getFadManager);
}

public int numberOfPermissibleActions(
final ActionClass actionClass,
final int maximumToCheckFor,
final Regulations regulations
) {
return numberOfPermissibleActions(
getFisher(),
regulations,
getYearlyActionCounter(),
getNumberOfActiveFads(),
actionClass,
maximumToCheckFor
);
}

public static int numberOfPermissibleActions(
final Fisher fisher,
final Regulations regulations,
Expand Down Expand Up @@ -213,28 +232,6 @@ public long getCount(

}

public <T> void registerObserver(
final Class<T> observedClass,
final Observer<? super T> observer
) {
observers.register(observedClass, observer);
}

public int numberOfPermissibleActions(
final ActionClass actionClass,
final int maximumToCheckFor,
final Regulations regulations
) {
return numberOfPermissibleActions(
getFisher(),
regulations,
getYearlyActionCounter(),
getNumberOfActiveFads(),
actionClass,
maximumToCheckFor
);
}

public Fisher getFisher() {
return fisher;
}
Expand Down Expand Up @@ -264,7 +261,9 @@ public Stream<Fad> getFadsAt(final SeaTile location) {
}

public void loseFad(final Fad fad) {
checkArgument(deployedFads.contains(fad));
// remove the FAD from deployed FADs if it is there
// (it won't be if the FAD was, e.g., manually deactivated
// and is now getting zapped because it drifted out)
deployedFads.remove(fad);
fad.lose();
}
Expand Down
Loading

0 comments on commit 3bfe855

Please sign in to comment.