GeneticAlgorithm.java 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947
  1. package algorithms;
  2. import java.awt.Dimension;
  3. import java.awt.Font;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import java.awt.event.MouseAdapter;
  7. import java.awt.event.MouseEvent;
  8. import java.awt.event.MouseListener;
  9. import java.math.BigDecimal;
  10. import java.math.RoundingMode;
  11. import java.util.ArrayList;
  12. import java.util.Collections;
  13. import java.util.HashMap;
  14. import java.util.Random;
  15. import java.util.Set;
  16. import javax.swing.BoxLayout;
  17. import javax.swing.JButton;
  18. import javax.swing.JCheckBox;
  19. import javax.swing.JFrame;
  20. import javax.swing.JLabel;
  21. import javax.swing.JPanel;
  22. import javax.swing.JScrollPane;
  23. import javax.swing.JSplitPane;
  24. import javax.swing.JTextArea;
  25. import javax.swing.JTextField;
  26. import javax.swing.JTree;
  27. import javax.swing.tree.DefaultMutableTreeNode;
  28. import javax.swing.tree.DefaultTreeModel;
  29. import javax.swing.tree.TreePath;
  30. import classes.AbstractCpsObject;
  31. import classes.Category;
  32. import classes.CpsEdge;
  33. import classes.CpsNode;
  34. import classes.HolonBattery;
  35. import classes.HolonObject;
  36. import classes.HolonSwitch;
  37. import classes.IdCounter;
  38. import classes.Position;
  39. import ui.controller.Control;
  40. import ui.controller.SimulationManager;
  41. import ui.model.DecoratedHolonObject.HolonObjectState;
  42. import ui.model.DecoratedNetwork;
  43. import ui.model.DecoratedState;
  44. import ui.model.Model;
  45. import api.Algorithm;
  46. public class GeneticAlgorithm implements Algorithm {
  47. Control controller;
  48. @Override
  49. public JPanel getAlgorithmPanel() {
  50. GenAlgoWindow panel = new GenAlgoWindow(controller, controller.getModel());
  51. return panel.frame;
  52. }
  53. @Override
  54. public void setController(Control control) {
  55. controller = control;
  56. }
  57. /*
  58. * The Window of the Algorithm
  59. */
  60. public class GenAlgoWindow {
  61. JPanel frame;
  62. Control controller;
  63. Model model;
  64. JTree genTree;
  65. DefaultTreeModel treeModel;
  66. DefaultMutableTreeNode treeRoot;
  67. HashMap<DefaultMutableTreeNode, HolegIndividual> treeIndiHashmap;
  68. GenAlgoHandler algoHandler;
  69. ArrayList<DefaultMutableTreeNode> generationNodes = new ArrayList<DefaultMutableTreeNode>();
  70. private JTextField edgeAmountField;
  71. private JCheckBox chckbxEditEdges;
  72. private JTextArea logArea;
  73. private JTextField popSizeField;
  74. private JTextField tournamentSizeField;
  75. private JTextField edgeBreakCount;
  76. private JTextField iterationsField;
  77. ParameterArray params = new ParameterArray();
  78. private JTextField edgeMutationField;
  79. private JTextField suppliedField;
  80. private JTextField oversuppliedField;
  81. private JTextField undersuppliedField;
  82. private JTextField edgeLengthField;
  83. private JTextField wildcardUsageField;
  84. private JTextField wildcardMutationField;
  85. private JTextField partialSuppliedField;
  86. private JTextField overproductionField;
  87. private JTextField generationAmountField;
  88. private JCheckBox chckbxWildNodes;
  89. ArrayList<HolegGeneration> generationHistory = new ArrayList<HolegGeneration>();
  90. /**
  91. * Create the application.
  92. */
  93. public GenAlgoWindow(Control controller, Model model) {
  94. this.model = model;
  95. this.controller = controller;
  96. algoHandler = new GenAlgoHandler(controller, model);
  97. algoHandler.addListener(this);
  98. treeIndiHashmap = new HashMap<DefaultMutableTreeNode, HolegIndividual>();
  99. initialize();
  100. algoHandler.setOriginalNetwork();
  101. }
  102. /**
  103. * Initialize the contents of the frame.
  104. */
  105. private void initialize() {
  106. frame = new JPanel();
  107. //frame.setBounds(100, 100, 500, 500);
  108. frame.setPreferredSize(new Dimension(500, 500));
  109. frame.setLayout(new BoxLayout(frame, BoxLayout.X_AXIS));
  110. JSplitPane mainSplitPane = new JSplitPane();
  111. mainSplitPane.setResizeWeight(0.3);
  112. frame.add(mainSplitPane);
  113. JScrollPane treeScrollPane = new JScrollPane();
  114. mainSplitPane.setLeftComponent(treeScrollPane);
  115. genTree = new JTree();
  116. treeScrollPane.setViewportView(genTree);
  117. treeModel = (DefaultTreeModel) genTree.getModel();
  118. treeRoot = new DefaultMutableTreeNode("Generations");
  119. treeModel.setRoot(treeRoot);
  120. genTree.setModel(treeModel);
  121. JSplitPane rightSplitPane = new JSplitPane();
  122. rightSplitPane.setResizeWeight(0.7);
  123. rightSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
  124. mainSplitPane.setRightComponent(rightSplitPane);
  125. JPanel parameterPanel = new JPanel();
  126. parameterPanel.setPreferredSize(new Dimension(100, 650));
  127. JScrollPane parameterScrollView = new JScrollPane();
  128. rightSplitPane.setLeftComponent(parameterScrollView);
  129. parameterScrollView.setViewportView(parameterPanel);
  130. JButton btnCreategeneration = new JButton("create N Generations");
  131. btnCreategeneration.setBounds(10, 11, 137, 23);
  132. btnCreategeneration.addActionListener(new ActionListener() {
  133. public void actionPerformed(ActionEvent arg0) {
  134. setParameters();
  135. algoHandler.createGeneration(Integer.parseInt(generationAmountField.getText()), params);
  136. }
  137. });
  138. parameterPanel.setLayout(null);
  139. parameterPanel.add(btnCreategeneration);
  140. edgeAmountField = new JTextField();
  141. edgeAmountField.setText("0");
  142. edgeAmountField.setBounds(147, 119, 86, 20);
  143. parameterPanel.add(edgeAmountField);
  144. edgeAmountField.setColumns(10);
  145. JLabel lblMaxEdges = new JLabel("Max Edges");
  146. lblMaxEdges.setBounds(10, 122, 91, 14);
  147. parameterPanel.add(lblMaxEdges);
  148. chckbxEditEdges = new JCheckBox("\r\n");
  149. chckbxEditEdges.setBounds(147, 92, 25, 23);
  150. parameterPanel.add(chckbxEditEdges);
  151. JLabel lblEditEdges = new JLabel("Edit Edges?");
  152. lblEditEdges.setBounds(10, 96, 91, 14);
  153. parameterPanel.add(lblEditEdges);
  154. popSizeField = new JTextField();
  155. popSizeField.setText("100");
  156. popSizeField.setBounds(147, 45, 86, 20);
  157. parameterPanel.add(popSizeField);
  158. popSizeField.setColumns(10);
  159. tournamentSizeField = new JTextField();
  160. tournamentSizeField.setText("30");
  161. tournamentSizeField.setBounds(147, 70, 86, 20);
  162. parameterPanel.add(tournamentSizeField);
  163. tournamentSizeField.setColumns(10);
  164. JLabel lblPopulationSize = new JLabel("Population Size");
  165. lblPopulationSize.setBounds(10, 45, 91, 14);
  166. parameterPanel.add(lblPopulationSize);
  167. JLabel lblTournamentSize = new JLabel("Tournament Size");
  168. lblTournamentSize.setBounds(10, 73, 91, 14);
  169. parameterPanel.add(lblTournamentSize);
  170. edgeBreakCount = new JTextField();
  171. edgeBreakCount.setText("0");
  172. edgeBreakCount.setBounds(147, 144, 86, 20);
  173. parameterPanel.add(edgeBreakCount);
  174. edgeBreakCount.setColumns(10);
  175. JLabel lblEdgeBreakProb = new JLabel("Edge Break Amount");
  176. lblEdgeBreakProb.setBounds(10, 147, 117, 14);
  177. parameterPanel.add(lblEdgeBreakProb);
  178. iterationsField = new JTextField();
  179. iterationsField.setText("1");
  180. iterationsField.setBounds(147, 169, 86, 20);
  181. parameterPanel.add(iterationsField);
  182. iterationsField.setColumns(10);
  183. JLabel lblSimIteration = new JLabel("Sim Iterations");
  184. lblSimIteration.setBounds(10, 172, 91, 14);
  185. parameterPanel.add(lblSimIteration);
  186. edgeMutationField = new JTextField();
  187. edgeMutationField.setText("0.01");
  188. edgeMutationField.setBounds(147, 194, 86, 20);
  189. parameterPanel.add(edgeMutationField);
  190. edgeMutationField.setColumns(10);
  191. JLabel lblMutationProb = new JLabel("Edge Mutation Prob");
  192. lblMutationProb.setBounds(10, 197, 117, 14);
  193. parameterPanel.add(lblMutationProb);
  194. suppliedField = new JTextField();
  195. suppliedField.setText("+10.0");
  196. suppliedField.setBounds(147, 297, 86, 20);
  197. parameterPanel.add(suppliedField);
  198. suppliedField.setColumns(10);
  199. JLabel lblFittnesspointsPerAttribute = new JLabel("Fittnesspoints per Attribute:");
  200. lblFittnesspointsPerAttribute.setFont(new Font("Tahoma", Font.PLAIN, 12));
  201. lblFittnesspointsPerAttribute.setBounds(59, 275, 157, 14);
  202. parameterPanel.add(lblFittnesspointsPerAttribute);
  203. JLabel lblSuppliedEntity = new JLabel("each supplied Entity");
  204. lblSuppliedEntity.setBounds(10, 300, 117, 14);
  205. parameterPanel.add(lblSuppliedEntity);
  206. oversuppliedField = new JTextField();
  207. oversuppliedField.setText("+10.0");
  208. oversuppliedField.setBounds(147, 322, 86, 20);
  209. parameterPanel.add(oversuppliedField);
  210. oversuppliedField.setColumns(10);
  211. JLabel lblOversuppliedEntity = new JLabel("each oversupplied Entity");
  212. lblOversuppliedEntity.setBounds(10, 325, 127, 14);
  213. parameterPanel.add(lblOversuppliedEntity);
  214. undersuppliedField = new JTextField();
  215. undersuppliedField.setText("-10.0");
  216. undersuppliedField.setBounds(147, 347, 86, 20);
  217. parameterPanel.add(undersuppliedField);
  218. undersuppliedField.setColumns(10);
  219. JLabel lblEachUndersuppliedEntity = new JLabel("each undersupplied Entity");
  220. lblEachUndersuppliedEntity.setBounds(10, 350, 127, 14);
  221. parameterPanel.add(lblEachUndersuppliedEntity);
  222. edgeLengthField = new JTextField();
  223. edgeLengthField.setText("-1.0");
  224. edgeLengthField.setBounds(147, 397, 86, 20);
  225. parameterPanel.add(edgeLengthField);
  226. edgeLengthField.setColumns(10);
  227. JLabel lblForEdge = new JLabel("for 100 edge length");
  228. lblForEdge.setBounds(10, 400, 127, 14);
  229. parameterPanel.add(lblForEdge);
  230. wildcardUsageField = new JTextField();
  231. wildcardUsageField.setText("-7.0");
  232. wildcardUsageField.setBounds(147, 422, 86, 20);
  233. parameterPanel.add(wildcardUsageField);
  234. wildcardUsageField.setColumns(10);
  235. JLabel lblWildcardUsage = new JLabel("each Wildcard usage");
  236. lblWildcardUsage.setBounds(10, 425, 127, 14);
  237. parameterPanel.add(lblWildcardUsage);
  238. JLabel lblWildcardMutation = new JLabel("Wildcard Mutation Prob");
  239. lblWildcardMutation.setBounds(10, 222, 117, 14);
  240. parameterPanel.add(lblWildcardMutation);
  241. wildcardMutationField = new JTextField();
  242. wildcardMutationField.setText("0.01");
  243. wildcardMutationField.setBounds(147, 219, 86, 20);
  244. parameterPanel.add(wildcardMutationField);
  245. wildcardMutationField.setColumns(10);
  246. JLabel lblEachPartiallySupplied = new JLabel("each partialsupplied Entity");
  247. lblEachPartiallySupplied.setBounds(10, 375, 137, 14);
  248. parameterPanel.add(lblEachPartiallySupplied);
  249. partialSuppliedField = new JTextField();
  250. partialSuppliedField.setText("-2.0");
  251. partialSuppliedField.setBounds(147, 372, 86, 20);
  252. parameterPanel.add(partialSuppliedField);
  253. partialSuppliedField.setColumns(10);
  254. JLabel lblForOverproduction = new JLabel("for 1000 overproduction");
  255. lblForOverproduction.setBounds(10, 450, 117, 14);
  256. parameterPanel.add(lblForOverproduction);
  257. overproductionField = new JTextField();
  258. overproductionField.setText("-5.0");
  259. overproductionField.setBounds(147, 447, 86, 20);
  260. parameterPanel.add(overproductionField);
  261. overproductionField.setColumns(10);
  262. generationAmountField = new JTextField();
  263. generationAmountField.setText("1");
  264. generationAmountField.setBounds(147, 12, 86, 20);
  265. parameterPanel.add(generationAmountField);
  266. generationAmountField.setColumns(10);
  267. JLabel lblNodesInWildcards = new JLabel("Nodes in Wildcards?");
  268. lblNodesInWildcards.setBounds(10, 247, 117, 14);
  269. parameterPanel.add(lblNodesInWildcards);
  270. chckbxWildNodes = new JCheckBox("");
  271. chckbxWildNodes.setBounds(147, 245, 97, 20);
  272. parameterPanel.add(chckbxWildNodes);
  273. logArea = new JTextArea();
  274. rightSplitPane.setRightComponent(logArea);
  275. MouseListener ml = new MouseAdapter() {
  276. public void mousePressed(MouseEvent e) {
  277. int selRow = genTree.getRowForLocation(e.getX(), e.getY());
  278. TreePath selPath = genTree.getPathForLocation(e.getX(), e.getY());
  279. if(selRow != -1) {
  280. if(e.getClickCount() == 1) {
  281. nodeSingleClick(selRow, selPath);
  282. }
  283. else if(e.getClickCount() == 2) {
  284. nodeDoubleClick(selRow, selPath);
  285. }
  286. }
  287. }
  288. };
  289. genTree.addMouseListener(ml);
  290. }
  291. public void nodeSingleClick(int selRow, TreePath selPath){
  292. DefaultMutableTreeNode node = (DefaultMutableTreeNode)selPath.getLastPathComponent();
  293. if(node.getUserObject() instanceof HolegGeneration){
  294. logArea.setText(((HolegGeneration)node.getUserObject()).getInformation());
  295. }
  296. }
  297. public void nodeDoubleClick(int selRow, TreePath selPath){
  298. DefaultMutableTreeNode node = (DefaultMutableTreeNode)selPath.getLastPathComponent();
  299. if(treeIndiHashmap.get(node) != null){
  300. algoHandler.drawIndividualWithPos(treeIndiHashmap.get(node));
  301. logArea.setText(treeIndiHashmap.get(node).log);
  302. }
  303. }
  304. public void populationCreated(HolegGeneration holegGen) {
  305. DefaultMutableTreeNode genNode = new DefaultMutableTreeNode(holegGen);
  306. generationHistory.add(holegGen);
  307. ArrayList<HolegIndividual> population = holegGen.getGeneration();
  308. for(int i = 0; i < population.size(); i++){
  309. DefaultMutableTreeNode child = new DefaultMutableTreeNode("Individual " + i);
  310. population.get(i).setId(holegGen.getGenCount(), i);
  311. treeIndiHashmap.put(child, population.get(i));
  312. genNode.add(child);
  313. }
  314. generationNodes.add(genNode);
  315. treeRoot.insert(genNode, 0);
  316. treeModel.reload();
  317. if(holegGen.getGenCount() == HolegGeneration.ORIGINAL_GEN){
  318. int nodeAmount = holegGen.getGeneration().get(0).getIndexes().size();
  319. int maxEdges = (nodeAmount*(nodeAmount-1))/2;
  320. edgeAmountField.setText(Integer.toString(maxEdges));
  321. params.set(params.ORIGINAL_NETWORK, holegGen.getGeneration().get(0));
  322. }
  323. }
  324. /**
  325. * sets All Parameters from the Textfields into the ParameterArray;
  326. */
  327. public void setParameters(){
  328. params.set(params.MAX_EDGES, Integer.parseInt(edgeAmountField.getText()));
  329. params.set(params.EDIT_EDGES, chckbxEditEdges.isSelected());
  330. params.set(params.POPULATION_SIZE, Integer.parseInt(popSizeField.getText()));
  331. params.set(params.TOURNAMENT_SIZE, Integer.parseInt(tournamentSizeField.getText()));
  332. params.set(params.EDGE_BREAK_AMOUNT, Integer.parseInt(edgeBreakCount.getText()));
  333. params.set(params.SIM_ITERATIONS, Integer.parseInt(iterationsField.getText()));
  334. params.set(params.EDGE_MUTATION_PROB, Double.parseDouble(edgeMutationField.getText()));
  335. params.set(params.SUPPLIED_POINTS, Double.parseDouble(suppliedField.getText()));
  336. params.set(params.OVERSUPPLIED_POINTS, Double.parseDouble(oversuppliedField.getText()));
  337. params.set(params.UNDERSUPPLIED_POINTS, Double.parseDouble(undersuppliedField.getText()));
  338. params.set(params.LENGTH_POINTS, Double.parseDouble(edgeLengthField.getText()));
  339. params.set(params.WILDCARD_USAGE, Double.parseDouble(wildcardUsageField.getText()));
  340. params.set(params.WILDCARD_MUTATION_PROB, Double.parseDouble(wildcardMutationField.getText()));
  341. params.set(params.PARTIALSUPPLIED_POINTS, Double.parseDouble(partialSuppliedField.getText()));
  342. params.set(params.OVERPRODUCTION, Double.parseDouble(overproductionField.getText()));
  343. params.set(params.NODES_IN_WILDCARDS, chckbxWildNodes.isSelected());
  344. params.set(params.TOURNAMENT_PROB, 0.15);
  345. }
  346. }
  347. /*
  348. * This class is Kind of the controller class. It calls the algorithm methods
  349. * and assures the results are transported to the GenAlogWindow
  350. */
  351. public class GenAlgoHandler{
  352. ArrayList<GenAlgoWindow> listeners = new ArrayList<GenAlgoWindow>();
  353. HolegFactory factory;
  354. Control controller;
  355. Model model;
  356. int genCount;
  357. GeneticAlgo holegGA;
  358. TournamentSelection<HolegIndividual> tRS;
  359. HolegFittnessScenario hF;
  360. HolegMutation hM;
  361. HolegCrossover hC;
  362. ArrayList<AbstractCpsObject> objSpace;
  363. CpsNode theNode = new CpsNode("Node");
  364. public GenAlgoHandler(Control controller, Model model){
  365. this.controller = controller;
  366. this.model = model;
  367. genCount = 1;
  368. objSpace = new ArrayList<AbstractCpsObject>();
  369. for(Category cat : model.getCategories()){
  370. for(AbstractCpsObject obj : cat.getObjects()){
  371. if(!(obj instanceof HolonWildCard) /* && obj.useForGA */){
  372. objSpace.add(obj);
  373. }
  374. }
  375. }
  376. ArrayList<AbstractCpsObject> origin = model.getObjectsOnCanvas();
  377. ArrayList<CpsEdge> edges = model.getEdgesOnCanvas();
  378. factory = new HolegFactory(objSpace, 0, 0);
  379. factory.originalObjects = origin;
  380. factory.originalEdges = edges;
  381. hC = new HolegCrossover();
  382. hF = new HolegFittnessScenario(controller);
  383. hM = new HolegMutation(0.01);
  384. hM.setObjectSpace(objSpace);
  385. tRS = new TournamentSelection<HolegIndividual>();
  386. holegGA = new GeneticAlgo(tRS, hC, hM, hF, factory, 0);
  387. }
  388. public void createGeneration(int genAmount, ParameterArray params){
  389. //setting the parameters of the algo components
  390. factory.maxConnections = (int)params.get(params.MAX_EDGES);
  391. factory.editEdges = (boolean)params.get(params.EDIT_EDGES);
  392. holegGA.popSize = (int)params.get(params.POPULATION_SIZE);
  393. tRS.tournamentSize = (int)params.get(params.TOURNAMENT_SIZE);
  394. tRS.selectProb = (double)params.get(params.TOURNAMENT_PROB);
  395. hF.setParameters(params);
  396. if((boolean)params.get(params.NODES_IN_WILDCARDS)){
  397. if(!objSpace.contains(theNode)){
  398. objSpace.add(theNode);
  399. }else{
  400. objSpace.remove(theNode);
  401. }
  402. }
  403. hM.setParameters(params);
  404. for(int i = 0; i < genAmount; i++){
  405. hF.initialize();
  406. if(genCount == 1){
  407. holegGA.generateRandomPopulation();
  408. HolegGeneration holegGen = new HolegGeneration(genCount);
  409. holegGen.setGeneration(holegGA.getSortedPopulation());
  410. addGenToPopulationListeners(holegGen);
  411. }else{
  412. holegGA.createNextGeneration();
  413. HolegGeneration holegGen = new HolegGeneration(genCount);
  414. holegGen.setGeneration(holegGA.getSortedPopulation());
  415. addGenToPopulationListeners(holegGen);
  416. }
  417. genCount++;
  418. }
  419. }
  420. public void drawIndividualWithPos(HolegIndividual hI){
  421. model.setObjectsOnCanvas(new ArrayList<AbstractCpsObject>());
  422. model.setEdgesOnCanvas(new ArrayList<CpsEdge>());
  423. hI.configurateNetwork();
  424. for(int i = 0; i < hI.getIndexes().size(); i++){
  425. controller.addObjectCanvas(hI.getObjectAt(i));
  426. }
  427. for(GAEdge e : hI.getAllEdges()){
  428. controller.addEdgeOnCanvas(e);
  429. }
  430. controller.calculateStateForCurrentTimeStep();
  431. controller.updateCanvas();
  432. }
  433. public void addListener(GenAlgoWindow listener){
  434. listeners.add(listener);
  435. }
  436. public void addGenToPopulationListeners(HolegGeneration holegGen){
  437. for(GenAlgoWindow listener : listeners){
  438. listener.populationCreated(holegGen);
  439. }
  440. }
  441. public ArrayList<HolegIndividual> sortPopulation(ArrayList<HolegIndividual> individuals){
  442. ArrayList<HolegIndividual> sortedList = new ArrayList<HolegIndividual>();
  443. for(HolegIndividual hI : individuals){
  444. for(int i = 0; i <= sortedList.size(); i++){
  445. if(i == sortedList.size()){
  446. sortedList.add(hI);
  447. break;
  448. }else if(sortedList.get(i).getFittness() < hI.getFittness()){
  449. sortedList.add(i, hI);
  450. break;
  451. }
  452. }
  453. }
  454. return sortedList;
  455. }
  456. public void setOriginalNetwork(){
  457. HolegIndividual originIndividual = new HolegIndividual(model.getObjectsOnCanvas(),
  458. model.getEdgesOnCanvas());
  459. HolegGeneration originalGen = new HolegGeneration(HolegGeneration.ORIGINAL_GEN);
  460. hF.calculateFittness(originIndividual);
  461. ArrayList<HolegIndividual> population = new ArrayList<HolegIndividual>();
  462. population.add(originIndividual);
  463. originalGen.setGeneration(population);
  464. addGenToPopulationListeners(originalGen);
  465. }
  466. }
  467. public class HolegIndividual{
  468. public ArrayList<CpsEdge> brokenEdges = new ArrayList<CpsEdge>();
  469. public ArrayList<GAEdge> additionalEdges = new ArrayList<GAEdge>();
  470. public ArrayList<GAEdge> originEdges = new ArrayList<GAEdge>();
  471. public ArrayList<Integer> indexes = new ArrayList<Integer>();
  472. public ArrayList<Integer> originIndexes = new ArrayList<Integer>();
  473. public ArrayList<Integer> wildCardIndexes = new ArrayList<Integer>();
  474. public ArrayList<HolegIndividual> parents = new ArrayList<HolegIndividual>();
  475. public HashMap<Integer, AbstractCpsObject> indexToObjectMap = new HashMap<Integer, AbstractCpsObject>();
  476. private HashMap<AbstractCpsObject, Integer> objectToIndexMap = new HashMap<AbstractCpsObject, Integer>();
  477. public boolean drawn;
  478. public String id;
  479. public String log;
  480. public String backupLog = "Individual Log";
  481. public int gen;
  482. public int pos;
  483. private int lastIndex;
  484. public double totalEdgeLength;
  485. public double fittness;
  486. public HolegIndividual(ArrayList<AbstractCpsObject> originObjects,
  487. ArrayList<CpsEdge> originalEdges){
  488. lastIndex = 0;
  489. log = "Individual Log";
  490. drawn = false;
  491. for(AbstractCpsObject abs : originObjects){
  492. AbstractCpsObject newObj = abs.makeCopy();
  493. newObj.setPosition(abs.getPosition());
  494. newObj.setId(abs.getId());
  495. addObject(newObj);
  496. originIndexes.add(objectToIndexMap.get(newObj));
  497. if(newObj instanceof HolonWildCard){
  498. wildCardIndexes.add(objectToIndexMap.get(newObj));
  499. }
  500. }
  501. if(originalEdges != null){
  502. for(CpsEdge e : originalEdges){
  503. addOriginalEdge(e);
  504. }
  505. }
  506. }
  507. public HolegIndividual(HolegIndividual indi){
  508. additionalEdges = new ArrayList<GAEdge>();
  509. additionalEdges.addAll(indi.getAdditionalEdges());
  510. originEdges = new ArrayList<GAEdge>();
  511. originEdges.addAll(indi.originEdges);
  512. indexes = new ArrayList<Integer>();
  513. indexes.addAll(indi.getIndexes());
  514. originIndexes = new ArrayList<Integer>();
  515. originIndexes.addAll(indi.originIndexes);
  516. parents = new ArrayList<HolegIndividual>();
  517. indexToObjectMap = new HashMap<Integer, AbstractCpsObject>();
  518. objectToIndexMap = new HashMap<AbstractCpsObject, Integer>();
  519. Set<Integer> keys = indi.indexToObjectMap.keySet();
  520. for(Integer i : keys){
  521. indexToObjectMap.put(i, indi.indexToObjectMap.get(i));
  522. objectToIndexMap.put(indi.indexToObjectMap.get(i), i);
  523. }
  524. lastIndex = indi.lastIndex;
  525. log = "Individual Log";
  526. drawn = false;
  527. }
  528. public double getFittness(){
  529. return fittness;
  530. }
  531. public void setFittness(double fittness){
  532. this.fittness = fittness;
  533. }
  534. public ArrayList<HolegIndividual> getParents(){
  535. return parents;
  536. }
  537. public void setParents(ArrayList<HolegIndividual> parents){
  538. this.parents = parents;
  539. for(int i = 0; i < parents.size(); i++){
  540. addLogEntry("Parent" + i + ": " + parents.get(i).getId());
  541. }
  542. backupLog = log;
  543. }
  544. public void setId(int Gen, int pos){
  545. if(Gen > 0){
  546. id = "Generation_" + Gen + " Rank_" + pos;
  547. }else{
  548. id = "Generation_Original";
  549. }
  550. }
  551. public String getId(){
  552. return id;
  553. }
  554. public ArrayList<AbstractCpsObject> getObjects(){
  555. ArrayList<AbstractCpsObject> objects = new ArrayList<AbstractCpsObject>();
  556. for(Integer i : indexes){
  557. objects.add(indexToObjectMap.get(i));
  558. }
  559. return objects;
  560. }
  561. public ArrayList<AbstractCpsObject> getOriginObjects(){
  562. ArrayList<AbstractCpsObject> originObjects = new ArrayList<AbstractCpsObject>();
  563. for(Integer i : originIndexes){
  564. originObjects.add(indexToObjectMap.get(i));
  565. }
  566. return originObjects;
  567. }
  568. public AbstractCpsObject getObjectWithIndex(int index){
  569. return indexToObjectMap.get(index);
  570. }
  571. public AbstractCpsObject getObjectAt(int position){
  572. return indexToObjectMap.get(indexes.get(position));
  573. }
  574. public ArrayList<Integer> getIndexes(){
  575. return indexes;
  576. }
  577. public ArrayList<Integer> getWildcardIndexes(){
  578. return wildCardIndexes;
  579. }
  580. public ArrayList<GAEdge> getAdditionalEdges(){
  581. return additionalEdges;
  582. }
  583. public ArrayList<GAEdge> getOriginalEdges(){
  584. return originEdges;
  585. }
  586. public ArrayList<GAEdge> getAllEdges(){
  587. ArrayList<GAEdge> allEdges = new ArrayList<GAEdge>();
  588. allEdges.addAll(additionalEdges);
  589. allEdges.addAll(originEdges);
  590. return allEdges;
  591. }
  592. public void addObject(AbstractCpsObject obj){
  593. addObjectWithIdx(obj, obj.getId());
  594. }
  595. public void addObjectWithIdx(AbstractCpsObject obj, int index){
  596. if(!indexToObjectMap.containsKey(index)){
  597. addIndex(index);
  598. indexToObjectMap.put(index, obj);
  599. objectToIndexMap.put(obj, index);
  600. }else{
  601. objectToIndexMap.remove(indexToObjectMap.get(index));
  602. indexToObjectMap.put(index, obj);
  603. objectToIndexMap.put(obj, index);
  604. }
  605. //indexToObjectMap.put(index, obj);
  606. }
  607. public void removeObject(int index){
  608. AbstractCpsObject toRemove = indexToObjectMap.get(index);
  609. HolonWildCard fill = new HolonWildCard("WildCard");
  610. fill.setId(toRemove.getId());
  611. fill.setPosition(toRemove.getPosition());
  612. indexToObjectMap.put(index, fill);
  613. }
  614. public void addIndex(int index){
  615. for(int i = 0; i < indexes.size(); i++){
  616. if(index < indexes.get(i)){
  617. indexes.add(i, index);
  618. return;
  619. }
  620. }
  621. indexes.add(index);
  622. return;
  623. }
  624. /*
  625. * posA and posB are the indexes of the Endpoints A and B in the list of Objects
  626. */
  627. public void addEdge(int indexA, int indexB){
  628. if(!edgeExists(indexA, indexB, getAllEdges())){
  629. if(!indexToObjectMap.containsKey(indexA)){
  630. CpsNode newObjA = new CpsNode("Node");
  631. addObjectWithIdx(newObjA, indexA);
  632. }
  633. if(!indexToObjectMap.containsKey(indexB)){
  634. CpsNode newObjB = new CpsNode("Node");
  635. addObjectWithIdx(newObjB, indexB);
  636. }
  637. additionalEdges.add(new GAEdge(indexA, indexB, indexToObjectMap.get(indexA), indexToObjectMap.get(indexB)));
  638. }
  639. }
  640. public void addOriginalEdge(CpsEdge e){
  641. if(indexToObjectMap.containsKey(e.getA().getId()) && indexToObjectMap.containsKey(e.getB().getId())){
  642. GAEdge realEdge = new GAEdge(e.getA().getId(), e.getB().getId(),
  643. indexToObjectMap.get(e.getA().getId()), indexToObjectMap.get(e.getB().getId()));
  644. if(!edgeExists(realEdge.aPos, realEdge.bPos, originEdges)){
  645. originEdges.add(realEdge);
  646. }
  647. }
  648. }
  649. public void addOriginalEdge(GAEdge e){
  650. if(!edgeExists(e.aPos, e.bPos, originEdges)){
  651. originEdges.add(new GAEdge(e.aPos, e.bPos, indexToObjectMap.get(e.aPos),
  652. indexToObjectMap.get(e.bPos)));
  653. }
  654. }
  655. public boolean edgeExists(int indexA, int indexB, ArrayList<GAEdge> edges){
  656. for(GAEdge e : edges){
  657. if((e.aPos == indexA && e.bPos == indexB) || (e.bPos == indexA && e.aPos == indexB)){
  658. return true;
  659. }
  660. }
  661. return false;
  662. }
  663. public void addLogEntry(String entry){
  664. log += "\n" + entry;
  665. }
  666. public void resetLog(){
  667. log = backupLog;
  668. }
  669. public int getAvailableIndex(){
  670. for(int i = 0; i <= indexes.size(); i++){
  671. if(!indexes.contains(i)){
  672. return i;
  673. }
  674. }
  675. return -1;
  676. }
  677. public void configurateNetwork(){
  678. //hier womöglich vorher alle edges von allen Knoten entfernen
  679. for(GAEdge e : getAllEdges()){
  680. e.setA(indexToObjectMap.get(e.aPos));
  681. e.setB(indexToObjectMap.get(e.bPos));
  682. e.revalidateConnection();
  683. }
  684. }
  685. public void setEdgeLength(double doubleValue) {
  686. totalEdgeLength = doubleValue;
  687. }
  688. }
  689. public class HolegGeneration{
  690. public static final int ORIGINAL_GEN = -1;
  691. ArrayList<HolegIndividual> generation;
  692. int genCount;
  693. String name;
  694. String log;
  695. public HolegGeneration(int genCount){
  696. this.genCount = genCount;
  697. generation = new ArrayList<HolegIndividual>();
  698. if(genCount >= 0){
  699. name = "Generation " + genCount;
  700. }else{
  701. name = "Original Network";
  702. }
  703. }
  704. public void setGeneration(ArrayList<HolegIndividual> generation){
  705. this.generation = generation;
  706. }
  707. public ArrayList<HolegIndividual> getGeneration(){
  708. return generation;
  709. }
  710. public int getGenCount(){
  711. return genCount;
  712. }
  713. @Override
  714. public String toString(){
  715. return name;
  716. }
  717. public String getInformation(){
  718. log = "Generation Log";
  719. if(generation.size() > 0){
  720. addLogEntry("Avg Fittness: " + getAvgFittness());
  721. addLogEntry("Max Fittness: " + getMaxFittness());
  722. addLogEntry("Min Fittness: " + getMinFittness());
  723. }
  724. return log;
  725. }
  726. public double getAvgFittness(){
  727. double fittness = 0;
  728. for(HolegIndividual i : generation){
  729. fittness += i.getFittness();
  730. }
  731. return (fittness/generation.size());
  732. }
  733. public double getMinFittness(){
  734. double fittness = generation.get(0).getFittness();
  735. for(HolegIndividual i : generation){
  736. if(i.getFittness() < fittness){
  737. fittness = i.getFittness();
  738. }
  739. }
  740. return fittness;
  741. }
  742. public double getMaxFittness(){
  743. double fittness = generation.get(0).getFittness();
  744. for(HolegIndividual i : generation){
  745. if(i.getFittness() > fittness){
  746. fittness = i.getFittness();
  747. }
  748. }
  749. return fittness;
  750. }
  751. public void addLogEntry(String entry){
  752. log += "\n" + entry;
  753. }
  754. }
  755. public class ParameterArray{
  756. public static final int POPULATION_SIZE = 0;
  757. public static final int TOURNAMENT_SIZE = 1;
  758. public static final int EDIT_EDGES = 2;
  759. public static final int MAX_EDGES = 3;
  760. public static final int EDGE_BREAK_AMOUNT = 4;
  761. public static final int SIM_ITERATIONS = 5;
  762. public static final int EDGE_MUTATION_PROB = 6;
  763. public static final int SUPPLIED_POINTS = 7;
  764. public static final int UNDERSUPPLIED_POINTS = 8;
  765. public static final int OVERSUPPLIED_POINTS = 9;
  766. public static final int LENGTH_POINTS = 10;
  767. public static final int WILDCARD_MUTATION_PROB = 11;
  768. public static final int PARTIALSUPPLIED_POINTS = 12;
  769. public static final int WILDCARD_USAGE = 13;
  770. public static final int OVERPRODUCTION = 14;
  771. public static final int NODES_IN_WILDCARDS = 15;
  772. public static final int OBJECT_SPACE = 16;
  773. public static final int ORIGINAL_NETWORK = 17;
  774. public static final int TOURNAMENT_PROB = 18;
  775. public ArrayList<Object> list = new ArrayList<Object>();
  776. public ParameterArray(){
  777. for(int i = 0; i < 19; i++){
  778. list.add(new Object());
  779. }
  780. }
  781. public Object get(int index){
  782. return list.get(index);
  783. }
  784. public <T extends Object> void set(int index, T object){
  785. list.set(index, object);
  786. }
  787. }
  788. public class GAEdge extends CpsEdge{
  789. public int aPos;
  790. public int bPos;
  791. public GAEdge(int a, int b, AbstractCpsObject nodeA, AbstractCpsObject nodeB){
  792. //super(nodeA,nodeB, CAPACITY_INFINITE);
  793. super(nodeA,nodeB, 100000);
  794. aPos = a;
  795. bPos = b;
  796. }
  797. public void revalidateConnection(){
  798. if(!this.getA().getConnections().contains(this)){
  799. this.getA().getConnections().add(this);
  800. }
  801. if(!this.getB().getConnections().contains(this)){
  802. this.getB().getConnections().add(this);
  803. }
  804. }
  805. }
  806. public class HolonWildCard extends AbstractCpsObject{
  807. AbstractCpsObject holdingObject;
  808. public HolonWildCard(String objName){
  809. super(objName);
  810. this.setConnections(new ArrayList<CpsEdge>());
  811. this.setImage("/Images/wildCard.png");
  812. this.setSav("CVS");
  813. this.setId(IdCounter.nextId());
  814. holdingObject = this;
  815. }
  816. public HolonWildCard(AbstractCpsObject obj) {
  817. super(obj);
  818. holdingObject = this;
  819. }
  820. //@Override
  821. public AbstractCpsObject makeCopy() {
  822. return new HolonWildCard(this);
  823. }
  824. public void setHoldingObject(AbstractCpsObject object){
  825. this.holdingObject = object;
  826. }
  827. public AbstractCpsObject getHoldingObject(){
  828. return holdingObject;
  829. }
  830. }
  831. public class GeneticAlgo{
  832. public int popSize;
  833. public ArrayList<HolegIndividual> population;
  834. public HolegFactory randomFactory;
  835. public TournamentSelection<HolegIndividual> selector;
  836. public HolegCrossover reproducer;
  837. public HolegMutation mutator;
  838. public HolegFittnessScenario fittnessFunction;
  839. public double topPercent;
  840. public double buttomPercent;
  841. public GeneticAlgo(TournamentSelection<HolegIndividual> selection, HolegCrossover crossover,
  842. HolegMutation mutator, HolegFittnessScenario fittnessFkt,
  843. HolegFactory factory, int popSize){
  844. this.selector = selection;
  845. this.reproducer = crossover;
  846. this.mutator = mutator;
  847. this.fittnessFunction = fittnessFkt;
  848. randomFactory = factory;
  849. this.popSize = popSize;
  850. population = new ArrayList<HolegIndividual>();
  851. topPercent = 0.05;
  852. //generateRandomPopulation();
  853. }
  854. public void generateRandomPopulation() {
  855. population = new ArrayList<HolegIndividual>();
  856. for(int i = 0; i < popSize; i++){
  857. population.add(randomFactory.createRandomIndividual());
  858. fittnessFunction.calculateFittness(population.get(i));
  859. }
  860. }
  861. public void createNextGeneration(){
  862. ArrayList<HolegIndividual> nextGen = new ArrayList<HolegIndividual>();
  863. int topBound = (int) Math.ceil(topPercent * popSize);
  864. //int topBound = 1;
  865. population = getSortedPopulation();
  866. for(HolegIndividual individual : population.subList(0, topBound)){
  867. ArrayList<HolegIndividual> childs = new ArrayList<HolegIndividual>();
  868. childs.add(individual);
  869. childs.add(individual);
  870. childs = reproducer.crossOver(childs);
  871. for(HolegIndividual i : childs){
  872. i.addLogEntry("Top % from previous gen");
  873. fittnessFunction.calculateFittness(i);
  874. nextGen.add(i);
  875. }
  876. }
  877. selector.setCurrentPopulation(population);
  878. while(nextGen.size() < popSize){
  879. ArrayList<HolegIndividual> freshInds = new ArrayList<HolegIndividual>();
  880. freshInds = reproducer.crossOver(selector.selectIndividuals());
  881. for(HolegIndividual i : freshInds){
  882. i = mutator.mutateIndividual(i);
  883. fittnessFunction.calculateFittness(i);
  884. }
  885. nextGen.addAll(freshInds);
  886. }
  887. if(popSize % 2 == 1){
  888. Random rnd = new Random();
  889. nextGen.remove(rnd.nextInt(popSize));
  890. }
  891. population = nextGen;
  892. }
  893. public ArrayList<HolegIndividual> getPopulation(){
  894. return population;
  895. }
  896. public ArrayList<HolegIndividual> getSortedPopulation(){
  897. return sortPopulation(population);
  898. }
  899. public ArrayList<HolegIndividual> sortPopulation(ArrayList<HolegIndividual> individuals){
  900. ArrayList<HolegIndividual> sortedList = new ArrayList<HolegIndividual>();
  901. for(HolegIndividual hI : individuals){
  902. for(int i = 0; i <= sortedList.size(); i++){
  903. if(i == sortedList.size()){
  904. sortedList.add(hI);
  905. break;
  906. }else if(sortedList.get(i).getFittness() < hI.getFittness()){
  907. sortedList.add(i, hI);
  908. break;
  909. }
  910. }
  911. }
  912. return sortedList;
  913. }
  914. }
  915. public class HolegFactory{
  916. ArrayList<AbstractCpsObject> objectSpace;
  917. public ArrayList<AbstractCpsObject> originalObjects;
  918. public ArrayList<CpsEdge> originalEdges;
  919. public int maxObjects;
  920. public int maxConnections;
  921. HolegMutation mutation;
  922. Random rng;
  923. public boolean editEdges;
  924. public HolegFactory(ArrayList<AbstractCpsObject> objects, int maxObjects, int maxConnections){
  925. objectSpace = objects;
  926. this.maxObjects = maxObjects;
  927. this.maxConnections = maxConnections;
  928. rng = new Random();
  929. originalObjects = new ArrayList<AbstractCpsObject>();
  930. originalEdges = new ArrayList<CpsEdge>();
  931. editEdges = false;
  932. mutation = new HolegMutation();
  933. }
  934. public HolegIndividual createRandomIndividual() {
  935. HolegIndividual hI = new HolegIndividual(originalObjects, originalEdges);
  936. setWildCards(hI);
  937. if(editEdges){
  938. editEdges(hI);
  939. }
  940. if(maxConnections > 0){
  941. createEdges(hI);
  942. }
  943. return hI;
  944. }
  945. private void setWildCards(HolegIndividual hI) {
  946. int setAmount = rng.nextInt(hI.getWildcardIndexes().size() + 1);
  947. ArrayList<Integer> list = new ArrayList<Integer>();
  948. list.addAll(hI.getWildcardIndexes());
  949. Collections.shuffle(list);
  950. int spaceIdx = 0;
  951. if(objectSpace.size() > 0){
  952. for(int i = 0; i < setAmount; i++){
  953. AbstractCpsObject wildCard = hI.indexToObjectMap.get(list.get(i));
  954. spaceIdx = rng.nextInt(objectSpace.size());
  955. AbstractCpsObject newObj = objectSpace.get(spaceIdx).makeCopy();
  956. newObj.setPosition(wildCard.getPosition());
  957. newObj.setId(wildCard.getId());
  958. hI.addObjectWithIdx(newObj, newObj.getId());
  959. }
  960. }
  961. }
  962. private void editEdges(HolegIndividual hI) {
  963. if(hI.getOriginalEdges().size() > 0 && hI.getIndexes().size() > 2){
  964. int editAmount = rng.nextInt(hI.getOriginalEdges().size());
  965. for(int i = 0; i < editAmount; i++){
  966. int edgeIdx = rng.nextInt(hI.getOriginalEdges().size());
  967. GAEdge toChange = hI.getOriginalEdges().get(edgeIdx);
  968. mutation.changeSingleEdge(hI, toChange, true);
  969. }
  970. }
  971. }
  972. public void createObjects(HolegIndividual hI){
  973. int objCount = rng.nextInt(maxObjects) + 1;
  974. for(int i = 0; i < objCount; i++){
  975. AbstractCpsObject newObj = null;
  976. if(!editEdges){
  977. AbstractCpsObject absObj = objectSpace.get(rng.nextInt(objectSpace.size()));
  978. if(absObj instanceof HolonObject){
  979. newObj = new HolonObject(absObj);
  980. }else if(absObj instanceof HolonSwitch){
  981. newObj = new HolonSwitch(absObj);
  982. }else if(absObj instanceof HolonBattery){
  983. newObj = new HolonBattery(absObj);
  984. }else if(absObj instanceof HolonWildCard){
  985. newObj = new HolonWildCard(absObj);
  986. }else if(absObj == null){
  987. newObj = new CpsNode("Node");
  988. }
  989. }else{
  990. newObj = new CpsNode("Node");
  991. }
  992. hI.addObject(newObj);
  993. }
  994. }
  995. public void createEdges(HolegIndividual hI){
  996. if(hI.getIndexes().size() > 1){
  997. int edgeCount = rng.nextInt(maxConnections + 1);
  998. ArrayList<Integer> list = new ArrayList<Integer>();
  999. for (int i = 0; i < hI.getIndexes().size(); i++) {
  1000. list.add(hI.getIndexes().get(i));
  1001. }
  1002. if(edgeCount >= hI.getAllEdges().size()){
  1003. edgeCount -= hI.getAllEdges().size();
  1004. }else{
  1005. edgeCount = 0;
  1006. }
  1007. for(int i = 0; i < edgeCount; i++){
  1008. Collections.shuffle(list);
  1009. int aPos = list.get(0);
  1010. int bPos = list.get(1);
  1011. hI.addEdge(aPos, bPos);
  1012. }
  1013. }
  1014. }
  1015. }
  1016. public class TournamentSelection<I extends HolegIndividual>{
  1017. public class Range{
  1018. public double min;
  1019. public double max;
  1020. public Range(double min, double max){
  1021. this.min = min;
  1022. this.max = max;
  1023. }
  1024. }
  1025. private ArrayList<I> currentPop;
  1026. public int tournamentSize;
  1027. private Random rng;
  1028. private ArrayList<Range> tournamentWheel;
  1029. public ArrayList<I> competitors;
  1030. public double selectProb;
  1031. private double maxRange;
  1032. public TournamentSelection(){
  1033. currentPop = new ArrayList<I>();
  1034. tournamentSize = 1;
  1035. rng = new Random();
  1036. selectProb = 1;
  1037. }
  1038. public TournamentSelection(int tSize, double selectProb){
  1039. currentPop = new ArrayList<I>();
  1040. rng = new Random();
  1041. tournamentSize = tSize;
  1042. this.selectProb = selectProb;
  1043. }
  1044. public void setCurrentPopulation(ArrayList<I> population) {
  1045. currentPop = population;
  1046. }
  1047. public void setTournamentSize(int size){
  1048. tournamentSize = size;
  1049. }
  1050. public ArrayList<I> selectIndividuals() {
  1051. ArrayList<I> parents = new ArrayList<I>();
  1052. parents.add(selectSingleIndividual());
  1053. parents.add(selectSingleIndividual());
  1054. return parents;
  1055. }
  1056. public I selectSingleIndividual(){
  1057. tournamentSelection();
  1058. initWheel();
  1059. double index = rng.nextDouble() * maxRange;
  1060. for(int i = 0; i < tournamentWheel.size(); i++){
  1061. if(index >= tournamentWheel.get(i).min && index <= tournamentWheel.get(i).max){
  1062. return competitors.get(i);
  1063. }
  1064. }
  1065. return competitors.get(rng.nextInt(competitors.size()));
  1066. }
  1067. public void tournamentSelection(){
  1068. competitors = new ArrayList<I>();
  1069. for(int i = 0; i < tournamentSize; i++){
  1070. I candidate = chooseCandidate();
  1071. int size = competitors.size();
  1072. for(int j = 0; j <= size; j++){
  1073. if(j != size){
  1074. if(competitors.get(j).getFittness() < candidate.getFittness()){
  1075. competitors.add(j, candidate);
  1076. break;
  1077. }
  1078. }else{
  1079. competitors.add(candidate);
  1080. }
  1081. }
  1082. }
  1083. }
  1084. public I chooseCandidate(){
  1085. int index = rng.nextInt(currentPop.size());
  1086. I candidate = currentPop.get(index);
  1087. return candidate;
  1088. }
  1089. public void initWheel(){
  1090. tournamentWheel = new ArrayList<Range>();
  1091. int power = 0;
  1092. maxRange = 0;
  1093. for(int i = 0; i < tournamentSize; i++){
  1094. double currentProb = selectProb * Math.pow((1- selectProb), power);
  1095. Range range = new Range(maxRange, maxRange + currentProb);
  1096. tournamentWheel.add(range);
  1097. maxRange += currentProb;
  1098. power++;
  1099. }
  1100. }
  1101. }
  1102. public class HolegFittnessScenario{
  1103. HolegFittnessFkt singleFkt;
  1104. Control controller;
  1105. Model model;
  1106. SimulationManager simManager;
  1107. ParameterArray params;
  1108. int edgeBreakCount;
  1109. double edgeLengthPoints;
  1110. double wildcardPoints;
  1111. double overprodPoints;
  1112. int totalSteps = 100;
  1113. int singleStep;
  1114. int breakCounter = 0;
  1115. HolegIndividual originalNetwork;
  1116. ArrayList<Integer> edgeBreakingIndexes = new ArrayList<Integer>();
  1117. double globalOverProd;
  1118. Random rng = new Random();
  1119. public HolegFittnessScenario(Control controller) {
  1120. singleFkt = new HolegFittnessFkt(controller);
  1121. model = singleFkt.getModel();
  1122. }
  1123. public double calculateFittness(HolegIndividual candidate) {
  1124. globalOverProd = 0;
  1125. double fittness = 0;
  1126. double noBreakFittness = calcFittnessWithoutBreak(candidate);
  1127. fittness += noBreakFittness;
  1128. candidate.addLogEntry("Fittness without break: " + noBreakFittness);
  1129. double breakFittness = calcFittnessWithBreak(candidate);
  1130. candidate.addLogEntry("Fittness with break: " + breakFittness);
  1131. fittness += breakFittness;
  1132. fittness = fittness /2;
  1133. globalOverProd = globalOverProd / 2;
  1134. globalOverProd = globalOverProd / totalSteps;
  1135. for(Integer wildIdx : candidate.getWildcardIndexes()){
  1136. if(!(candidate.indexToObjectMap.get(wildIdx) instanceof HolonWildCard)){
  1137. fittness += wildcardPoints;
  1138. }
  1139. }
  1140. double edgeLength = 0;
  1141. for(GAEdge e : candidate.getAllEdges()){
  1142. Position aPos = e.getA().getPosition();
  1143. Position bPos = e.getB().getPosition();
  1144. double xDiff = Math.abs(aPos.x - bPos.x);
  1145. double yDiff = Math.abs(aPos.y - bPos.y);
  1146. edgeLength += Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2));
  1147. }
  1148. candidate.setEdgeLength(getRoundedValue(edgeLength));
  1149. candidate.addLogEntry("Total Edge Length: " + getRoundedValue(edgeLength));
  1150. fittness += (edgeLength/100)*edgeLengthPoints;
  1151. candidate.addLogEntry("average Overproduction: " + getRoundedValue(globalOverProd));
  1152. candidate.setFittness(getRoundedValue(fittness));
  1153. candidate.addLogEntry("Fittness: " + getRoundedValue(fittness));
  1154. return fittness;
  1155. }
  1156. public double calcFittnessWithoutBreak(HolegIndividual candidate){
  1157. double fittness = 0;
  1158. double avgOverProduction = 0;
  1159. for(CpsEdge edge : candidate.brokenEdges){
  1160. //edge.setWorkingState(true);
  1161. }
  1162. candidate.brokenEdges.clear();
  1163. for(int i = 0; i < totalSteps; i++){
  1164. model.setCurIteration(singleStep * i);
  1165. fittness += singleFkt.calculateFittness(candidate);
  1166. avgOverProduction += singleFkt.getCurrentOverProduction();
  1167. }
  1168. globalOverProd += avgOverProduction;
  1169. fittness += (avgOverProduction / 1000) * overprodPoints;
  1170. fittness = (int)fittness;
  1171. fittness = fittness/totalSteps;
  1172. return fittness;
  1173. }
  1174. public double calcFittnessWithBreak(HolegIndividual candidate){
  1175. double fittness = 0;
  1176. double avgOverProduction = 0;
  1177. for(CpsEdge edge : candidate.brokenEdges){
  1178. //edge.setWorkingState(true);
  1179. }
  1180. breakEdges(candidate);
  1181. for(int i = 0; i < totalSteps; i++){
  1182. model.setCurIteration(singleStep * i);
  1183. fittness += singleFkt.calculateFittness(candidate);
  1184. avgOverProduction += singleFkt.getCurrentOverProduction();
  1185. }
  1186. globalOverProd += avgOverProduction;
  1187. fittness += (avgOverProduction / 1000) * overprodPoints;
  1188. fittness = (int)fittness;
  1189. fittness = fittness/totalSteps;
  1190. return fittness;
  1191. }
  1192. private void breakEdges(HolegIndividual candidate) {
  1193. candidate.brokenEdges.clear();
  1194. int unbrokenEdges = 0;
  1195. for(Integer idx : edgeBreakingIndexes){
  1196. ArrayList<CpsEdge> healthyEdges = new ArrayList<CpsEdge>();
  1197. for(CpsEdge edge : candidate.indexToObjectMap.get(idx).getConnections()){
  1198. /*
  1199. if(edge.isWorking()){
  1200. healthyEdges.add(edge);
  1201. }
  1202. */
  1203. }
  1204. Collections.shuffle(healthyEdges);
  1205. if(healthyEdges.size() > 0){
  1206. //healthyEdges.get(0).setWorkingState(false);
  1207. candidate.brokenEdges.add(healthyEdges.get(0));
  1208. }else{
  1209. unbrokenEdges++;
  1210. }
  1211. }
  1212. if(unbrokenEdges > 0){
  1213. ArrayList<CpsEdge> healthyEdges = new ArrayList<CpsEdge>();
  1214. for(CpsEdge edge : candidate.getAllEdges()){
  1215. /*
  1216. if(edge.isWorking()){
  1217. healthyEdges.add(edge);
  1218. }
  1219. */
  1220. }
  1221. Collections.shuffle(healthyEdges);
  1222. int bound;
  1223. if(unbrokenEdges <= healthyEdges.size()){
  1224. bound = unbrokenEdges;
  1225. }else{
  1226. bound = healthyEdges.size();
  1227. }
  1228. for(int i = 0; i < bound; i++){
  1229. //healthyEdges.get(i).setWorkingState(false);
  1230. }
  1231. }
  1232. }
  1233. public void setParameters(ParameterArray params){
  1234. this.params = params;
  1235. edgeBreakCount = (int)params.get(params.EDGE_BREAK_AMOUNT);
  1236. edgeLengthPoints = (double)params.get(params.LENGTH_POINTS);
  1237. wildcardPoints = (double)params.get(params.WILDCARD_USAGE);
  1238. totalSteps = (int)params.get(params.SIM_ITERATIONS);
  1239. overprodPoints = (double)params.get(params.OVERPRODUCTION);
  1240. originalNetwork = (HolegIndividual)params.get(params.ORIGINAL_NETWORK);
  1241. if(totalSteps < 100){
  1242. singleStep = (int) Math.floor(100/totalSteps);
  1243. }else{
  1244. singleStep = 1;
  1245. }
  1246. singleFkt.setParameters(params);
  1247. }
  1248. /*
  1249. * method is called before a new generation is calculated
  1250. * setting the specific edge breaks here
  1251. */
  1252. public void initialize(){
  1253. edgeBreakingIndexes.clear();
  1254. ArrayList<Integer> objIndexes = new ArrayList<Integer>();
  1255. objIndexes.addAll(originalNetwork.getIndexes());
  1256. Collections.shuffle(objIndexes);
  1257. //shuffeling leads to random selection of Indexes
  1258. int bound;
  1259. if(edgeBreakCount <= objIndexes.size()){
  1260. bound = edgeBreakCount;
  1261. }else{
  1262. bound = objIndexes.size();
  1263. }
  1264. for(int i = 0; i < bound; i++){
  1265. edgeBreakingIndexes.add(objIndexes.get(rng.nextInt(objIndexes.size())));
  1266. }
  1267. }
  1268. public double getRoundedValue(double value){
  1269. BigDecimal bd = new BigDecimal(value);
  1270. bd = bd.setScale(2, RoundingMode.HALF_UP);
  1271. return bd.doubleValue();
  1272. }
  1273. }
  1274. public class HolegFittnessFkt{
  1275. Control controller;
  1276. Model model;
  1277. SimulationManager simManager;
  1278. ParameterArray params;
  1279. double suppliedPoints;
  1280. double oversuppliedPoints;
  1281. double undersuppliedPoints;
  1282. double partiallysuppliedPoints;
  1283. boolean everyoneSupplied;
  1284. public HolegFittnessFkt(Control controller){
  1285. model = new Model();
  1286. simManager = new SimulationManager(model);
  1287. }
  1288. public double calculateFittness(HolegIndividual candidate){
  1289. model.getObjectsOnCanvas().clear();
  1290. model.getEdgesOnCanvas().clear();
  1291. candidate.configurateNetwork();
  1292. model.getObjectsOnCanvas().addAll(candidate.getObjects());
  1293. model.getEdgesOnCanvas().addAll(candidate.getAllEdges());
  1294. simManager.calculateStateForTimeStep(model.getCurIteration());
  1295. DecoratedState state = simManager.getDecorState(model.getCurIteration());
  1296. everyoneSupplied = true;
  1297. double fittness = 0;
  1298. for(DecoratedNetwork net : state.getNetworkList()){
  1299. fittness += net.getConsumerSelfSuppliedList().stream().map(con -> con.getState()).map(objState -> StateToFitness(objState)).reduce(0.0,(a,b)->(a+b));
  1300. fittness += net.getConsumerList().stream().map(con -> con.getState()).map(objState -> StateToFitness(objState)).reduce(0.0,(a,b)->(a+b));
  1301. }
  1302. return fittness;
  1303. }
  1304. public double StateToFitness(HolonObjectState state){
  1305. switch (state) {
  1306. case NOT_SUPPLIED:
  1307. return undersuppliedPoints;
  1308. case NO_ENERGY:
  1309. return 0f;
  1310. case OVER_SUPPLIED:
  1311. return oversuppliedPoints;
  1312. case PARTIALLY_SUPPLIED:
  1313. return partiallysuppliedPoints;
  1314. case PRODUCER:
  1315. return 0f;
  1316. case SUPPLIED:
  1317. return suppliedPoints;
  1318. default:
  1319. return 0f;
  1320. }
  1321. }
  1322. public float getCurrentOverProduction(){
  1323. float overProd = 0;
  1324. /*
  1325. for(SubNet subnet : simManager.getSubNets()){
  1326. overProd += subnet.spareProduction;
  1327. }
  1328. * */
  1329. return overProd;
  1330. }
  1331. public boolean getEveryoneSupplied(){
  1332. return everyoneSupplied;
  1333. }
  1334. public Model getModel(){
  1335. return model;
  1336. }
  1337. public void setParameters(ParameterArray params){
  1338. this.params = params;
  1339. suppliedPoints = (double)params.get(params.SUPPLIED_POINTS);
  1340. oversuppliedPoints = (double)params.get(params.OVERSUPPLIED_POINTS);
  1341. undersuppliedPoints = (double)params.get(params.UNDERSUPPLIED_POINTS);
  1342. partiallysuppliedPoints = (double)params.get(params.PARTIALSUPPLIED_POINTS);
  1343. }
  1344. }
  1345. public class HolegCrossover{
  1346. protected double crossProb;
  1347. protected Random rng;
  1348. public HolegCrossover(double prob){
  1349. crossProb = prob;
  1350. rng = new Random();
  1351. }
  1352. public HolegCrossover(){
  1353. crossProb = 0.7;
  1354. rng = new Random();
  1355. }
  1356. public void setCrossoverProbability(double prob){
  1357. crossProb = prob;
  1358. }
  1359. public double getCrossoverProbability(){
  1360. return crossProb;
  1361. }
  1362. public ArrayList<HolegIndividual> crossOver(ArrayList<HolegIndividual> parents) {
  1363. HolegIndividual parent1 = parents.get(0);
  1364. HolegIndividual parent2 = parents.get(1);
  1365. ArrayList<HolegIndividual> children = new ArrayList<HolegIndividual>();
  1366. children.add(createChild(parent1, parent2));
  1367. children.add(createChild(parent2, parent1));
  1368. return children;
  1369. }
  1370. private HolegIndividual createChild(HolegIndividual parent1, HolegIndividual parent2) {
  1371. HolegIndividual child = new HolegIndividual(parent1.getOriginObjects(), null);
  1372. ArrayList<HolegIndividual> parents = new ArrayList<HolegIndividual>();
  1373. parents.add(parent1);
  1374. parents.add(parent2);
  1375. child.setParents(parents);
  1376. ArrayList<Integer> parent1WildCardIndexes = parent1.wildCardIndexes;
  1377. int splitIdx = (int) Math.ceil((double)parent1WildCardIndexes.size()/2);
  1378. for(int i = 0; i < splitIdx; i++){
  1379. int index = parent1WildCardIndexes.get(i);
  1380. AbstractCpsObject wildObj = parent1.indexToObjectMap.get(index);
  1381. AbstractCpsObject newWildObj = wildObj.makeCopy();
  1382. newWildObj.setId(wildObj.getId());
  1383. newWildObj.setPosition(wildObj.getPosition());
  1384. child.addObject(newWildObj);
  1385. }
  1386. int restAmount = parent1WildCardIndexes.size() - splitIdx;
  1387. ArrayList<Integer> parent2WildCardIndexes = parent2.wildCardIndexes;
  1388. for(int j = 0; j < restAmount; j++){
  1389. int index = parent2WildCardIndexes.size() - 1; //greift auf letztes element zu
  1390. index -= j; //greift bei jedem durchlauf auf ein weiter vorderes element zu
  1391. if(index >= 0){
  1392. int objIdx = parent2WildCardIndexes.get(index);
  1393. AbstractCpsObject wildObj = parent2.indexToObjectMap.get(objIdx);
  1394. AbstractCpsObject newWildObj = wildObj.makeCopy();
  1395. newWildObj.setId(wildObj.getId());
  1396. newWildObj.setPosition(wildObj.getPosition());
  1397. child.addObject(newWildObj);
  1398. }else{
  1399. break;
  1400. }
  1401. }
  1402. child.wildCardIndexes = parent1.wildCardIndexes;
  1403. //OriginEdges
  1404. splitIdx = (int) Math.ceil((double)parent1.getOriginalEdges().size()/2);
  1405. for(int i = 0; i < splitIdx; i++){
  1406. child.addOriginalEdge(parent1.getOriginalEdges().get(i));
  1407. }
  1408. restAmount = parent1.getOriginalEdges().size() - splitIdx;
  1409. for(int j = 0; j < restAmount; j++){
  1410. int idx = parent2.getOriginalEdges().size() - 1;
  1411. idx -= j;
  1412. if(idx >= 0){
  1413. child.addOriginalEdge(parent2.getOriginalEdges().get(idx));
  1414. }
  1415. }
  1416. //HolonEdges
  1417. splitIdx = (int) Math.ceil((double)parent1.getAdditionalEdges().size()/2);
  1418. for(int k = 0; k < splitIdx; k++){
  1419. int posA = parent1.getAdditionalEdges().get(k).aPos;
  1420. int posB = parent1.getAdditionalEdges().get(k).bPos;
  1421. child.addEdge(posA, posB);
  1422. }
  1423. restAmount = parent1.getAdditionalEdges().size() - splitIdx;
  1424. for(int l = 0; l < restAmount; l++){
  1425. int idx = parent2.getAdditionalEdges().size() - 1;
  1426. idx -= l;
  1427. if(idx >= 0){
  1428. int posA = parent2.getAdditionalEdges().get(idx).aPos;
  1429. int posB = parent2.getAdditionalEdges().get(idx).bPos;
  1430. child.addEdge(posA, posB);
  1431. }
  1432. }
  1433. return child;
  1434. }
  1435. }
  1436. public class HolegMutation{
  1437. protected double mutationProb;
  1438. public Random rng = new Random();
  1439. public final int ADD_EDGE = 0;
  1440. public final int REMOVE_EDGE = 1;
  1441. public final int CHANGE_OBJECT = 0;
  1442. public final int REMOVE_OBJECT = 1;
  1443. ArrayList<AbstractCpsObject> objSpace;
  1444. public boolean editEdges = false;
  1445. public int maxConnections = 0;
  1446. public double edgeMutationProb = 0;
  1447. public HolegMutation(){
  1448. mutationProb = 0.001;
  1449. rng = new Random();
  1450. }
  1451. public HolegMutation(double prob){
  1452. mutationProb = prob;
  1453. }
  1454. public void setMutationProbability(double probability){
  1455. mutationProb = probability;
  1456. }
  1457. public double getMutationProbability(){
  1458. return mutationProb;
  1459. }
  1460. public HolegIndividual mutateIndividual(HolegIndividual mutant) {
  1461. for(Integer wildIdx : mutant.getWildcardIndexes()){
  1462. if(rng.nextDouble() < mutationProb){
  1463. switch(rng.nextInt(2)){
  1464. case CHANGE_OBJECT :
  1465. changeObject(mutant, wildIdx);
  1466. break;
  1467. case REMOVE_OBJECT :
  1468. removeObject(mutant, wildIdx);
  1469. break;
  1470. }
  1471. }
  1472. }
  1473. ArrayList<GAEdge> mutationEdges = new ArrayList<GAEdge>();
  1474. int endIdx = 0;
  1475. boolean isOriginal = false;
  1476. if(editEdges){
  1477. mutationEdges.addAll(mutant.getOriginalEdges());
  1478. endIdx = mutationEdges.size(); //originalEdges müssen zuerst mutieren da sie sonst
  1479. //verworfen werden falls additional Edge gleiche werte bekommt
  1480. mutationEdges.addAll(mutant.getAdditionalEdges());
  1481. }else{
  1482. mutationEdges.addAll(mutant.getAdditionalEdges());
  1483. }
  1484. for(int i = 0; i < mutationEdges.size(); i++){
  1485. if(rng.nextDouble() < edgeMutationProb){
  1486. if(i < endIdx){
  1487. changeSingleEdge(mutant, mutationEdges.get(i), true);
  1488. }else{
  1489. changeSingleEdge(mutant, mutationEdges.get(i), false);
  1490. }
  1491. }
  1492. }
  1493. if(rng.nextDouble() < edgeMutationProb){
  1494. switch(rng.nextInt(2)){
  1495. case ADD_EDGE:
  1496. addEdge(mutant);
  1497. break;
  1498. case REMOVE_EDGE:
  1499. removeEdge(mutant);
  1500. break;
  1501. }
  1502. }
  1503. return mutant;
  1504. }
  1505. public void removeObject(HolegIndividual mutant, int removeIdx) {
  1506. ArrayList<CpsEdge> connections = new ArrayList<CpsEdge>();
  1507. connections.addAll(mutant.getObjectWithIndex(removeIdx).getConnections());
  1508. for(CpsEdge e : connections){
  1509. e.getA().getConnections().remove(e);
  1510. e.getB().getConnections().remove(e);
  1511. }
  1512. ArrayList<GAEdge> edgesToRemove = new ArrayList<GAEdge>();
  1513. for(GAEdge gE : mutant.getAllEdges()){
  1514. if(gE.aPos == removeIdx || gE.bPos == removeIdx){
  1515. edgesToRemove.add(gE);
  1516. }
  1517. }
  1518. mutant.getAllEdges().removeAll(edgesToRemove);
  1519. mutant.addLogEntry("Object wit ID " + mutant.indexToObjectMap.get(removeIdx).getId() + " removed");
  1520. mutant.removeObject(removeIdx);
  1521. }
  1522. public void changeObject(HolegIndividual mutant, int changeIdx) {
  1523. if(objSpace.size() > 0){
  1524. AbstractCpsObject newObj = null;
  1525. AbstractCpsObject absObj = objSpace.get(rng.nextInt(objSpace.size()));
  1526. newObj = absObj.makeCopy();
  1527. AbstractCpsObject oldObject = mutant.getObjectWithIndex(changeIdx);
  1528. for(CpsEdge e : oldObject.getConnections()){
  1529. if(e.getA() == oldObject){
  1530. e.setA(newObj);
  1531. newObj.addConnection(e);
  1532. }else if(e.getB() == oldObject){
  1533. e.setB(newObj);
  1534. newObj.addConnection(e);
  1535. }
  1536. }
  1537. newObj.setId(oldObject.getId());
  1538. newObj.setPosition(oldObject.getPosition());
  1539. mutant.indexToObjectMap.put(changeIdx, newObj);
  1540. mutant.addLogEntry("Object with Id " + newObj.getId() + " changed");
  1541. }
  1542. }
  1543. public void removeEdge(HolegIndividual mutant) {
  1544. ArrayList<GAEdge> edgesSpace = new ArrayList<GAEdge>();
  1545. int spaceEndIdx = 0;
  1546. if(editEdges){
  1547. edgesSpace.addAll(mutant.getAdditionalEdges());
  1548. spaceEndIdx = edgesSpace.size();
  1549. edgesSpace.addAll(mutant.getOriginalEdges());
  1550. }else{
  1551. edgesSpace.addAll(mutant.getAdditionalEdges());
  1552. spaceEndIdx = edgesSpace.size();
  1553. }
  1554. if(edgesSpace.size() > 0){
  1555. int edgeIdx = rng.nextInt(edgesSpace.size());
  1556. CpsEdge toRemove = edgesSpace.get(edgeIdx);
  1557. toRemove.getA().getConnections().remove(toRemove);
  1558. toRemove.getB().getConnections().remove(toRemove);
  1559. if(edgeIdx < spaceEndIdx){
  1560. mutant.getAdditionalEdges().remove(edgeIdx);
  1561. }else{
  1562. mutant.getOriginalEdges().remove(edgeIdx-spaceEndIdx);
  1563. }
  1564. mutant.addLogEntry("Edge (" + toRemove.getA().getId() + ","
  1565. + toRemove.getB().getId() + ") removed");
  1566. }
  1567. }
  1568. public void addEdge(HolegIndividual mutant) {
  1569. if(mutant.getAllEdges().size() < maxConnections){
  1570. if(mutant.getIndexes().size() > 1){
  1571. ArrayList<Integer> list = new ArrayList<Integer>();
  1572. list.addAll(mutant.getIndexes());
  1573. Collections.shuffle(list);
  1574. int aPos = list.get(0);
  1575. int bPos = list.get(1);
  1576. mutant.addEdge(aPos, bPos);
  1577. mutant.addLogEntry("Edge (" + mutant.indexToObjectMap.get(aPos).getId() +
  1578. "," + mutant.indexToObjectMap.get(bPos).getId() + ") added");
  1579. }
  1580. }
  1581. }
  1582. public void changeRandomEdge(HolegIndividual mutant) {
  1583. ArrayList<GAEdge> edgeSpace;
  1584. if(editEdges){
  1585. edgeSpace = mutant.getAllEdges();
  1586. }else{
  1587. edgeSpace = mutant.getAdditionalEdges();
  1588. }
  1589. if(edgeSpace.size() > 0){
  1590. int edgeIdx = rng.nextInt(edgeSpace.size());
  1591. GAEdge toChange = edgeSpace.get(edgeIdx);
  1592. boolean changeA = rng.nextBoolean();
  1593. int randomIndex = rng.nextInt(mutant.getIndexes().size());
  1594. randomIndex = mutant.getIndexes().get(randomIndex);
  1595. if(changeA){
  1596. toChange.getA().getConnections().remove(toChange);
  1597. if(toChange.getB() != mutant.getObjectWithIndex(randomIndex)){
  1598. toChange.setA(mutant.getObjectWithIndex(randomIndex));
  1599. toChange.aPos = randomIndex;
  1600. mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
  1601. }else{
  1602. toChange.getB().getConnections().remove(toChange);
  1603. mutant.getAdditionalEdges().remove(toChange);
  1604. }
  1605. }else{
  1606. toChange.getB().getConnections().remove(toChange);
  1607. if(toChange.getA() != mutant.getObjectWithIndex(randomIndex)){
  1608. toChange.setB(mutant.getObjectWithIndex(randomIndex));
  1609. toChange.bPos = randomIndex;
  1610. mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
  1611. }else{
  1612. toChange.getA().getConnections().remove(toChange);
  1613. mutant.getAdditionalEdges().remove(toChange);
  1614. }
  1615. }
  1616. }
  1617. }
  1618. public void changeSingleEdge(HolegIndividual mutant, GAEdge toChange, boolean isOriginal){
  1619. boolean changeA = rng.nextBoolean();
  1620. int randomIndex = rng.nextInt(mutant.getIndexes().size());
  1621. randomIndex = mutant.getIndexes().get(randomIndex);
  1622. String logString = "Edge (" + toChange.aPos + "," + toChange.bPos +
  1623. ") changed to ";
  1624. if(mutant.getObjectWithIndex(randomIndex) != toChange.getA() &&
  1625. mutant.getObjectWithIndex(randomIndex) != toChange.getB()){
  1626. if(changeA && !mutant.edgeExists(randomIndex, toChange.bPos, mutant.getAllEdges())){
  1627. toChange.getA().getConnections().remove(toChange);
  1628. toChange.setA(mutant.getObjectWithIndex(randomIndex));
  1629. toChange.aPos = randomIndex;
  1630. mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
  1631. }else if(!mutant.edgeExists(randomIndex, toChange.aPos, mutant.getAllEdges())){
  1632. toChange.getB().getConnections().remove(toChange);
  1633. toChange.setB(mutant.getObjectWithIndex(randomIndex));
  1634. toChange.bPos = randomIndex;
  1635. mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
  1636. }
  1637. }
  1638. mutant.addLogEntry(logString + "(" + toChange.aPos + "," + toChange.bPos + ")");
  1639. }
  1640. public void setParameters(ParameterArray params){
  1641. this.edgeMutationProb = (double)params.get(params.EDGE_MUTATION_PROB);
  1642. this.setMutationProbability((double)params.get(params.WILDCARD_MUTATION_PROB));
  1643. this.maxConnections = (int)params.get(params.MAX_EDGES);
  1644. this.editEdges = (boolean)params.get(params.EDIT_EDGES);
  1645. }
  1646. public void setObjectSpace(ArrayList<AbstractCpsObject> space){
  1647. objSpace = space;
  1648. }
  1649. public void setEdgeMutationProb(double prob){
  1650. this.edgeMutationProb = prob;
  1651. }
  1652. }
  1653. }