package com.plectix.simulator.smiles; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Random; import com.plectix.simulator.simulator.ThreadLocalData; import com.plectix.simulator.staticanalysis.Agent; import com.plectix.simulator.staticanalysis.ConnectedComponent; import com.plectix.simulator.staticanalysis.Site; import com.plectix.simulator.util.DecimalFormatter; import com.plectix.simulator.util.PlxTimer; import com.plectix.simulator.util.io.PlxLogger; import com.plectix.simulator.util.string.ConnectedComponentToSmilesString; public class SmilesTest { private static final PlxLogger LOGGER = ThreadLocalData .getLogger(SmilesTest.class); private static final int MAXIMUM_NUMBER_OF_SHUFFLES = 1000; private ConnectedComponent ccomponent; private String uniqueKappaString; private ConnectedComponentToSmilesString connectedComponentToSmilesString; public SmilesTest(ConnectedComponent cc) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("New ConnectedComponent with " + cc.getAgents().size() + " agents"); } ccomponent = cc; } public String test() { String message = ""; int size = ccomponent.getAgents().size(); connectedComponentToSmilesString = ConnectedComponentToSmilesString .getInstance(); uniqueKappaString = connectedComponentToSmilesString .toUniqueString(ccomponent); if (LOGGER.isDebugEnabled()) { LOGGER.debug("uniqueKappaString " + uniqueKappaString); } message = testAgents(size).toString() + testLinkIndexes(); return message; } private StringBuffer testAgents(int size) { List<Agent> list = copy(ccomponent.getAgents()); StringBuffer fails = new StringBuffer(); if (size == 2) { list = reverse(list); checkit(list, fails); } else if (size > 2) { int numberOfTrials = Math.min(size * size, MAXIMUM_NUMBER_OF_SHUFFLES); PlxTimer plxTimer = new PlxTimer(); plxTimer.startTimer(); for (int i = 0; i < numberOfTrials; i++) { Collections.shuffle(list); if (!checkit(list, fails)) break; } plxTimer.stopTimer(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Timing: CC has " + size + " agents -> " + numberOfTrials + " iterations took " + DecimalFormatter .toStringWithSetNumberOfFractionDigits( 1000.0 * plxTimer .getThreadTimeInSeconds(), 6) + " msecs -> " + DecimalFormatter .toStringWithSetNumberOfFractionDigits(1000.0 * plxTimer.getThreadTimeInSeconds() / numberOfTrials, 6) + " msecs/string -> " + DecimalFormatter .toStringWithSetNumberOfFractionDigits(1000.0 * plxTimer.getThreadTimeInSeconds() / numberOfTrials / size, 6) + " msecs/string/agent "); } } return fails; } private boolean checkit(List<Agent> list, StringBuffer fails) { String smilesString = connectedComponentToSmilesString .toUniqueString(new ConnectedComponent(list)); if (!smilesString.equals(uniqueKappaString)) { String message = "\ntestAgents:\nexpected\t" + uniqueKappaString + ",\nbut\t\t" + smilesString + "\n"; fails.append(message); return false; } return true; } private String testLinkIndexes() { StringBuffer fails = new StringBuffer(); LinkedHashMap<Integer, Integer> links = new LinkedHashMap<Integer, Integer>(); Random rnd = new Random(); int r; for (Agent agent : ccomponent.getAgents()) { for (Site site : agent.getSites()) { int index = site.getLinkIndex(); if (index != -1) { if (!links.containsKey(index)) { r = rnd.nextInt(100); links.put(index, r); } else { r = links.get(index); } site.setLinkIndex(r); } } } String smilesString = connectedComponentToSmilesString .toUniqueString(ccomponent); if (!smilesString.equals(uniqueKappaString)) { fails.append("\ntestLinkIndex:\nexpected\t" + uniqueKappaString + ",\nbut\t\t" + smilesString + "\n"); } return fails.toString(); } private List<Agent> reverse(List<Agent> list) { ArrayList<Agent> reverse = new ArrayList<Agent>(2); reverse.add(list.get(1)); reverse.add(list.get(0)); return reverse; } private <E> List<E> copy(List<E> agents) { List<E> copy = new ArrayList<E>(); for (E agent : agents) { copy.add(agent); } return copy; } }