2

I have a model with a lot of edges (links) between different sorts of other agents (objects). I would like to model these edges as agents where I could add attributes and schedule actions. It is helpful to see a simple example of how to do this job?

update: I followed your instructions and get an error when running the model:

FATAL [Thread-2] 12:45:02,901 repast.simphony.ui.GUIScheduleRunner - RunTimeException when running the schedule
Current tick (1.0)
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at repast.simphony.engine.schedule.DynamicTargetAction.execute(DynamicTargetAction.java:72)
    at repast.simphony.engine.controller.ScheduledMethodControllerAction$ScheduleMethodAllAction.execute(ScheduledMethodControllerAction.java:333)
    at repast.simphony.engine.schedule.DefaultAction.execute(DefaultAction.java:38)
    at repast.simphony.engine.schedule.ScheduleGroup.executeList(ScheduleGroup.java:205)
    at repast.simphony.engine.schedule.ScheduleGroup.execute(ScheduleGroup.java:231)
    at repast.simphony.engine.schedule.Schedule.execute(Schedule.java:352)
    at repast.simphony.ui.GUIScheduleRunner$ScheduleLoopRunnable.run(GUIScheduleRunner.java:52)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.reflect.InvocationTargetException
    at jzombies.Zombie$$FastClassByCGLIB$$6141f31.invoke(<generated>)
    at net.sf.cglib.reflect.FastMethod.invoke(FastMethod.java:53)
    at repast.simphony.engine.schedule.DynamicTargetAction.execute(DynamicTargetAction.java:69)
    ... 7 more
Caused by: java.lang.NullPointerException
    at repast.simphony.query.PropertyGreaterThan.createPredicate(PropertyGreaterThan.java:72)
    at repast.simphony.query.AbstractPropertyQuery.query(AbstractPropertyQuery.java:83)
    at jzombies.Zombie.query_energy(Zombie.java:141)
    at jzombies.Zombie.step(Zombie.java:67)
    ... 10 more

I think it's affected by this method in Zombie: (but I have no idea where is wrong since the error message does not provide specific instruction)

    public void query_energy() {
//      Zombie this_zombie = new Zombie (space, grid, 9999);
        Context<Object> context = ContextUtils.getContext(this);
        Query<Object> query = new PropertyGreaterThan<Object>(context, "id", 2);
        for (Object o : query.query()) {
            Zombie h = (Zombie)o;
            System.out.println("zombie id: " + h.getID());
        }

    }
Jack
  • 1,339
  • 1
  • 12
  • 31
  • 1
    Can you check if the context is null there? That would produce error. – Nick Collier Aug 23 '19 at 14:28
  • Even though it originated from the original question, this seems like a new question asking about a NullPointerException so I'd suggest creating a new post. – J. Ozik Aug 23 '19 at 17:48

1 Answers1

3

Here's an example based on the JZombies_Demo model.

First create a CustomEdge class.

package jzombies;

import repast.simphony.space.graph.RepastEdge;

public class CustomEdge<T> extends RepastEdge<T> {

    private double customProperty;

    public double getCustomProperty() {
        return customProperty;
    }

    public void setCustomProperty(double customProperty) {
        this.customProperty = customProperty;
    }

    public CustomEdge(T source, T target, boolean directed, double weight) {
        super(source, target, directed, weight);
    }

    public CustomEdge(T source, T target, boolean directed) {
        super(source, target, directed);
    }

    public void customAction() {
        // define custom action here
    }
}

Then a CustomEdgeCreator class:

package jzombies;

import repast.simphony.space.graph.EdgeCreator;

public class CustomEdgeCreator<T> implements EdgeCreator<CustomEdge<T>, T> {

    public Class<CustomEdge> getEdgeType() {
        return CustomEdge.class;
    }

    public CustomEdge<T> createEdge(T source, T target, boolean isDirected, double weight) {
        return new CustomEdge<T>(source, target, isDirected, weight);
    }

}

Then when you define the NetworkBuilder in the JZombiesBuilder class you provide a CustomEdgeCreator instance:

NetworkBuilder<Object> netBuilder = new NetworkBuilder<Object>(
                "infection network", context, true).setEdgeCreator(new CustomEdgeCreator());
        netBuilder.buildNetwork();

At this point whenever you add an edge to the network you will be able to access the edge instance and schedule any custom action you define, for example like this in the Zombie class:

    Network<Object> net = (Network<Object>)context.getProjection("infection network");
    CustomEdge edge = (CustomEdge)net.addEdge(this, zombie);
    RunEnvironment.getInstance().getCurrentSchedule().schedule(
            ScheduleParameters.createOneTime(RunEnvironment.getInstance().getCurrentSchedule().getTickCount() + 20), edge, "customAction");

I hope this helps.

J. Ozik
  • 1,083
  • 5
  • 6
  • looks very helpful. I am gong to try it now and see if I can get it work. thank you – Jack Aug 23 '19 at 03:41
  • Though it's working for a long time, I don't quite understand the use of in your code. If I want to create another kind of edge, different from the CustomEdge, do I have to repeat the above process again? (i.e. add a second CustomEdgeCreator class and CustomEdge class) – Jack Oct 21 '19 at 09:23