Skip to content

Commit

Permalink
add the ability to imitate friends
Browse files Browse the repository at this point in the history
along with some refactoring of option suppliers
  • Loading branch information
nicolaspayette committed Nov 20, 2024
1 parent 23e5a58 commit 5882675
Show file tree
Hide file tree
Showing 24 changed files with 361 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import java.util.HashMap;
import java.util.Map;

class AverageOptionValues<T> extends MapBasedOptionValues<T> {
class AverageOptionValues<T> extends HashMapBasedOptionValues<T> {

private final Map<T, Integer> counts = new HashMap<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
import uk.ac.ox.poseidon.core.Factory;
import uk.ac.ox.poseidon.core.Simulation;

public class AverageOptionValuesFactory<O> implements Factory<OptionValues<O>> {
public class AverageOptionValuesFactory<O> implements Factory<MutableOptionValues<O>> {
@Override
public OptionValues<O> get(final Simulation simulation) {
public MutableOptionValues<O> get(final Simulation simulation) {
return new AverageOptionValues<>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* 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.poseidon.agents.behaviours.choices;

import com.google.common.collect.ImmutableList;
import ec.util.MersenneTwisterFast;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import uk.ac.ox.poseidon.agents.registers.Register;
import uk.ac.ox.poseidon.agents.vessels.Vessel;

import java.util.Map;
import java.util.function.Supplier;

import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static uk.ac.ox.poseidon.core.MasonUtils.upToNOf;

@RequiredArgsConstructor
class BestOptionsFromFriendsSupplier<O> implements Supplier<OptionValues<O>> {

private final Vessel vessel;
private final int maxNumberOfFriends;
private final Register<? extends OptionValues<O>> optionValuesRegister;
private final MersenneTwisterFast rng;

private final @Getter(lazy = true) ImmutableList<Vessel> friends = chooseFriends();

private ImmutableList<Vessel> chooseFriends() {
assert optionValuesRegister != null;
assert this.vessel != null;
return upToNOf(
maxNumberOfFriends,
optionValuesRegister
.getVessels()
.filter(vessel -> vessel.getHomePort() == this.vessel.getHomePort())
.filter(vessel -> vessel != this.vessel)
.toList(),
rng
);
}

@Override
public OptionValues<O> get() {
return new ImmutableOptionValues<>(
getFriends()
.stream()
.flatMap(vessel -> optionValuesRegister.get(vessel).stream())
.flatMap(optionValues -> optionValues.getBestEntries().stream())
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue, Math::max))
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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.poseidon.agents.behaviours.choices;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import uk.ac.ox.poseidon.agents.registers.Register;
import uk.ac.ox.poseidon.agents.vessels.Vessel;
import uk.ac.ox.poseidon.agents.vessels.VesselScopeFactory;
import uk.ac.ox.poseidon.core.Factory;
import uk.ac.ox.poseidon.core.Simulation;

import java.util.function.Supplier;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class BestOptionsFromFriendsSupplierFactory<O>
extends VesselScopeFactory<Supplier<OptionValues<O>>> {

private int maxNumberOfFriends;
private Factory<? extends Register<? extends OptionValues<O>>> optionValuesRegister;

@Override
protected Supplier<OptionValues<O>> newInstance(
final Simulation simulation,
final Vessel vessel
) {
return new BestOptionsFromFriendsSupplier<>(
vessel,
maxNumberOfFriends,
optionValuesRegister.get(simulation),
simulation.random
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,31 @@
*
*/

package uk.ac.ox.poseidon.agents.registers;
package uk.ac.ox.poseidon.agents.behaviours.choices;

import lombok.RequiredArgsConstructor;
import uk.ac.ox.poseidon.agents.registers.Register;
import uk.ac.ox.poseidon.agents.vessels.Vessel;

import java.util.Map.Entry;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;
import java.util.Map;
import java.util.function.Supplier;

import static java.util.Map.entry;
import static com.google.common.collect.ImmutableMap.toImmutableMap;

@RequiredArgsConstructor
public class TransformedRegister<S, T> implements Register<T> {
public class BestOptionsSupplier<O> implements Supplier<OptionValues<O>> {

private final Register<S> sourceRegister;
private final Function<Stream<Entry<Vessel, S>>, Stream<Entry<Vessel, T>>> transformer;
private final Vessel vessel;
private final Register<? extends OptionValues<O>> optionValuesRegister;

@Override
public Optional<T> get(final Vessel vessel) {
final Optional<Entry<Vessel, S>> sourceEntry =
sourceRegister
.get(vessel)
.map(value -> entry(vessel, value));
return transformer
.apply(sourceEntry.stream())
.findAny()
.map(Entry::getValue);
public OptionValues<O> get() {
return new ImmutableOptionValues<>(
optionValuesRegister
.getOtherEntries(vessel)
.map(Map.Entry::getValue)
.flatMap(optionValues -> optionValues.getBestEntries().stream())
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue, Math::max))
);
}

@Override
public Stream<Entry<Vessel, T>> getAllEntries() {
return transformer.apply(sourceRegister.getAllEntries());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,31 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import one.util.streamex.EntryStream;
import uk.ac.ox.poseidon.agents.registers.Register;
import uk.ac.ox.poseidon.agents.registers.TransformedRegister;
import uk.ac.ox.poseidon.agents.vessels.Vessel;
import uk.ac.ox.poseidon.agents.vessels.VesselScopeFactory;
import uk.ac.ox.poseidon.core.Factory;
import uk.ac.ox.poseidon.core.Simulation;
import uk.ac.ox.poseidon.core.SimulationScopeFactory;

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

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class BestOptionsRegisterFactory<O>
extends SimulationScopeFactory<Register<Entry<O, Double>>> {
public class BestOptionsSupplierFactory<O>
extends VesselScopeFactory<Supplier<OptionValues<O>>> {

Factory<? extends Register<? extends OptionValues<O>>> optionValuesRegister;

@Override
protected Register<Entry<O, Double>> newInstance(final Simulation simulation) {
return new TransformedRegister<>(
optionValuesRegister.get(simulation),
entryStream -> EntryStream
.of(entryStream)
.flatMapValues(optionValues -> optionValues.getBestEntries().stream())
protected Supplier<OptionValues<O>> newInstance(
final Simulation simulation,
final Vessel vessel
) {
return new BestOptionsSupplier<>(
vessel,
optionValuesRegister.get(simulation)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
public class EpsilonGreedyChooser<O> implements Supplier<O> {

private final double epsilon;
private final OptionValues<O> optionValues;
private final MutableOptionValues<O> optionValues;
private final Picker<O> explorer;
private final Picker<O> exploiter;
private final Evaluator<O> evaluator;
Expand All @@ -40,7 +40,7 @@ public class EpsilonGreedyChooser<O> implements Supplier<O> {

public EpsilonGreedyChooser(
final double epsilon,
final OptionValues<O> optionValues,
final MutableOptionValues<O> optionValues,
final Picker<O> explorer,
final Picker<O> exploiter,
final Evaluator<O> evaluator,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import static uk.ac.ox.poseidon.core.utils.Preconditions.checkUnitRange;

class ExponentialMovingAverageOptionValues<T> extends MapBasedOptionValues<T> {
class ExponentialMovingAverageOptionValues<T> extends HashMapBasedOptionValues<T> {

private final double alpha;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class ExponentialMovingAverageOptionValuesFactory<O> extends VesselScopeFactory<OptionValues<O>> {
public class ExponentialMovingAverageOptionValuesFactory<O> extends VesselScopeFactory<MutableOptionValues<O>> {

private double alpha;

@Override
protected OptionValues<O> newInstance(
protected MutableOptionValues<O> newInstance(
final Simulation simulation,
final Vessel vessel
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* 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.poseidon.agents.behaviours.choices;

import lombok.Getter;

import java.util.HashMap;
import java.util.Map;

@Getter
public abstract class HashMapBasedOptionValues<O>
extends MapBasedOptionValues<O>
implements MutableOptionValues<O> {

protected final Map<O, Double> values = new HashMap<>();

@Override
public void observe(
final O option,
final double value
) {
final double oldValue = values.getOrDefault(option, 0.0);
values.put(option, newValue(option, oldValue, value));
invalidateCache();
}

protected void invalidateCache() {
cachedBest = null;
}

protected abstract double newValue(
O option,
double oldValue,
double observedValue
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.poseidon.agents.behaviours.choices;

import com.google.common.collect.ImmutableMap;
import lombok.Getter;

import java.util.Map;

@Getter
public class ImmutableOptionValues<O> extends MapBasedOptionValues<O> {

private final ImmutableMap<O, Double> values;

public ImmutableOptionValues(final Map<O, Double> values) {
this.values = ImmutableMap.copyOf(values);
}

}
Loading

0 comments on commit 5882675

Please sign in to comment.