} else {
// it is supposed to fill KB before each query
}
// add to query
Query query = PrognosController.this.setupQuery(shipNear);
queryList.add(query);
shipEntitiesInQuery.put(query,shipNear);
}
// System.out.println("[" + new Date() + "] took " + (System.currentTimeMillis() - time) + " ms to prepare for query on ship " + myShip.getShipName());
long timeForPreparation = (System.currentTimeMillis() - time);
// System.out.println("[" + new Date() + "] heap usage after preparation of query of " + myShip.getShipName() + " is " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
// store reasoning mode, for log purpose
String reasoningModeLabel = isToUseMultipleQuery?(isContinuousCase()?"CONTINUOUS":"DISCRETE"):(isContinuousCase()?"CONTINUOUS_SEQUENTIAL":"DISCRETE_SEQUENTIAL");
long timeForQuery = 0; // will store time needed to perform query
// mapping between ship's ID and how many iteration the reasoner used in order to get results
Map<Integer, Integer> iterationQuantityMap = new HashMap<Integer, Integer>();
// mapping between ship's ID and how long it took to query that ship. This is only useful if we are doing sequential query
// (i.e. query each ship one by one instead of querying them altogether)
Map<Integer, Long> executionTimeMap = new HashMap<Integer, Long>();
if (!queryList.isEmpty()) {
// timestamp to calculate time of query
long milliseconds = System.currentTimeMillis();
ProbabilisticNetwork returnedNet = null; // points to the returned SSBN
if (isToUseMultipleQuery) {
PrognosController.this.runQuery(queryList); // this.net will contain the result
returnedNet = net; // net already contains all nodes
} else {
// append nodes of the SSBN to returnedNet
returnedNet = new ProbabilisticNetwork("SequentialQueryResult");
for (Query query : queryList) {
long timestampBeforeSeqQuery = System.currentTimeMillis(); // I want to include the KB overhead in the query time of seq query
ShipEntity queriedShipEntity = shipEntitiesInQuery.get(query); // ship to query
// kb must reflect only the current ship
PrognosController.this.populateRelevantKB(queriedShipEntity, true);
// query each target one-by-one
PrognosController.this.runQuery(Collections.singletonList(query));
long timeFor1QueryInSeqQuery = System.currentTimeMillis() - timestampBeforeSeqQuery;
try {
// its the same time and iteration for all of them (because we did only 1 query to get all the results)
iterationQuantityMap.put(queriedShipEntity.getID(), textModeRunner.getSSBNgenerator().getLastIterationCount());
executionTimeMap.put(queriedShipEntity.getID(), timeFor1QueryInSeqQuery);
} catch (Exception e) {
e.printStackTrace();
}
for (Node node : net.getNodes()) {
// only add if it is not redundant
if (returnedNet.getNodeIndex(node.getName()) < 0) {
// supposedly, we only need the marginals, so we don't have to copy the structure of the net or its details
returnedNet.addNode(node);
}
}
}
}
// System.out.println(">> It took " + ((System.currentTimeMillis() - milliseconds)/1000.0) + " seconds to run query " + queryList + ". Area is " + World.This().getDetectingMile()
// + " nautic miles. The size of the network is " + net.getNodeCount() + ". Reasoning mode was " + (isContinuousCase()?"CONTINUOUS.":"DISCRETE."));
// System.out.println("[" + new Date() + "] current heap usage is " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
// total time the query took
timeForQuery = (System.currentTimeMillis() - milliseconds);
if (isToUseMultipleQuery) {
// fill the iteration quantity and execution time per ship for the multiple query case
for (ShipEntity ship : shipEntitiesInQuery.values()) {
try {
// its the same time and iteration for all of them (because we did only 1 query to get all the results)
iterationQuantityMap.put(ship.getID(), textModeRunner.getSSBNgenerator().getLastIterationCount());
executionTimeMap.put(ship.getID(), timeForQuery); // value is not required in mult. query, but we need to fill something, so that the column of CSV is constant
} catch (Exception e) {
e.printStackTrace();
}
}
}
// this.net contains the SSBN
for (Node node : returnedNet.getNodes()) {
// only consider printing log for SSBN nodes generated from isShipOfInterest (such nodes supposedly have names starting with "isShipOfInterest")
if (node.getName().toUpperCase().startsWith("ISSHIPOFINTEREST")) {
try {
ShipEntity ship = DataBase.getInstance().getShipByName(node.getName().substring(node.getName().toLowerCase().lastIndexOf("ship"), node.getName().length()));
// print log in csv-like format: [timestamp , queried ship , area (nautic miles) , reasoning mode (continuous or discrete) , time for preparation , heap before query , time to query, heap after query, shipofinterest, probability(of true) ]
System.out.println(
">> , "
+ timestampLabel // timestamp
+ " , " + DataBase.getInstance().getShips().size() // quantity of ships
+ " , " + DataBase.getInstance().getOrganizations().size() // quantity of organizations
+ " , " + DataBase.getInstance().getPeople().size() // quantity of people
+ " , " + shipName // name of the ship provided by the user
+ " , " + World.This().getDetectingMile() // detecting area, in nautic miles
+ " , " + reasoningModeLabel // reasoning mode
+ " , " + timeForPreparation // time took to prepare query
+ " , " + heapBeforeQuery // memory usage before query
+ " , " + timeForQuery // time took to actually perform query
+ " , " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) // memory usage afer query
+ " , " + returnedNet.getNodeCount() // size of net
+ " , " + "Ship" + ship.getID() // ship of interest
+ " , " + ((TreeVariable)node).getMarginalAt((node.getStateAt(0).equalsIgnoreCase("TRUE")?0:1)) // probability ship of interest
+ " , " + (ship.getTerroristPlan() != null && ship.getTerroristPlan().getTerroristPlanType() != null) // whether it is a terrorist
+ " , " + queryList.size() // size of query is supposedly the quantity of ships
+ " , " + iterationQuantityMap.get(ship.getID()) // how many iterations the reasoner used to get a result for the ship of interest
+ " , " + executionTimeMap.get(ship.getID()) // time in milliseconds to complete 1 query (only important in sequential query)
);
} catch (Throwable t) {
// logging should not stop program
t.printStackTrace();
}
}
}
} else {
// there are no ships nearby
// System.out.println(">> No ships nearby " + myShip.getShipName() + ". Area is " + World.This().getDetectingMile()
// + " nautic miles. Reasoning mode was " + (isContinuousCase()?"CONTINUOUS.":"DISCRETE."));
// System.out.println("[" + new Date() + "] current heap usage is " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
// print log [timestamp , queried ship , area (nautic miles) , reasoning mode (continuous or discrete) , time for preparation , heap before query , time to query, heap after query, shipofinterest, probability(of true) ]
System.out.println(
">> , "
+ timestampLabel // timestamp
+ " , " + DataBase.getInstance().getShips().size() // quantity of ships
+ " , " + DataBase.getInstance().getOrganizations().size() // quantity of organizations
+ " , " + DataBase.getInstance().getPeople().size() // quantity of people
+ " , " + shipName // ship id of queried ship (ship provided by user as input for this method)
+ " , " + World.This().getDetectingMile() // detecting area, in nautic miles
+ " , " + reasoningModeLabel // reasoning mode
+ " , " + timeForPreparation // time took to prepare query
+ " , " + heapBeforeQuery // memory usage before query
+ " , " + timeForQuery // time took to actually perform query
+ " , " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) // memory usage afer query
+ " , " + 0 // size of net = 0 because nothing was queried
+ " , " + "null" // there were no ship to actually query
+ " , " + -1.0f // invalid probability
+ " , " + false // it is not a ship of interest
+ " , " + 0 // no ships in the result
+ " , " + 0 // no iteration performed by the reasoner
+ " , " + 0 // if 0 query in total, it's 0 query time sequentially as well
);
}
// query ships of interest as well, if asked
if (isToForceIncludeShipOfInterest) {
// reset KB, because we are going to do a different query
resetKB();
// reset the maps with test data
iterationQuantityMap.clear();
executionTimeMap.clear();
try {
// try freeing memory now, because we want to collect memory usage again
System.gc();
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
// calculate new time and heap of preparation phase
time = System.currentTimeMillis();
heapBeforeQuery = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
// prepare another multiple query
queryList.clear();
// look for ships that are terrorists.
Map<Query, ShipEntity> terroristShips = new HashMap<Query, ShipEntity>(); // will record who was added to new query
for (ShipEntity ship : DataBase.getInstance().getShips()) {
if (ship.getTerroristPlan() != null && ship.getTerroristPlan().getTerroristPlanType() != null) {
// this is a ship of interest
if (!shipEntitiesInQuery.containsValue(ship)) {
Query query = PrognosController.this.setupQuery(ship);
queryList.add(query);
if (isToUseMultipleQuery) {
PrognosController.this.populateRelevantKB(ship, false);
} else {
// register what ship was added to which query