|
@@ -0,0 +1,1947 @@
|
|
|
+package algorithms;
|
|
|
+
|
|
|
+import java.awt.Dimension;
|
|
|
+import java.awt.Font;
|
|
|
+import java.awt.event.ActionEvent;
|
|
|
+import java.awt.event.ActionListener;
|
|
|
+import java.awt.event.MouseAdapter;
|
|
|
+import java.awt.event.MouseEvent;
|
|
|
+import java.awt.event.MouseListener;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Random;
|
|
|
+import java.util.Set;
|
|
|
+
|
|
|
+import javax.swing.BoxLayout;
|
|
|
+import javax.swing.JButton;
|
|
|
+import javax.swing.JCheckBox;
|
|
|
+import javax.swing.JFrame;
|
|
|
+import javax.swing.JLabel;
|
|
|
+import javax.swing.JPanel;
|
|
|
+import javax.swing.JScrollPane;
|
|
|
+import javax.swing.JSplitPane;
|
|
|
+import javax.swing.JTextArea;
|
|
|
+import javax.swing.JTextField;
|
|
|
+import javax.swing.JTree;
|
|
|
+import javax.swing.tree.DefaultMutableTreeNode;
|
|
|
+import javax.swing.tree.DefaultTreeModel;
|
|
|
+import javax.swing.tree.TreePath;
|
|
|
+
|
|
|
+import classes.AbstractCpsObject;
|
|
|
+import classes.Category;
|
|
|
+import classes.CpsEdge;
|
|
|
+import classes.CpsNode;
|
|
|
+import classes.HolonBattery;
|
|
|
+import classes.HolonObject;
|
|
|
+import classes.HolonSwitch;
|
|
|
+import classes.IdCounter;
|
|
|
+import classes.Position;
|
|
|
+import ui.controller.Control;
|
|
|
+import ui.controller.SimulationManager;
|
|
|
+import ui.model.DecoratedHolonObject.HolonObjectState;
|
|
|
+import ui.model.DecoratedNetwork;
|
|
|
+import ui.model.DecoratedState;
|
|
|
+import ui.model.Model;
|
|
|
+import api.Algorithm;
|
|
|
+
|
|
|
+public class GeneticAlgorithm implements Algorithm {
|
|
|
+ Control controller;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public JPanel getAlgorithmPanel() {
|
|
|
+ GenAlgoWindow panel = new GenAlgoWindow(controller, controller.getModel());
|
|
|
+ return panel.frame;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void setController(Control control) {
|
|
|
+ controller = control;
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * The Window of the Algorithm
|
|
|
+ */
|
|
|
+ public class GenAlgoWindow {
|
|
|
+ JPanel frame;
|
|
|
+ Control controller;
|
|
|
+ Model model;
|
|
|
+ JTree genTree;
|
|
|
+ DefaultTreeModel treeModel;
|
|
|
+ DefaultMutableTreeNode treeRoot;
|
|
|
+ HashMap<DefaultMutableTreeNode, HolegIndividual> treeIndiHashmap;
|
|
|
+ GenAlgoHandler algoHandler;
|
|
|
+ ArrayList<DefaultMutableTreeNode> generationNodes = new ArrayList<DefaultMutableTreeNode>();
|
|
|
+ private JTextField edgeAmountField;
|
|
|
+ private JCheckBox chckbxEditEdges;
|
|
|
+ private JTextArea logArea;
|
|
|
+ private JTextField popSizeField;
|
|
|
+ private JTextField tournamentSizeField;
|
|
|
+ private JTextField edgeBreakCount;
|
|
|
+ private JTextField iterationsField;
|
|
|
+ ParameterArray params = new ParameterArray();
|
|
|
+ private JTextField edgeMutationField;
|
|
|
+ private JTextField suppliedField;
|
|
|
+ private JTextField oversuppliedField;
|
|
|
+ private JTextField undersuppliedField;
|
|
|
+ private JTextField edgeLengthField;
|
|
|
+ private JTextField wildcardUsageField;
|
|
|
+ private JTextField wildcardMutationField;
|
|
|
+ private JTextField partialSuppliedField;
|
|
|
+ private JTextField overproductionField;
|
|
|
+ private JTextField generationAmountField;
|
|
|
+ private JCheckBox chckbxWildNodes;
|
|
|
+ ArrayList<HolegGeneration> generationHistory = new ArrayList<HolegGeneration>();
|
|
|
+ /**
|
|
|
+ * Create the application.
|
|
|
+ */
|
|
|
+ public GenAlgoWindow(Control controller, Model model) {
|
|
|
+ this.model = model;
|
|
|
+ this.controller = controller;
|
|
|
+ algoHandler = new GenAlgoHandler(controller, model);
|
|
|
+ algoHandler.addListener(this);
|
|
|
+ treeIndiHashmap = new HashMap<DefaultMutableTreeNode, HolegIndividual>();
|
|
|
+ initialize();
|
|
|
+ algoHandler.setOriginalNetwork();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Initialize the contents of the frame.
|
|
|
+ */
|
|
|
+ private void initialize() {
|
|
|
+ frame = new JPanel();
|
|
|
+ //frame.setBounds(100, 100, 500, 500);
|
|
|
+ frame.setPreferredSize(new Dimension(500, 500));
|
|
|
+ frame.setLayout(new BoxLayout(frame, BoxLayout.X_AXIS));
|
|
|
+
|
|
|
+
|
|
|
+ JSplitPane mainSplitPane = new JSplitPane();
|
|
|
+ mainSplitPane.setResizeWeight(0.3);
|
|
|
+ frame.add(mainSplitPane);
|
|
|
+
|
|
|
+ JScrollPane treeScrollPane = new JScrollPane();
|
|
|
+ mainSplitPane.setLeftComponent(treeScrollPane);
|
|
|
+
|
|
|
+ genTree = new JTree();
|
|
|
+ treeScrollPane.setViewportView(genTree);
|
|
|
+
|
|
|
+ treeModel = (DefaultTreeModel) genTree.getModel();
|
|
|
+ treeRoot = new DefaultMutableTreeNode("Generations");
|
|
|
+ treeModel.setRoot(treeRoot);
|
|
|
+ genTree.setModel(treeModel);
|
|
|
+
|
|
|
+ JSplitPane rightSplitPane = new JSplitPane();
|
|
|
+ rightSplitPane.setResizeWeight(0.7);
|
|
|
+ rightSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
|
|
|
+ mainSplitPane.setRightComponent(rightSplitPane);
|
|
|
+
|
|
|
+ JPanel parameterPanel = new JPanel();
|
|
|
+ parameterPanel.setPreferredSize(new Dimension(100, 650));
|
|
|
+ JScrollPane parameterScrollView = new JScrollPane();
|
|
|
+ rightSplitPane.setLeftComponent(parameterScrollView);
|
|
|
+ parameterScrollView.setViewportView(parameterPanel);
|
|
|
+
|
|
|
+
|
|
|
+ JButton btnCreategeneration = new JButton("create N Generations");
|
|
|
+ btnCreategeneration.setBounds(10, 11, 137, 23);
|
|
|
+ btnCreategeneration.addActionListener(new ActionListener() {
|
|
|
+ public void actionPerformed(ActionEvent arg0) {
|
|
|
+ setParameters();
|
|
|
+ algoHandler.createGeneration(Integer.parseInt(generationAmountField.getText()), params);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ parameterPanel.setLayout(null);
|
|
|
+ parameterPanel.add(btnCreategeneration);
|
|
|
+
|
|
|
+ edgeAmountField = new JTextField();
|
|
|
+ edgeAmountField.setText("0");
|
|
|
+ edgeAmountField.setBounds(147, 119, 86, 20);
|
|
|
+ parameterPanel.add(edgeAmountField);
|
|
|
+ edgeAmountField.setColumns(10);
|
|
|
+
|
|
|
+ JLabel lblMaxEdges = new JLabel("Max Edges");
|
|
|
+ lblMaxEdges.setBounds(10, 122, 91, 14);
|
|
|
+ parameterPanel.add(lblMaxEdges);
|
|
|
+
|
|
|
+ chckbxEditEdges = new JCheckBox("\r\n");
|
|
|
+ chckbxEditEdges.setBounds(147, 92, 25, 23);
|
|
|
+ parameterPanel.add(chckbxEditEdges);
|
|
|
+
|
|
|
+ JLabel lblEditEdges = new JLabel("Edit Edges?");
|
|
|
+ lblEditEdges.setBounds(10, 96, 91, 14);
|
|
|
+ parameterPanel.add(lblEditEdges);
|
|
|
+
|
|
|
+ popSizeField = new JTextField();
|
|
|
+ popSizeField.setText("100");
|
|
|
+ popSizeField.setBounds(147, 45, 86, 20);
|
|
|
+ parameterPanel.add(popSizeField);
|
|
|
+ popSizeField.setColumns(10);
|
|
|
+
|
|
|
+ tournamentSizeField = new JTextField();
|
|
|
+ tournamentSizeField.setText("30");
|
|
|
+ tournamentSizeField.setBounds(147, 70, 86, 20);
|
|
|
+ parameterPanel.add(tournamentSizeField);
|
|
|
+ tournamentSizeField.setColumns(10);
|
|
|
+
|
|
|
+ JLabel lblPopulationSize = new JLabel("Population Size");
|
|
|
+ lblPopulationSize.setBounds(10, 45, 91, 14);
|
|
|
+ parameterPanel.add(lblPopulationSize);
|
|
|
+
|
|
|
+ JLabel lblTournamentSize = new JLabel("Tournament Size");
|
|
|
+ lblTournamentSize.setBounds(10, 73, 91, 14);
|
|
|
+ parameterPanel.add(lblTournamentSize);
|
|
|
+
|
|
|
+ edgeBreakCount = new JTextField();
|
|
|
+ edgeBreakCount.setText("0");
|
|
|
+ edgeBreakCount.setBounds(147, 144, 86, 20);
|
|
|
+ parameterPanel.add(edgeBreakCount);
|
|
|
+ edgeBreakCount.setColumns(10);
|
|
|
+
|
|
|
+ JLabel lblEdgeBreakProb = new JLabel("Edge Break Amount");
|
|
|
+ lblEdgeBreakProb.setBounds(10, 147, 117, 14);
|
|
|
+ parameterPanel.add(lblEdgeBreakProb);
|
|
|
+
|
|
|
+ iterationsField = new JTextField();
|
|
|
+ iterationsField.setText("1");
|
|
|
+ iterationsField.setBounds(147, 169, 86, 20);
|
|
|
+ parameterPanel.add(iterationsField);
|
|
|
+ iterationsField.setColumns(10);
|
|
|
+
|
|
|
+ JLabel lblSimIteration = new JLabel("Sim Iterations");
|
|
|
+ lblSimIteration.setBounds(10, 172, 91, 14);
|
|
|
+ parameterPanel.add(lblSimIteration);
|
|
|
+
|
|
|
+ edgeMutationField = new JTextField();
|
|
|
+ edgeMutationField.setText("0.01");
|
|
|
+ edgeMutationField.setBounds(147, 194, 86, 20);
|
|
|
+ parameterPanel.add(edgeMutationField);
|
|
|
+ edgeMutationField.setColumns(10);
|
|
|
+
|
|
|
+ JLabel lblMutationProb = new JLabel("Edge Mutation Prob");
|
|
|
+ lblMutationProb.setBounds(10, 197, 117, 14);
|
|
|
+ parameterPanel.add(lblMutationProb);
|
|
|
+
|
|
|
+ suppliedField = new JTextField();
|
|
|
+ suppliedField.setText("+10.0");
|
|
|
+ suppliedField.setBounds(147, 297, 86, 20);
|
|
|
+ parameterPanel.add(suppliedField);
|
|
|
+ suppliedField.setColumns(10);
|
|
|
+
|
|
|
+ JLabel lblFittnesspointsPerAttribute = new JLabel("Fittnesspoints per Attribute:");
|
|
|
+ lblFittnesspointsPerAttribute.setFont(new Font("Tahoma", Font.PLAIN, 12));
|
|
|
+ lblFittnesspointsPerAttribute.setBounds(59, 275, 157, 14);
|
|
|
+ parameterPanel.add(lblFittnesspointsPerAttribute);
|
|
|
+
|
|
|
+ JLabel lblSuppliedEntity = new JLabel("each supplied Entity");
|
|
|
+ lblSuppliedEntity.setBounds(10, 300, 117, 14);
|
|
|
+ parameterPanel.add(lblSuppliedEntity);
|
|
|
+
|
|
|
+ oversuppliedField = new JTextField();
|
|
|
+ oversuppliedField.setText("+10.0");
|
|
|
+ oversuppliedField.setBounds(147, 322, 86, 20);
|
|
|
+ parameterPanel.add(oversuppliedField);
|
|
|
+ oversuppliedField.setColumns(10);
|
|
|
+
|
|
|
+ JLabel lblOversuppliedEntity = new JLabel("each oversupplied Entity");
|
|
|
+ lblOversuppliedEntity.setBounds(10, 325, 127, 14);
|
|
|
+ parameterPanel.add(lblOversuppliedEntity);
|
|
|
+
|
|
|
+ undersuppliedField = new JTextField();
|
|
|
+ undersuppliedField.setText("-10.0");
|
|
|
+ undersuppliedField.setBounds(147, 347, 86, 20);
|
|
|
+ parameterPanel.add(undersuppliedField);
|
|
|
+ undersuppliedField.setColumns(10);
|
|
|
+
|
|
|
+ JLabel lblEachUndersuppliedEntity = new JLabel("each undersupplied Entity");
|
|
|
+ lblEachUndersuppliedEntity.setBounds(10, 350, 127, 14);
|
|
|
+ parameterPanel.add(lblEachUndersuppliedEntity);
|
|
|
+
|
|
|
+ edgeLengthField = new JTextField();
|
|
|
+ edgeLengthField.setText("-1.0");
|
|
|
+ edgeLengthField.setBounds(147, 397, 86, 20);
|
|
|
+ parameterPanel.add(edgeLengthField);
|
|
|
+ edgeLengthField.setColumns(10);
|
|
|
+
|
|
|
+ JLabel lblForEdge = new JLabel("for 100 edge length");
|
|
|
+ lblForEdge.setBounds(10, 400, 127, 14);
|
|
|
+ parameterPanel.add(lblForEdge);
|
|
|
+
|
|
|
+ wildcardUsageField = new JTextField();
|
|
|
+ wildcardUsageField.setText("-7.0");
|
|
|
+ wildcardUsageField.setBounds(147, 422, 86, 20);
|
|
|
+ parameterPanel.add(wildcardUsageField);
|
|
|
+ wildcardUsageField.setColumns(10);
|
|
|
+
|
|
|
+ JLabel lblWildcardUsage = new JLabel("each Wildcard usage");
|
|
|
+ lblWildcardUsage.setBounds(10, 425, 127, 14);
|
|
|
+ parameterPanel.add(lblWildcardUsage);
|
|
|
+
|
|
|
+ JLabel lblWildcardMutation = new JLabel("Wildcard Mutation Prob");
|
|
|
+ lblWildcardMutation.setBounds(10, 222, 117, 14);
|
|
|
+ parameterPanel.add(lblWildcardMutation);
|
|
|
+
|
|
|
+ wildcardMutationField = new JTextField();
|
|
|
+ wildcardMutationField.setText("0.01");
|
|
|
+ wildcardMutationField.setBounds(147, 219, 86, 20);
|
|
|
+ parameterPanel.add(wildcardMutationField);
|
|
|
+ wildcardMutationField.setColumns(10);
|
|
|
+
|
|
|
+ JLabel lblEachPartiallySupplied = new JLabel("each partialsupplied Entity");
|
|
|
+ lblEachPartiallySupplied.setBounds(10, 375, 137, 14);
|
|
|
+ parameterPanel.add(lblEachPartiallySupplied);
|
|
|
+
|
|
|
+ partialSuppliedField = new JTextField();
|
|
|
+ partialSuppliedField.setText("-2.0");
|
|
|
+ partialSuppliedField.setBounds(147, 372, 86, 20);
|
|
|
+ parameterPanel.add(partialSuppliedField);
|
|
|
+ partialSuppliedField.setColumns(10);
|
|
|
+
|
|
|
+ JLabel lblForOverproduction = new JLabel("for 1000 overproduction");
|
|
|
+ lblForOverproduction.setBounds(10, 450, 117, 14);
|
|
|
+ parameterPanel.add(lblForOverproduction);
|
|
|
+
|
|
|
+ overproductionField = new JTextField();
|
|
|
+ overproductionField.setText("-5.0");
|
|
|
+ overproductionField.setBounds(147, 447, 86, 20);
|
|
|
+ parameterPanel.add(overproductionField);
|
|
|
+ overproductionField.setColumns(10);
|
|
|
+
|
|
|
+ generationAmountField = new JTextField();
|
|
|
+ generationAmountField.setText("1");
|
|
|
+ generationAmountField.setBounds(147, 12, 86, 20);
|
|
|
+ parameterPanel.add(generationAmountField);
|
|
|
+ generationAmountField.setColumns(10);
|
|
|
+
|
|
|
+ JLabel lblNodesInWildcards = new JLabel("Nodes in Wildcards?");
|
|
|
+ lblNodesInWildcards.setBounds(10, 247, 117, 14);
|
|
|
+ parameterPanel.add(lblNodesInWildcards);
|
|
|
+
|
|
|
+ chckbxWildNodes = new JCheckBox("");
|
|
|
+ chckbxWildNodes.setBounds(147, 245, 97, 20);
|
|
|
+ parameterPanel.add(chckbxWildNodes);
|
|
|
+
|
|
|
+ logArea = new JTextArea();
|
|
|
+ rightSplitPane.setRightComponent(logArea);
|
|
|
+
|
|
|
+ MouseListener ml = new MouseAdapter() {
|
|
|
+ public void mousePressed(MouseEvent e) {
|
|
|
+ int selRow = genTree.getRowForLocation(e.getX(), e.getY());
|
|
|
+ TreePath selPath = genTree.getPathForLocation(e.getX(), e.getY());
|
|
|
+ if(selRow != -1) {
|
|
|
+ if(e.getClickCount() == 1) {
|
|
|
+ nodeSingleClick(selRow, selPath);
|
|
|
+ }
|
|
|
+ else if(e.getClickCount() == 2) {
|
|
|
+ nodeDoubleClick(selRow, selPath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ genTree.addMouseListener(ml);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void nodeSingleClick(int selRow, TreePath selPath){
|
|
|
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode)selPath.getLastPathComponent();
|
|
|
+
|
|
|
+ if(node.getUserObject() instanceof HolegGeneration){
|
|
|
+ logArea.setText(((HolegGeneration)node.getUserObject()).getInformation());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void nodeDoubleClick(int selRow, TreePath selPath){
|
|
|
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode)selPath.getLastPathComponent();
|
|
|
+
|
|
|
+
|
|
|
+ if(treeIndiHashmap.get(node) != null){
|
|
|
+ algoHandler.drawIndividualWithPos(treeIndiHashmap.get(node));
|
|
|
+ logArea.setText(treeIndiHashmap.get(node).log);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public void populationCreated(HolegGeneration holegGen) {
|
|
|
+ DefaultMutableTreeNode genNode = new DefaultMutableTreeNode(holegGen);
|
|
|
+ generationHistory.add(holegGen);
|
|
|
+ ArrayList<HolegIndividual> population = holegGen.getGeneration();
|
|
|
+ for(int i = 0; i < population.size(); i++){
|
|
|
+ DefaultMutableTreeNode child = new DefaultMutableTreeNode("Individual " + i);
|
|
|
+ population.get(i).setId(holegGen.getGenCount(), i);
|
|
|
+ treeIndiHashmap.put(child, population.get(i));
|
|
|
+ genNode.add(child);
|
|
|
+ }
|
|
|
+ generationNodes.add(genNode);
|
|
|
+ treeRoot.insert(genNode, 0);
|
|
|
+ treeModel.reload();
|
|
|
+ if(holegGen.getGenCount() == HolegGeneration.ORIGINAL_GEN){
|
|
|
+ int nodeAmount = holegGen.getGeneration().get(0).getIndexes().size();
|
|
|
+ int maxEdges = (nodeAmount*(nodeAmount-1))/2;
|
|
|
+ edgeAmountField.setText(Integer.toString(maxEdges));
|
|
|
+
|
|
|
+ params.set(params.ORIGINAL_NETWORK, holegGen.getGeneration().get(0));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * sets All Parameters from the Textfields into the ParameterArray;
|
|
|
+ */
|
|
|
+ public void setParameters(){
|
|
|
+ params.set(params.MAX_EDGES, Integer.parseInt(edgeAmountField.getText()));
|
|
|
+ params.set(params.EDIT_EDGES, chckbxEditEdges.isSelected());
|
|
|
+ params.set(params.POPULATION_SIZE, Integer.parseInt(popSizeField.getText()));
|
|
|
+ params.set(params.TOURNAMENT_SIZE, Integer.parseInt(tournamentSizeField.getText()));
|
|
|
+ params.set(params.EDGE_BREAK_AMOUNT, Integer.parseInt(edgeBreakCount.getText()));
|
|
|
+ params.set(params.SIM_ITERATIONS, Integer.parseInt(iterationsField.getText()));
|
|
|
+ params.set(params.EDGE_MUTATION_PROB, Double.parseDouble(edgeMutationField.getText()));
|
|
|
+ params.set(params.SUPPLIED_POINTS, Double.parseDouble(suppliedField.getText()));
|
|
|
+ params.set(params.OVERSUPPLIED_POINTS, Double.parseDouble(oversuppliedField.getText()));
|
|
|
+ params.set(params.UNDERSUPPLIED_POINTS, Double.parseDouble(undersuppliedField.getText()));
|
|
|
+ params.set(params.LENGTH_POINTS, Double.parseDouble(edgeLengthField.getText()));
|
|
|
+ params.set(params.WILDCARD_USAGE, Double.parseDouble(wildcardUsageField.getText()));
|
|
|
+ params.set(params.WILDCARD_MUTATION_PROB, Double.parseDouble(wildcardMutationField.getText()));
|
|
|
+ params.set(params.PARTIALSUPPLIED_POINTS, Double.parseDouble(partialSuppliedField.getText()));
|
|
|
+ params.set(params.OVERPRODUCTION, Double.parseDouble(overproductionField.getText()));
|
|
|
+ params.set(params.NODES_IN_WILDCARDS, chckbxWildNodes.isSelected());
|
|
|
+ params.set(params.TOURNAMENT_PROB, 0.15);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * This class is Kind of the controller class. It calls the algorithm methods
|
|
|
+ * and assures the results are transported to the GenAlogWindow
|
|
|
+ */
|
|
|
+ public class GenAlgoHandler{
|
|
|
+ ArrayList<GenAlgoWindow> listeners = new ArrayList<GenAlgoWindow>();
|
|
|
+ HolegFactory factory;
|
|
|
+ Control controller;
|
|
|
+ Model model;
|
|
|
+ int genCount;
|
|
|
+
|
|
|
+ GeneticAlgo holegGA;
|
|
|
+ TournamentSelection<HolegIndividual> tRS;
|
|
|
+ HolegFittnessScenario hF;
|
|
|
+ HolegMutation hM;
|
|
|
+ HolegCrossover hC;
|
|
|
+ ArrayList<AbstractCpsObject> objSpace;
|
|
|
+ CpsNode theNode = new CpsNode("Node");
|
|
|
+
|
|
|
+ public GenAlgoHandler(Control controller, Model model){
|
|
|
+ this.controller = controller;
|
|
|
+ this.model = model;
|
|
|
+ genCount = 1;
|
|
|
+ objSpace = new ArrayList<AbstractCpsObject>();
|
|
|
+ for(Category cat : model.getCategories()){
|
|
|
+ for(AbstractCpsObject obj : cat.getObjects()){
|
|
|
+ if(!(obj instanceof HolonWildCard) /* && obj.useForGA */){
|
|
|
+ objSpace.add(obj);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ArrayList<AbstractCpsObject> origin = model.getObjectsOnCanvas();
|
|
|
+ ArrayList<CpsEdge> edges = model.getEdgesOnCanvas();
|
|
|
+ factory = new HolegFactory(objSpace, 0, 0);
|
|
|
+ factory.originalObjects = origin;
|
|
|
+ factory.originalEdges = edges;
|
|
|
+
|
|
|
+ hC = new HolegCrossover();
|
|
|
+ hF = new HolegFittnessScenario(controller);
|
|
|
+ hM = new HolegMutation(0.01);
|
|
|
+ hM.setObjectSpace(objSpace);
|
|
|
+ tRS = new TournamentSelection<HolegIndividual>();
|
|
|
+ holegGA = new GeneticAlgo(tRS, hC, hM, hF, factory, 0);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void createGeneration(int genAmount, ParameterArray params){
|
|
|
+ //setting the parameters of the algo components
|
|
|
+ factory.maxConnections = (int)params.get(params.MAX_EDGES);
|
|
|
+ factory.editEdges = (boolean)params.get(params.EDIT_EDGES);
|
|
|
+ holegGA.popSize = (int)params.get(params.POPULATION_SIZE);
|
|
|
+ tRS.tournamentSize = (int)params.get(params.TOURNAMENT_SIZE);
|
|
|
+ tRS.selectProb = (double)params.get(params.TOURNAMENT_PROB);
|
|
|
+ hF.setParameters(params);
|
|
|
+
|
|
|
+
|
|
|
+ if((boolean)params.get(params.NODES_IN_WILDCARDS)){
|
|
|
+ if(!objSpace.contains(theNode)){
|
|
|
+ objSpace.add(theNode);
|
|
|
+ }else{
|
|
|
+ objSpace.remove(theNode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ hM.setParameters(params);
|
|
|
+ for(int i = 0; i < genAmount; i++){
|
|
|
+ hF.initialize();
|
|
|
+ if(genCount == 1){
|
|
|
+ holegGA.generateRandomPopulation();
|
|
|
+ HolegGeneration holegGen = new HolegGeneration(genCount);
|
|
|
+ holegGen.setGeneration(holegGA.getSortedPopulation());
|
|
|
+ addGenToPopulationListeners(holegGen);
|
|
|
+ }else{
|
|
|
+ holegGA.createNextGeneration();
|
|
|
+ HolegGeneration holegGen = new HolegGeneration(genCount);
|
|
|
+ holegGen.setGeneration(holegGA.getSortedPopulation());
|
|
|
+ addGenToPopulationListeners(holegGen);
|
|
|
+ }
|
|
|
+ genCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void drawIndividualWithPos(HolegIndividual hI){
|
|
|
+ model.setObjectsOnCanvas(new ArrayList<AbstractCpsObject>());
|
|
|
+ model.setEdgesOnCanvas(new ArrayList<CpsEdge>());
|
|
|
+
|
|
|
+ hI.configurateNetwork();
|
|
|
+ for(int i = 0; i < hI.getIndexes().size(); i++){
|
|
|
+ controller.addObjectCanvas(hI.getObjectAt(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ for(GAEdge e : hI.getAllEdges()){
|
|
|
+ controller.addEdgeOnCanvas(e);
|
|
|
+ }
|
|
|
+ controller.calculateStateForCurrentTimeStep();
|
|
|
+ controller.updateCanvas();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addListener(GenAlgoWindow listener){
|
|
|
+ listeners.add(listener);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addGenToPopulationListeners(HolegGeneration holegGen){
|
|
|
+ for(GenAlgoWindow listener : listeners){
|
|
|
+ listener.populationCreated(holegGen);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<HolegIndividual> sortPopulation(ArrayList<HolegIndividual> individuals){
|
|
|
+ ArrayList<HolegIndividual> sortedList = new ArrayList<HolegIndividual>();
|
|
|
+ for(HolegIndividual hI : individuals){
|
|
|
+ for(int i = 0; i <= sortedList.size(); i++){
|
|
|
+ if(i == sortedList.size()){
|
|
|
+ sortedList.add(hI);
|
|
|
+ break;
|
|
|
+ }else if(sortedList.get(i).getFittness() < hI.getFittness()){
|
|
|
+ sortedList.add(i, hI);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return sortedList;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setOriginalNetwork(){
|
|
|
+ HolegIndividual originIndividual = new HolegIndividual(model.getObjectsOnCanvas(),
|
|
|
+ model.getEdgesOnCanvas());
|
|
|
+
|
|
|
+
|
|
|
+ HolegGeneration originalGen = new HolegGeneration(HolegGeneration.ORIGINAL_GEN);
|
|
|
+ hF.calculateFittness(originIndividual);
|
|
|
+ ArrayList<HolegIndividual> population = new ArrayList<HolegIndividual>();
|
|
|
+ population.add(originIndividual);
|
|
|
+ originalGen.setGeneration(population);
|
|
|
+ addGenToPopulationListeners(originalGen);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class HolegIndividual{
|
|
|
+
|
|
|
+ public ArrayList<CpsEdge> brokenEdges = new ArrayList<CpsEdge>();
|
|
|
+ public ArrayList<GAEdge> additionalEdges = new ArrayList<GAEdge>();
|
|
|
+ public ArrayList<GAEdge> originEdges = new ArrayList<GAEdge>();
|
|
|
+ public ArrayList<Integer> indexes = new ArrayList<Integer>();
|
|
|
+ public ArrayList<Integer> originIndexes = new ArrayList<Integer>();
|
|
|
+ public ArrayList<Integer> wildCardIndexes = new ArrayList<Integer>();
|
|
|
+ public ArrayList<HolegIndividual> parents = new ArrayList<HolegIndividual>();
|
|
|
+ public HashMap<Integer, AbstractCpsObject> indexToObjectMap = new HashMap<Integer, AbstractCpsObject>();
|
|
|
+ private HashMap<AbstractCpsObject, Integer> objectToIndexMap = new HashMap<AbstractCpsObject, Integer>();
|
|
|
+ public boolean drawn;
|
|
|
+ public String id;
|
|
|
+ public String log;
|
|
|
+ public String backupLog = "Individual Log";
|
|
|
+ public int gen;
|
|
|
+ public int pos;
|
|
|
+ private int lastIndex;
|
|
|
+ public double totalEdgeLength;
|
|
|
+
|
|
|
+ public double fittness;
|
|
|
+
|
|
|
+ public HolegIndividual(ArrayList<AbstractCpsObject> originObjects,
|
|
|
+ ArrayList<CpsEdge> originalEdges){
|
|
|
+
|
|
|
+ lastIndex = 0;
|
|
|
+ log = "Individual Log";
|
|
|
+ drawn = false;
|
|
|
+
|
|
|
+ for(AbstractCpsObject abs : originObjects){
|
|
|
+
|
|
|
+ AbstractCpsObject newObj = abs.makeCopy();
|
|
|
+ newObj.setPosition(abs.getPosition());
|
|
|
+ newObj.setId(abs.getId());
|
|
|
+ addObject(newObj);
|
|
|
+ originIndexes.add(objectToIndexMap.get(newObj));
|
|
|
+ if(newObj instanceof HolonWildCard){
|
|
|
+ wildCardIndexes.add(objectToIndexMap.get(newObj));
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if(originalEdges != null){
|
|
|
+ for(CpsEdge e : originalEdges){
|
|
|
+ addOriginalEdge(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public HolegIndividual(HolegIndividual indi){
|
|
|
+ additionalEdges = new ArrayList<GAEdge>();
|
|
|
+ additionalEdges.addAll(indi.getAdditionalEdges());
|
|
|
+ originEdges = new ArrayList<GAEdge>();
|
|
|
+ originEdges.addAll(indi.originEdges);
|
|
|
+ indexes = new ArrayList<Integer>();
|
|
|
+ indexes.addAll(indi.getIndexes());
|
|
|
+ originIndexes = new ArrayList<Integer>();
|
|
|
+ originIndexes.addAll(indi.originIndexes);
|
|
|
+ parents = new ArrayList<HolegIndividual>();
|
|
|
+
|
|
|
+ indexToObjectMap = new HashMap<Integer, AbstractCpsObject>();
|
|
|
+ objectToIndexMap = new HashMap<AbstractCpsObject, Integer>();
|
|
|
+ Set<Integer> keys = indi.indexToObjectMap.keySet();
|
|
|
+ for(Integer i : keys){
|
|
|
+ indexToObjectMap.put(i, indi.indexToObjectMap.get(i));
|
|
|
+ objectToIndexMap.put(indi.indexToObjectMap.get(i), i);
|
|
|
+ }
|
|
|
+
|
|
|
+ lastIndex = indi.lastIndex;
|
|
|
+ log = "Individual Log";
|
|
|
+ drawn = false;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public double getFittness(){
|
|
|
+ return fittness;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setFittness(double fittness){
|
|
|
+ this.fittness = fittness;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<HolegIndividual> getParents(){
|
|
|
+ return parents;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setParents(ArrayList<HolegIndividual> parents){
|
|
|
+ this.parents = parents;
|
|
|
+ for(int i = 0; i < parents.size(); i++){
|
|
|
+ addLogEntry("Parent" + i + ": " + parents.get(i).getId());
|
|
|
+ }
|
|
|
+ backupLog = log;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setId(int Gen, int pos){
|
|
|
+ if(Gen > 0){
|
|
|
+ id = "Generation_" + Gen + " Rank_" + pos;
|
|
|
+ }else{
|
|
|
+ id = "Generation_Original";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getId(){
|
|
|
+ return id;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<AbstractCpsObject> getObjects(){
|
|
|
+ ArrayList<AbstractCpsObject> objects = new ArrayList<AbstractCpsObject>();
|
|
|
+ for(Integer i : indexes){
|
|
|
+ objects.add(indexToObjectMap.get(i));
|
|
|
+ }
|
|
|
+ return objects;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<AbstractCpsObject> getOriginObjects(){
|
|
|
+ ArrayList<AbstractCpsObject> originObjects = new ArrayList<AbstractCpsObject>();
|
|
|
+ for(Integer i : originIndexes){
|
|
|
+ originObjects.add(indexToObjectMap.get(i));
|
|
|
+ }
|
|
|
+ return originObjects;
|
|
|
+ }
|
|
|
+
|
|
|
+ public AbstractCpsObject getObjectWithIndex(int index){
|
|
|
+ return indexToObjectMap.get(index);
|
|
|
+ }
|
|
|
+
|
|
|
+ public AbstractCpsObject getObjectAt(int position){
|
|
|
+ return indexToObjectMap.get(indexes.get(position));
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<Integer> getIndexes(){
|
|
|
+ return indexes;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<Integer> getWildcardIndexes(){
|
|
|
+ return wildCardIndexes;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<GAEdge> getAdditionalEdges(){
|
|
|
+ return additionalEdges;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<GAEdge> getOriginalEdges(){
|
|
|
+ return originEdges;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<GAEdge> getAllEdges(){
|
|
|
+ ArrayList<GAEdge> allEdges = new ArrayList<GAEdge>();
|
|
|
+ allEdges.addAll(additionalEdges);
|
|
|
+ allEdges.addAll(originEdges);
|
|
|
+ return allEdges;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addObject(AbstractCpsObject obj){
|
|
|
+ addObjectWithIdx(obj, obj.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addObjectWithIdx(AbstractCpsObject obj, int index){
|
|
|
+ if(!indexToObjectMap.containsKey(index)){
|
|
|
+ addIndex(index);
|
|
|
+ indexToObjectMap.put(index, obj);
|
|
|
+ objectToIndexMap.put(obj, index);
|
|
|
+ }else{
|
|
|
+ objectToIndexMap.remove(indexToObjectMap.get(index));
|
|
|
+ indexToObjectMap.put(index, obj);
|
|
|
+ objectToIndexMap.put(obj, index);
|
|
|
+ }
|
|
|
+ //indexToObjectMap.put(index, obj);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void removeObject(int index){
|
|
|
+ AbstractCpsObject toRemove = indexToObjectMap.get(index);
|
|
|
+ HolonWildCard fill = new HolonWildCard("WildCard");
|
|
|
+ fill.setId(toRemove.getId());
|
|
|
+ fill.setPosition(toRemove.getPosition());
|
|
|
+ indexToObjectMap.put(index, fill);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addIndex(int index){
|
|
|
+ for(int i = 0; i < indexes.size(); i++){
|
|
|
+ if(index < indexes.get(i)){
|
|
|
+ indexes.add(i, index);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ indexes.add(index);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * posA and posB are the indexes of the Endpoints A and B in the list of Objects
|
|
|
+ */
|
|
|
+
|
|
|
+
|
|
|
+ public void addEdge(int indexA, int indexB){
|
|
|
+ if(!edgeExists(indexA, indexB, getAllEdges())){
|
|
|
+
|
|
|
+ if(!indexToObjectMap.containsKey(indexA)){
|
|
|
+ CpsNode newObjA = new CpsNode("Node");
|
|
|
+ addObjectWithIdx(newObjA, indexA);
|
|
|
+ }
|
|
|
+ if(!indexToObjectMap.containsKey(indexB)){
|
|
|
+ CpsNode newObjB = new CpsNode("Node");
|
|
|
+ addObjectWithIdx(newObjB, indexB);
|
|
|
+ }
|
|
|
+ additionalEdges.add(new GAEdge(indexA, indexB, indexToObjectMap.get(indexA), indexToObjectMap.get(indexB)));
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addOriginalEdge(CpsEdge e){
|
|
|
+ if(indexToObjectMap.containsKey(e.getA().getId()) && indexToObjectMap.containsKey(e.getB().getId())){
|
|
|
+ GAEdge realEdge = new GAEdge(e.getA().getId(), e.getB().getId(),
|
|
|
+ indexToObjectMap.get(e.getA().getId()), indexToObjectMap.get(e.getB().getId()));
|
|
|
+
|
|
|
+ if(!edgeExists(realEdge.aPos, realEdge.bPos, originEdges)){
|
|
|
+ originEdges.add(realEdge);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addOriginalEdge(GAEdge e){
|
|
|
+ if(!edgeExists(e.aPos, e.bPos, originEdges)){
|
|
|
+ originEdges.add(new GAEdge(e.aPos, e.bPos, indexToObjectMap.get(e.aPos),
|
|
|
+ indexToObjectMap.get(e.bPos)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean edgeExists(int indexA, int indexB, ArrayList<GAEdge> edges){
|
|
|
+ for(GAEdge e : edges){
|
|
|
+ if((e.aPos == indexA && e.bPos == indexB) || (e.bPos == indexA && e.aPos == indexB)){
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addLogEntry(String entry){
|
|
|
+ log += "\n" + entry;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void resetLog(){
|
|
|
+ log = backupLog;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getAvailableIndex(){
|
|
|
+ for(int i = 0; i <= indexes.size(); i++){
|
|
|
+ if(!indexes.contains(i)){
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void configurateNetwork(){
|
|
|
+ //hier womöglich vorher alle edges von allen Knoten entfernen
|
|
|
+ for(GAEdge e : getAllEdges()){
|
|
|
+ e.setA(indexToObjectMap.get(e.aPos));
|
|
|
+ e.setB(indexToObjectMap.get(e.bPos));
|
|
|
+ e.revalidateConnection();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setEdgeLength(double doubleValue) {
|
|
|
+ totalEdgeLength = doubleValue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class HolegGeneration{
|
|
|
+ public static final int ORIGINAL_GEN = -1;
|
|
|
+
|
|
|
+ ArrayList<HolegIndividual> generation;
|
|
|
+ int genCount;
|
|
|
+ String name;
|
|
|
+ String log;
|
|
|
+
|
|
|
+ public HolegGeneration(int genCount){
|
|
|
+ this.genCount = genCount;
|
|
|
+ generation = new ArrayList<HolegIndividual>();
|
|
|
+ if(genCount >= 0){
|
|
|
+ name = "Generation " + genCount;
|
|
|
+ }else{
|
|
|
+ name = "Original Network";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public void setGeneration(ArrayList<HolegIndividual> generation){
|
|
|
+ this.generation = generation;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<HolegIndividual> getGeneration(){
|
|
|
+ return generation;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getGenCount(){
|
|
|
+ return genCount;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String toString(){
|
|
|
+ return name;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getInformation(){
|
|
|
+ log = "Generation Log";
|
|
|
+ if(generation.size() > 0){
|
|
|
+ addLogEntry("Avg Fittness: " + getAvgFittness());
|
|
|
+ addLogEntry("Max Fittness: " + getMaxFittness());
|
|
|
+ addLogEntry("Min Fittness: " + getMinFittness());
|
|
|
+ }
|
|
|
+ return log;
|
|
|
+ }
|
|
|
+
|
|
|
+ public double getAvgFittness(){
|
|
|
+ double fittness = 0;
|
|
|
+ for(HolegIndividual i : generation){
|
|
|
+ fittness += i.getFittness();
|
|
|
+ }
|
|
|
+
|
|
|
+ return (fittness/generation.size());
|
|
|
+ }
|
|
|
+
|
|
|
+ public double getMinFittness(){
|
|
|
+ double fittness = generation.get(0).getFittness();
|
|
|
+ for(HolegIndividual i : generation){
|
|
|
+ if(i.getFittness() < fittness){
|
|
|
+ fittness = i.getFittness();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return fittness;
|
|
|
+ }
|
|
|
+
|
|
|
+ public double getMaxFittness(){
|
|
|
+ double fittness = generation.get(0).getFittness();
|
|
|
+ for(HolegIndividual i : generation){
|
|
|
+ if(i.getFittness() > fittness){
|
|
|
+ fittness = i.getFittness();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return fittness;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addLogEntry(String entry){
|
|
|
+ log += "\n" + entry;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class ParameterArray{
|
|
|
+ public static final int POPULATION_SIZE = 0;
|
|
|
+ public static final int TOURNAMENT_SIZE = 1;
|
|
|
+ public static final int EDIT_EDGES = 2;
|
|
|
+ public static final int MAX_EDGES = 3;
|
|
|
+ public static final int EDGE_BREAK_AMOUNT = 4;
|
|
|
+ public static final int SIM_ITERATIONS = 5;
|
|
|
+ public static final int EDGE_MUTATION_PROB = 6;
|
|
|
+ public static final int SUPPLIED_POINTS = 7;
|
|
|
+ public static final int UNDERSUPPLIED_POINTS = 8;
|
|
|
+ public static final int OVERSUPPLIED_POINTS = 9;
|
|
|
+ public static final int LENGTH_POINTS = 10;
|
|
|
+ public static final int WILDCARD_MUTATION_PROB = 11;
|
|
|
+ public static final int PARTIALSUPPLIED_POINTS = 12;
|
|
|
+ public static final int WILDCARD_USAGE = 13;
|
|
|
+ public static final int OVERPRODUCTION = 14;
|
|
|
+ public static final int NODES_IN_WILDCARDS = 15;
|
|
|
+ public static final int OBJECT_SPACE = 16;
|
|
|
+ public static final int ORIGINAL_NETWORK = 17;
|
|
|
+ public static final int TOURNAMENT_PROB = 18;
|
|
|
+
|
|
|
+ public ArrayList<Object> list = new ArrayList<Object>();
|
|
|
+
|
|
|
+ public ParameterArray(){
|
|
|
+ for(int i = 0; i < 19; i++){
|
|
|
+ list.add(new Object());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public Object get(int index){
|
|
|
+ return list.get(index);
|
|
|
+ }
|
|
|
+
|
|
|
+ public <T extends Object> void set(int index, T object){
|
|
|
+ list.set(index, object);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class GAEdge extends CpsEdge{
|
|
|
+ public int aPos;
|
|
|
+ public int bPos;
|
|
|
+
|
|
|
+ public GAEdge(int a, int b, AbstractCpsObject nodeA, AbstractCpsObject nodeB){
|
|
|
+ //super(nodeA,nodeB, CAPACITY_INFINITE);
|
|
|
+ super(nodeA,nodeB, 100000);
|
|
|
+ aPos = a;
|
|
|
+ bPos = b;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void revalidateConnection(){
|
|
|
+ if(!this.getA().getConnections().contains(this)){
|
|
|
+ this.getA().getConnections().add(this);
|
|
|
+ }
|
|
|
+ if(!this.getB().getConnections().contains(this)){
|
|
|
+ this.getB().getConnections().add(this);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class HolonWildCard extends AbstractCpsObject{
|
|
|
+ AbstractCpsObject holdingObject;
|
|
|
+
|
|
|
+ public HolonWildCard(String objName){
|
|
|
+ super(objName);
|
|
|
+ this.setConnections(new ArrayList<CpsEdge>());
|
|
|
+ this.setImage("/Images/wildCard.png");
|
|
|
+ this.setSav("CVS");
|
|
|
+ this.setId(IdCounter.nextId());
|
|
|
+ holdingObject = this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public HolonWildCard(AbstractCpsObject obj) {
|
|
|
+ super(obj);
|
|
|
+ holdingObject = this;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //@Override
|
|
|
+ public AbstractCpsObject makeCopy() {
|
|
|
+ return new HolonWildCard(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setHoldingObject(AbstractCpsObject object){
|
|
|
+ this.holdingObject = object;
|
|
|
+ }
|
|
|
+
|
|
|
+ public AbstractCpsObject getHoldingObject(){
|
|
|
+ return holdingObject;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class GeneticAlgo{
|
|
|
+ public int popSize;
|
|
|
+ public ArrayList<HolegIndividual> population;
|
|
|
+
|
|
|
+ public HolegFactory randomFactory;
|
|
|
+ public TournamentSelection<HolegIndividual> selector;
|
|
|
+ public HolegCrossover reproducer;
|
|
|
+ public HolegMutation mutator;
|
|
|
+ public HolegFittnessScenario fittnessFunction;
|
|
|
+ public double topPercent;
|
|
|
+ public double buttomPercent;
|
|
|
+
|
|
|
+ public GeneticAlgo(TournamentSelection<HolegIndividual> selection, HolegCrossover crossover,
|
|
|
+ HolegMutation mutator, HolegFittnessScenario fittnessFkt,
|
|
|
+ HolegFactory factory, int popSize){
|
|
|
+
|
|
|
+ this.selector = selection;
|
|
|
+ this.reproducer = crossover;
|
|
|
+ this.mutator = mutator;
|
|
|
+ this.fittnessFunction = fittnessFkt;
|
|
|
+ randomFactory = factory;
|
|
|
+ this.popSize = popSize;
|
|
|
+
|
|
|
+ population = new ArrayList<HolegIndividual>();
|
|
|
+ topPercent = 0.05;
|
|
|
+
|
|
|
+ //generateRandomPopulation();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void generateRandomPopulation() {
|
|
|
+ population = new ArrayList<HolegIndividual>();
|
|
|
+ for(int i = 0; i < popSize; i++){
|
|
|
+ population.add(randomFactory.createRandomIndividual());
|
|
|
+ fittnessFunction.calculateFittness(population.get(i));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void createNextGeneration(){
|
|
|
+ ArrayList<HolegIndividual> nextGen = new ArrayList<HolegIndividual>();
|
|
|
+
|
|
|
+
|
|
|
+ int topBound = (int) Math.ceil(topPercent * popSize);
|
|
|
+ //int topBound = 1;
|
|
|
+ population = getSortedPopulation();
|
|
|
+
|
|
|
+ for(HolegIndividual individual : population.subList(0, topBound)){
|
|
|
+ ArrayList<HolegIndividual> childs = new ArrayList<HolegIndividual>();
|
|
|
+ childs.add(individual);
|
|
|
+ childs.add(individual);
|
|
|
+ childs = reproducer.crossOver(childs);
|
|
|
+ for(HolegIndividual i : childs){
|
|
|
+ i.addLogEntry("Top % from previous gen");
|
|
|
+ fittnessFunction.calculateFittness(i);
|
|
|
+ nextGen.add(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ selector.setCurrentPopulation(population);
|
|
|
+ while(nextGen.size() < popSize){
|
|
|
+ ArrayList<HolegIndividual> freshInds = new ArrayList<HolegIndividual>();
|
|
|
+ freshInds = reproducer.crossOver(selector.selectIndividuals());
|
|
|
+ for(HolegIndividual i : freshInds){
|
|
|
+ i = mutator.mutateIndividual(i);
|
|
|
+ fittnessFunction.calculateFittness(i);
|
|
|
+ }
|
|
|
+ nextGen.addAll(freshInds);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(popSize % 2 == 1){
|
|
|
+ Random rnd = new Random();
|
|
|
+ nextGen.remove(rnd.nextInt(popSize));
|
|
|
+ }
|
|
|
+ population = nextGen;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<HolegIndividual> getPopulation(){
|
|
|
+ return population;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<HolegIndividual> getSortedPopulation(){
|
|
|
+ return sortPopulation(population);
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<HolegIndividual> sortPopulation(ArrayList<HolegIndividual> individuals){
|
|
|
+ ArrayList<HolegIndividual> sortedList = new ArrayList<HolegIndividual>();
|
|
|
+ for(HolegIndividual hI : individuals){
|
|
|
+ for(int i = 0; i <= sortedList.size(); i++){
|
|
|
+ if(i == sortedList.size()){
|
|
|
+ sortedList.add(hI);
|
|
|
+ break;
|
|
|
+ }else if(sortedList.get(i).getFittness() < hI.getFittness()){
|
|
|
+ sortedList.add(i, hI);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return sortedList;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class HolegFactory{
|
|
|
+ ArrayList<AbstractCpsObject> objectSpace;
|
|
|
+ public ArrayList<AbstractCpsObject> originalObjects;
|
|
|
+ public ArrayList<CpsEdge> originalEdges;
|
|
|
+ public int maxObjects;
|
|
|
+ public int maxConnections;
|
|
|
+ HolegMutation mutation;
|
|
|
+ Random rng;
|
|
|
+ public boolean editEdges;
|
|
|
+
|
|
|
+ public HolegFactory(ArrayList<AbstractCpsObject> objects, int maxObjects, int maxConnections){
|
|
|
+ objectSpace = objects;
|
|
|
+ this.maxObjects = maxObjects;
|
|
|
+ this.maxConnections = maxConnections;
|
|
|
+ rng = new Random();
|
|
|
+ originalObjects = new ArrayList<AbstractCpsObject>();
|
|
|
+ originalEdges = new ArrayList<CpsEdge>();
|
|
|
+ editEdges = false;
|
|
|
+ mutation = new HolegMutation();
|
|
|
+ }
|
|
|
+
|
|
|
+ public HolegIndividual createRandomIndividual() {
|
|
|
+ HolegIndividual hI = new HolegIndividual(originalObjects, originalEdges);
|
|
|
+ setWildCards(hI);
|
|
|
+ if(editEdges){
|
|
|
+ editEdges(hI);
|
|
|
+ }
|
|
|
+ if(maxConnections > 0){
|
|
|
+ createEdges(hI);
|
|
|
+ }
|
|
|
+ return hI;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void setWildCards(HolegIndividual hI) {
|
|
|
+ int setAmount = rng.nextInt(hI.getWildcardIndexes().size() + 1);
|
|
|
+ ArrayList<Integer> list = new ArrayList<Integer>();
|
|
|
+ list.addAll(hI.getWildcardIndexes());
|
|
|
+ Collections.shuffle(list);
|
|
|
+ int spaceIdx = 0;
|
|
|
+ if(objectSpace.size() > 0){
|
|
|
+ for(int i = 0; i < setAmount; i++){
|
|
|
+ AbstractCpsObject wildCard = hI.indexToObjectMap.get(list.get(i));
|
|
|
+ spaceIdx = rng.nextInt(objectSpace.size());
|
|
|
+ AbstractCpsObject newObj = objectSpace.get(spaceIdx).makeCopy();
|
|
|
+ newObj.setPosition(wildCard.getPosition());
|
|
|
+ newObj.setId(wildCard.getId());
|
|
|
+ hI.addObjectWithIdx(newObj, newObj.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void editEdges(HolegIndividual hI) {
|
|
|
+ if(hI.getOriginalEdges().size() > 0 && hI.getIndexes().size() > 2){
|
|
|
+ int editAmount = rng.nextInt(hI.getOriginalEdges().size());
|
|
|
+ for(int i = 0; i < editAmount; i++){
|
|
|
+ int edgeIdx = rng.nextInt(hI.getOriginalEdges().size());
|
|
|
+ GAEdge toChange = hI.getOriginalEdges().get(edgeIdx);
|
|
|
+ mutation.changeSingleEdge(hI, toChange, true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void createObjects(HolegIndividual hI){
|
|
|
+
|
|
|
+ int objCount = rng.nextInt(maxObjects) + 1;
|
|
|
+
|
|
|
+ for(int i = 0; i < objCount; i++){
|
|
|
+
|
|
|
+
|
|
|
+ AbstractCpsObject newObj = null;
|
|
|
+ if(!editEdges){
|
|
|
+ AbstractCpsObject absObj = objectSpace.get(rng.nextInt(objectSpace.size()));
|
|
|
+ if(absObj instanceof HolonObject){
|
|
|
+ newObj = new HolonObject(absObj);
|
|
|
+ }else if(absObj instanceof HolonSwitch){
|
|
|
+ newObj = new HolonSwitch(absObj);
|
|
|
+ }else if(absObj instanceof HolonBattery){
|
|
|
+ newObj = new HolonBattery(absObj);
|
|
|
+ }else if(absObj instanceof HolonWildCard){
|
|
|
+ newObj = new HolonWildCard(absObj);
|
|
|
+ }else if(absObj == null){
|
|
|
+ newObj = new CpsNode("Node");
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ newObj = new CpsNode("Node");
|
|
|
+ }
|
|
|
+
|
|
|
+ hI.addObject(newObj);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void createEdges(HolegIndividual hI){
|
|
|
+ if(hI.getIndexes().size() > 1){
|
|
|
+ int edgeCount = rng.nextInt(maxConnections + 1);
|
|
|
+ ArrayList<Integer> list = new ArrayList<Integer>();
|
|
|
+
|
|
|
+ for (int i = 0; i < hI.getIndexes().size(); i++) {
|
|
|
+ list.add(hI.getIndexes().get(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ if(edgeCount >= hI.getAllEdges().size()){
|
|
|
+ edgeCount -= hI.getAllEdges().size();
|
|
|
+ }else{
|
|
|
+ edgeCount = 0;
|
|
|
+ }
|
|
|
+ for(int i = 0; i < edgeCount; i++){
|
|
|
+ Collections.shuffle(list);
|
|
|
+ int aPos = list.get(0);
|
|
|
+ int bPos = list.get(1);
|
|
|
+ hI.addEdge(aPos, bPos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class TournamentSelection<I extends HolegIndividual>{
|
|
|
+ public class Range{
|
|
|
+
|
|
|
+ public double min;
|
|
|
+ public double max;
|
|
|
+ public Range(double min, double max){
|
|
|
+ this.min = min;
|
|
|
+ this.max = max;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private ArrayList<I> currentPop;
|
|
|
+ public int tournamentSize;
|
|
|
+ private Random rng;
|
|
|
+ private ArrayList<Range> tournamentWheel;
|
|
|
+ public ArrayList<I> competitors;
|
|
|
+ public double selectProb;
|
|
|
+ private double maxRange;
|
|
|
+
|
|
|
+
|
|
|
+ public TournamentSelection(){
|
|
|
+ currentPop = new ArrayList<I>();
|
|
|
+ tournamentSize = 1;
|
|
|
+ rng = new Random();
|
|
|
+ selectProb = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ public TournamentSelection(int tSize, double selectProb){
|
|
|
+ currentPop = new ArrayList<I>();
|
|
|
+ rng = new Random();
|
|
|
+ tournamentSize = tSize;
|
|
|
+ this.selectProb = selectProb;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setCurrentPopulation(ArrayList<I> population) {
|
|
|
+ currentPop = population;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setTournamentSize(int size){
|
|
|
+ tournamentSize = size;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<I> selectIndividuals() {
|
|
|
+ ArrayList<I> parents = new ArrayList<I>();
|
|
|
+ parents.add(selectSingleIndividual());
|
|
|
+ parents.add(selectSingleIndividual());
|
|
|
+ return parents;
|
|
|
+ }
|
|
|
+
|
|
|
+ public I selectSingleIndividual(){
|
|
|
+ tournamentSelection();
|
|
|
+ initWheel();
|
|
|
+ double index = rng.nextDouble() * maxRange;
|
|
|
+ for(int i = 0; i < tournamentWheel.size(); i++){
|
|
|
+ if(index >= tournamentWheel.get(i).min && index <= tournamentWheel.get(i).max){
|
|
|
+ return competitors.get(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return competitors.get(rng.nextInt(competitors.size()));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void tournamentSelection(){
|
|
|
+ competitors = new ArrayList<I>();
|
|
|
+ for(int i = 0; i < tournamentSize; i++){
|
|
|
+ I candidate = chooseCandidate();
|
|
|
+ int size = competitors.size();
|
|
|
+ for(int j = 0; j <= size; j++){
|
|
|
+ if(j != size){
|
|
|
+ if(competitors.get(j).getFittness() < candidate.getFittness()){
|
|
|
+ competitors.add(j, candidate);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ competitors.add(candidate);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public I chooseCandidate(){
|
|
|
+ int index = rng.nextInt(currentPop.size());
|
|
|
+ I candidate = currentPop.get(index);
|
|
|
+ return candidate;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void initWheel(){
|
|
|
+ tournamentWheel = new ArrayList<Range>();
|
|
|
+ int power = 0;
|
|
|
+ maxRange = 0;
|
|
|
+ for(int i = 0; i < tournamentSize; i++){
|
|
|
+ double currentProb = selectProb * Math.pow((1- selectProb), power);
|
|
|
+ Range range = new Range(maxRange, maxRange + currentProb);
|
|
|
+ tournamentWheel.add(range);
|
|
|
+ maxRange += currentProb;
|
|
|
+ power++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class HolegFittnessScenario{
|
|
|
+ HolegFittnessFkt singleFkt;
|
|
|
+ Control controller;
|
|
|
+ Model model;
|
|
|
+ SimulationManager simManager;
|
|
|
+ ParameterArray params;
|
|
|
+ int edgeBreakCount;
|
|
|
+ double edgeLengthPoints;
|
|
|
+ double wildcardPoints;
|
|
|
+ double overprodPoints;
|
|
|
+ int totalSteps = 100;
|
|
|
+ int singleStep;
|
|
|
+ int breakCounter = 0;
|
|
|
+ HolegIndividual originalNetwork;
|
|
|
+ ArrayList<Integer> edgeBreakingIndexes = new ArrayList<Integer>();
|
|
|
+ double globalOverProd;
|
|
|
+ Random rng = new Random();
|
|
|
+
|
|
|
+ public HolegFittnessScenario(Control controller) {
|
|
|
+ singleFkt = new HolegFittnessFkt(controller);
|
|
|
+ model = singleFkt.getModel();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public double calculateFittness(HolegIndividual candidate) {
|
|
|
+ globalOverProd = 0;
|
|
|
+ double fittness = 0;
|
|
|
+ double noBreakFittness = calcFittnessWithoutBreak(candidate);
|
|
|
+ fittness += noBreakFittness;
|
|
|
+ candidate.addLogEntry("Fittness without break: " + noBreakFittness);
|
|
|
+ double breakFittness = calcFittnessWithBreak(candidate);
|
|
|
+ candidate.addLogEntry("Fittness with break: " + breakFittness);
|
|
|
+ fittness += breakFittness;
|
|
|
+ fittness = fittness /2;
|
|
|
+ globalOverProd = globalOverProd / 2;
|
|
|
+ globalOverProd = globalOverProd / totalSteps;
|
|
|
+
|
|
|
+ for(Integer wildIdx : candidate.getWildcardIndexes()){
|
|
|
+ if(!(candidate.indexToObjectMap.get(wildIdx) instanceof HolonWildCard)){
|
|
|
+ fittness += wildcardPoints;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ double edgeLength = 0;
|
|
|
+ for(GAEdge e : candidate.getAllEdges()){
|
|
|
+ Position aPos = e.getA().getPosition();
|
|
|
+ Position bPos = e.getB().getPosition();
|
|
|
+ double xDiff = Math.abs(aPos.x - bPos.x);
|
|
|
+ double yDiff = Math.abs(aPos.y - bPos.y);
|
|
|
+ edgeLength += Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2));
|
|
|
+ }
|
|
|
+
|
|
|
+ candidate.setEdgeLength(getRoundedValue(edgeLength));
|
|
|
+ candidate.addLogEntry("Total Edge Length: " + getRoundedValue(edgeLength));
|
|
|
+ fittness += (edgeLength/100)*edgeLengthPoints;
|
|
|
+
|
|
|
+ candidate.addLogEntry("average Overproduction: " + getRoundedValue(globalOverProd));
|
|
|
+
|
|
|
+ candidate.setFittness(getRoundedValue(fittness));
|
|
|
+ candidate.addLogEntry("Fittness: " + getRoundedValue(fittness));
|
|
|
+ return fittness;
|
|
|
+ }
|
|
|
+
|
|
|
+ public double calcFittnessWithoutBreak(HolegIndividual candidate){
|
|
|
+ double fittness = 0;
|
|
|
+ double avgOverProduction = 0;
|
|
|
+
|
|
|
+ for(CpsEdge edge : candidate.brokenEdges){
|
|
|
+ //edge.setWorkingState(true);
|
|
|
+ }
|
|
|
+ candidate.brokenEdges.clear();
|
|
|
+
|
|
|
+ for(int i = 0; i < totalSteps; i++){
|
|
|
+ model.setCurIteration(singleStep * i);
|
|
|
+ fittness += singleFkt.calculateFittness(candidate);
|
|
|
+ avgOverProduction += singleFkt.getCurrentOverProduction();
|
|
|
+ }
|
|
|
+
|
|
|
+ globalOverProd += avgOverProduction;
|
|
|
+ fittness += (avgOverProduction / 1000) * overprodPoints;
|
|
|
+ fittness = (int)fittness;
|
|
|
+ fittness = fittness/totalSteps;
|
|
|
+ return fittness;
|
|
|
+ }
|
|
|
+
|
|
|
+ public double calcFittnessWithBreak(HolegIndividual candidate){
|
|
|
+ double fittness = 0;
|
|
|
+ double avgOverProduction = 0;
|
|
|
+
|
|
|
+ for(CpsEdge edge : candidate.brokenEdges){
|
|
|
+ //edge.setWorkingState(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ breakEdges(candidate);
|
|
|
+
|
|
|
+ for(int i = 0; i < totalSteps; i++){
|
|
|
+ model.setCurIteration(singleStep * i);
|
|
|
+ fittness += singleFkt.calculateFittness(candidate);
|
|
|
+ avgOverProduction += singleFkt.getCurrentOverProduction();
|
|
|
+ }
|
|
|
+
|
|
|
+ globalOverProd += avgOverProduction;
|
|
|
+ fittness += (avgOverProduction / 1000) * overprodPoints;
|
|
|
+ fittness = (int)fittness;
|
|
|
+ fittness = fittness/totalSteps;
|
|
|
+
|
|
|
+ return fittness;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void breakEdges(HolegIndividual candidate) {
|
|
|
+ candidate.brokenEdges.clear();
|
|
|
+ int unbrokenEdges = 0;
|
|
|
+ for(Integer idx : edgeBreakingIndexes){
|
|
|
+ ArrayList<CpsEdge> healthyEdges = new ArrayList<CpsEdge>();
|
|
|
+
|
|
|
+
|
|
|
+ for(CpsEdge edge : candidate.indexToObjectMap.get(idx).getConnections()){
|
|
|
+ /*
|
|
|
+ if(edge.isWorking()){
|
|
|
+ healthyEdges.add(edge);
|
|
|
+ }
|
|
|
+ */
|
|
|
+ }
|
|
|
+
|
|
|
+ Collections.shuffle(healthyEdges);
|
|
|
+ if(healthyEdges.size() > 0){
|
|
|
+ //healthyEdges.get(0).setWorkingState(false);
|
|
|
+ candidate.brokenEdges.add(healthyEdges.get(0));
|
|
|
+ }else{
|
|
|
+ unbrokenEdges++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(unbrokenEdges > 0){
|
|
|
+ ArrayList<CpsEdge> healthyEdges = new ArrayList<CpsEdge>();
|
|
|
+ for(CpsEdge edge : candidate.getAllEdges()){
|
|
|
+ /*
|
|
|
+ if(edge.isWorking()){
|
|
|
+ healthyEdges.add(edge);
|
|
|
+ }
|
|
|
+ */
|
|
|
+ }
|
|
|
+ Collections.shuffle(healthyEdges);
|
|
|
+ int bound;
|
|
|
+ if(unbrokenEdges <= healthyEdges.size()){
|
|
|
+ bound = unbrokenEdges;
|
|
|
+ }else{
|
|
|
+ bound = healthyEdges.size();
|
|
|
+ }
|
|
|
+ for(int i = 0; i < bound; i++){
|
|
|
+ //healthyEdges.get(i).setWorkingState(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setParameters(ParameterArray params){
|
|
|
+ this.params = params;
|
|
|
+ edgeBreakCount = (int)params.get(params.EDGE_BREAK_AMOUNT);
|
|
|
+ edgeLengthPoints = (double)params.get(params.LENGTH_POINTS);
|
|
|
+ wildcardPoints = (double)params.get(params.WILDCARD_USAGE);
|
|
|
+ totalSteps = (int)params.get(params.SIM_ITERATIONS);
|
|
|
+ overprodPoints = (double)params.get(params.OVERPRODUCTION);
|
|
|
+ originalNetwork = (HolegIndividual)params.get(params.ORIGINAL_NETWORK);
|
|
|
+ if(totalSteps < 100){
|
|
|
+ singleStep = (int) Math.floor(100/totalSteps);
|
|
|
+ }else{
|
|
|
+ singleStep = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ singleFkt.setParameters(params);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * method is called before a new generation is calculated
|
|
|
+ * setting the specific edge breaks here
|
|
|
+ */
|
|
|
+ public void initialize(){
|
|
|
+ edgeBreakingIndexes.clear();
|
|
|
+ ArrayList<Integer> objIndexes = new ArrayList<Integer>();
|
|
|
+ objIndexes.addAll(originalNetwork.getIndexes());
|
|
|
+ Collections.shuffle(objIndexes);
|
|
|
+ //shuffeling leads to random selection of Indexes
|
|
|
+ int bound;
|
|
|
+ if(edgeBreakCount <= objIndexes.size()){
|
|
|
+ bound = edgeBreakCount;
|
|
|
+ }else{
|
|
|
+ bound = objIndexes.size();
|
|
|
+ }
|
|
|
+ for(int i = 0; i < bound; i++){
|
|
|
+ edgeBreakingIndexes.add(objIndexes.get(rng.nextInt(objIndexes.size())));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public double getRoundedValue(double value){
|
|
|
+ BigDecimal bd = new BigDecimal(value);
|
|
|
+ bd = bd.setScale(2, RoundingMode.HALF_UP);
|
|
|
+ return bd.doubleValue();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class HolegFittnessFkt{
|
|
|
+ Control controller;
|
|
|
+ Model model;
|
|
|
+ SimulationManager simManager;
|
|
|
+ ParameterArray params;
|
|
|
+ double suppliedPoints;
|
|
|
+ double oversuppliedPoints;
|
|
|
+ double undersuppliedPoints;
|
|
|
+ double partiallysuppliedPoints;
|
|
|
+ boolean everyoneSupplied;
|
|
|
+
|
|
|
+ public HolegFittnessFkt(Control controller){
|
|
|
+ model = new Model();
|
|
|
+ simManager = new SimulationManager(model);
|
|
|
+ }
|
|
|
+
|
|
|
+ public double calculateFittness(HolegIndividual candidate){
|
|
|
+ model.getObjectsOnCanvas().clear();
|
|
|
+ model.getEdgesOnCanvas().clear();
|
|
|
+ candidate.configurateNetwork();
|
|
|
+ model.getObjectsOnCanvas().addAll(candidate.getObjects());
|
|
|
+ model.getEdgesOnCanvas().addAll(candidate.getAllEdges());
|
|
|
+ simManager.calculateStateForTimeStep(model.getCurIteration());
|
|
|
+
|
|
|
+ DecoratedState state = simManager.getDecorState(model.getCurIteration());
|
|
|
+
|
|
|
+ everyoneSupplied = true;
|
|
|
+ double fittness = 0;
|
|
|
+ for(DecoratedNetwork net : state.getNetworkList()){
|
|
|
+ fittness += net.getConsumerSelfSuppliedList().stream().map(con -> con.getState()).map(objState -> StateToFitness(objState)).reduce(0.0,(a,b)->(a+b));
|
|
|
+ fittness += net.getConsumerList().stream().map(con -> con.getState()).map(objState -> StateToFitness(objState)).reduce(0.0,(a,b)->(a+b));
|
|
|
+ }
|
|
|
+ return fittness;
|
|
|
+ }
|
|
|
+
|
|
|
+ public double StateToFitness(HolonObjectState state){
|
|
|
+ switch (state) {
|
|
|
+ case NOT_SUPPLIED:
|
|
|
+ return undersuppliedPoints;
|
|
|
+ case NO_ENERGY:
|
|
|
+ return 0f;
|
|
|
+ case OVER_SUPPLIED:
|
|
|
+ return oversuppliedPoints;
|
|
|
+ case PARTIALLY_SUPPLIED:
|
|
|
+ return partiallysuppliedPoints;
|
|
|
+ case PRODUCER:
|
|
|
+ return 0f;
|
|
|
+ case SUPPLIED:
|
|
|
+ return suppliedPoints;
|
|
|
+ default:
|
|
|
+ return 0f;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public float getCurrentOverProduction(){
|
|
|
+ float overProd = 0;
|
|
|
+ /*
|
|
|
+ for(SubNet subnet : simManager.getSubNets()){
|
|
|
+ overProd += subnet.spareProduction;
|
|
|
+ }
|
|
|
+ * */
|
|
|
+ return overProd;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean getEveryoneSupplied(){
|
|
|
+ return everyoneSupplied;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Model getModel(){
|
|
|
+ return model;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setParameters(ParameterArray params){
|
|
|
+ this.params = params;
|
|
|
+ suppliedPoints = (double)params.get(params.SUPPLIED_POINTS);
|
|
|
+ oversuppliedPoints = (double)params.get(params.OVERSUPPLIED_POINTS);
|
|
|
+ undersuppliedPoints = (double)params.get(params.UNDERSUPPLIED_POINTS);
|
|
|
+ partiallysuppliedPoints = (double)params.get(params.PARTIALSUPPLIED_POINTS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class HolegCrossover{
|
|
|
+ protected double crossProb;
|
|
|
+ protected Random rng;
|
|
|
+
|
|
|
+ public HolegCrossover(double prob){
|
|
|
+ crossProb = prob;
|
|
|
+ rng = new Random();
|
|
|
+ }
|
|
|
+
|
|
|
+ public HolegCrossover(){
|
|
|
+ crossProb = 0.7;
|
|
|
+ rng = new Random();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setCrossoverProbability(double prob){
|
|
|
+ crossProb = prob;
|
|
|
+ }
|
|
|
+
|
|
|
+ public double getCrossoverProbability(){
|
|
|
+ return crossProb;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ArrayList<HolegIndividual> crossOver(ArrayList<HolegIndividual> parents) {
|
|
|
+ HolegIndividual parent1 = parents.get(0);
|
|
|
+ HolegIndividual parent2 = parents.get(1);
|
|
|
+ ArrayList<HolegIndividual> children = new ArrayList<HolegIndividual>();
|
|
|
+ children.add(createChild(parent1, parent2));
|
|
|
+ children.add(createChild(parent2, parent1));
|
|
|
+ return children;
|
|
|
+ }
|
|
|
+
|
|
|
+ private HolegIndividual createChild(HolegIndividual parent1, HolegIndividual parent2) {
|
|
|
+ HolegIndividual child = new HolegIndividual(parent1.getOriginObjects(), null);
|
|
|
+ ArrayList<HolegIndividual> parents = new ArrayList<HolegIndividual>();
|
|
|
+ parents.add(parent1);
|
|
|
+ parents.add(parent2);
|
|
|
+ child.setParents(parents);
|
|
|
+
|
|
|
+ ArrayList<Integer> parent1WildCardIndexes = parent1.wildCardIndexes;
|
|
|
+ int splitIdx = (int) Math.ceil((double)parent1WildCardIndexes.size()/2);
|
|
|
+
|
|
|
+ for(int i = 0; i < splitIdx; i++){
|
|
|
+ int index = parent1WildCardIndexes.get(i);
|
|
|
+
|
|
|
+ AbstractCpsObject wildObj = parent1.indexToObjectMap.get(index);
|
|
|
+ AbstractCpsObject newWildObj = wildObj.makeCopy();
|
|
|
+ newWildObj.setId(wildObj.getId());
|
|
|
+ newWildObj.setPosition(wildObj.getPosition());
|
|
|
+ child.addObject(newWildObj);
|
|
|
+ }
|
|
|
+ int restAmount = parent1WildCardIndexes.size() - splitIdx;
|
|
|
+
|
|
|
+ ArrayList<Integer> parent2WildCardIndexes = parent2.wildCardIndexes;
|
|
|
+ for(int j = 0; j < restAmount; j++){
|
|
|
+ int index = parent2WildCardIndexes.size() - 1; //greift auf letztes element zu
|
|
|
+ index -= j; //greift bei jedem durchlauf auf ein weiter vorderes element zu
|
|
|
+ if(index >= 0){
|
|
|
+ int objIdx = parent2WildCardIndexes.get(index);
|
|
|
+
|
|
|
+ AbstractCpsObject wildObj = parent2.indexToObjectMap.get(objIdx);
|
|
|
+ AbstractCpsObject newWildObj = wildObj.makeCopy();
|
|
|
+ newWildObj.setId(wildObj.getId());
|
|
|
+ newWildObj.setPosition(wildObj.getPosition());
|
|
|
+ child.addObject(newWildObj);
|
|
|
+ }else{
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ child.wildCardIndexes = parent1.wildCardIndexes;
|
|
|
+
|
|
|
+ //OriginEdges
|
|
|
+ splitIdx = (int) Math.ceil((double)parent1.getOriginalEdges().size()/2);
|
|
|
+ for(int i = 0; i < splitIdx; i++){
|
|
|
+ child.addOriginalEdge(parent1.getOriginalEdges().get(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ restAmount = parent1.getOriginalEdges().size() - splitIdx;
|
|
|
+ for(int j = 0; j < restAmount; j++){
|
|
|
+ int idx = parent2.getOriginalEdges().size() - 1;
|
|
|
+ idx -= j;
|
|
|
+ if(idx >= 0){
|
|
|
+ child.addOriginalEdge(parent2.getOriginalEdges().get(idx));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //HolonEdges
|
|
|
+ splitIdx = (int) Math.ceil((double)parent1.getAdditionalEdges().size()/2);
|
|
|
+ for(int k = 0; k < splitIdx; k++){
|
|
|
+ int posA = parent1.getAdditionalEdges().get(k).aPos;
|
|
|
+ int posB = parent1.getAdditionalEdges().get(k).bPos;
|
|
|
+
|
|
|
+ child.addEdge(posA, posB);
|
|
|
+ }
|
|
|
+
|
|
|
+ restAmount = parent1.getAdditionalEdges().size() - splitIdx;
|
|
|
+ for(int l = 0; l < restAmount; l++){
|
|
|
+ int idx = parent2.getAdditionalEdges().size() - 1;
|
|
|
+ idx -= l;
|
|
|
+
|
|
|
+ if(idx >= 0){
|
|
|
+ int posA = parent2.getAdditionalEdges().get(idx).aPos;
|
|
|
+ int posB = parent2.getAdditionalEdges().get(idx).bPos;
|
|
|
+
|
|
|
+ child.addEdge(posA, posB);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return child;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class HolegMutation{
|
|
|
+ protected double mutationProb;
|
|
|
+ public Random rng = new Random();
|
|
|
+
|
|
|
+ public final int ADD_EDGE = 0;
|
|
|
+ public final int REMOVE_EDGE = 1;
|
|
|
+ public final int CHANGE_OBJECT = 0;
|
|
|
+ public final int REMOVE_OBJECT = 1;
|
|
|
+ ArrayList<AbstractCpsObject> objSpace;
|
|
|
+ public boolean editEdges = false;
|
|
|
+ public int maxConnections = 0;
|
|
|
+ public double edgeMutationProb = 0;
|
|
|
+
|
|
|
+ public HolegMutation(){
|
|
|
+ mutationProb = 0.001;
|
|
|
+ rng = new Random();
|
|
|
+ }
|
|
|
+
|
|
|
+ public HolegMutation(double prob){
|
|
|
+ mutationProb = prob;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setMutationProbability(double probability){
|
|
|
+ mutationProb = probability;
|
|
|
+ }
|
|
|
+
|
|
|
+ public double getMutationProbability(){
|
|
|
+ return mutationProb;
|
|
|
+ }
|
|
|
+
|
|
|
+ public HolegIndividual mutateIndividual(HolegIndividual mutant) {
|
|
|
+
|
|
|
+ for(Integer wildIdx : mutant.getWildcardIndexes()){
|
|
|
+ if(rng.nextDouble() < mutationProb){
|
|
|
+ switch(rng.nextInt(2)){
|
|
|
+ case CHANGE_OBJECT :
|
|
|
+ changeObject(mutant, wildIdx);
|
|
|
+ break;
|
|
|
+ case REMOVE_OBJECT :
|
|
|
+ removeObject(mutant, wildIdx);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ArrayList<GAEdge> mutationEdges = new ArrayList<GAEdge>();
|
|
|
+
|
|
|
+ int endIdx = 0;
|
|
|
+ boolean isOriginal = false;
|
|
|
+
|
|
|
+ if(editEdges){
|
|
|
+ mutationEdges.addAll(mutant.getOriginalEdges());
|
|
|
+ endIdx = mutationEdges.size(); //originalEdges müssen zuerst mutieren da sie sonst
|
|
|
+ //verworfen werden falls additional Edge gleiche werte bekommt
|
|
|
+ mutationEdges.addAll(mutant.getAdditionalEdges());
|
|
|
+ }else{
|
|
|
+ mutationEdges.addAll(mutant.getAdditionalEdges());
|
|
|
+ }
|
|
|
+
|
|
|
+ for(int i = 0; i < mutationEdges.size(); i++){
|
|
|
+ if(rng.nextDouble() < edgeMutationProb){
|
|
|
+ if(i < endIdx){
|
|
|
+ changeSingleEdge(mutant, mutationEdges.get(i), true);
|
|
|
+ }else{
|
|
|
+ changeSingleEdge(mutant, mutationEdges.get(i), false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(rng.nextDouble() < edgeMutationProb){
|
|
|
+ switch(rng.nextInt(2)){
|
|
|
+ case ADD_EDGE:
|
|
|
+ addEdge(mutant);
|
|
|
+ break;
|
|
|
+ case REMOVE_EDGE:
|
|
|
+ removeEdge(mutant);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ return mutant;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void removeObject(HolegIndividual mutant, int removeIdx) {
|
|
|
+ ArrayList<CpsEdge> connections = new ArrayList<CpsEdge>();
|
|
|
+ connections.addAll(mutant.getObjectWithIndex(removeIdx).getConnections());
|
|
|
+ for(CpsEdge e : connections){
|
|
|
+ e.getA().getConnections().remove(e);
|
|
|
+ e.getB().getConnections().remove(e);
|
|
|
+ }
|
|
|
+ ArrayList<GAEdge> edgesToRemove = new ArrayList<GAEdge>();
|
|
|
+ for(GAEdge gE : mutant.getAllEdges()){
|
|
|
+ if(gE.aPos == removeIdx || gE.bPos == removeIdx){
|
|
|
+ edgesToRemove.add(gE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mutant.getAllEdges().removeAll(edgesToRemove);
|
|
|
+ mutant.addLogEntry("Object wit ID " + mutant.indexToObjectMap.get(removeIdx).getId() + " removed");
|
|
|
+ mutant.removeObject(removeIdx);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void changeObject(HolegIndividual mutant, int changeIdx) {
|
|
|
+ if(objSpace.size() > 0){
|
|
|
+ AbstractCpsObject newObj = null;
|
|
|
+ AbstractCpsObject absObj = objSpace.get(rng.nextInt(objSpace.size()));
|
|
|
+ newObj = absObj.makeCopy();
|
|
|
+
|
|
|
+ AbstractCpsObject oldObject = mutant.getObjectWithIndex(changeIdx);
|
|
|
+ for(CpsEdge e : oldObject.getConnections()){
|
|
|
+ if(e.getA() == oldObject){
|
|
|
+ e.setA(newObj);
|
|
|
+ newObj.addConnection(e);
|
|
|
+ }else if(e.getB() == oldObject){
|
|
|
+ e.setB(newObj);
|
|
|
+ newObj.addConnection(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ newObj.setId(oldObject.getId());
|
|
|
+ newObj.setPosition(oldObject.getPosition());
|
|
|
+
|
|
|
+ mutant.indexToObjectMap.put(changeIdx, newObj);
|
|
|
+ mutant.addLogEntry("Object with Id " + newObj.getId() + " changed");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void removeEdge(HolegIndividual mutant) {
|
|
|
+ ArrayList<GAEdge> edgesSpace = new ArrayList<GAEdge>();
|
|
|
+ int spaceEndIdx = 0;
|
|
|
+ if(editEdges){
|
|
|
+
|
|
|
+ edgesSpace.addAll(mutant.getAdditionalEdges());
|
|
|
+ spaceEndIdx = edgesSpace.size();
|
|
|
+ edgesSpace.addAll(mutant.getOriginalEdges());
|
|
|
+
|
|
|
+ }else{
|
|
|
+ edgesSpace.addAll(mutant.getAdditionalEdges());
|
|
|
+ spaceEndIdx = edgesSpace.size();
|
|
|
+ }
|
|
|
+ if(edgesSpace.size() > 0){
|
|
|
+ int edgeIdx = rng.nextInt(edgesSpace.size());
|
|
|
+ CpsEdge toRemove = edgesSpace.get(edgeIdx);
|
|
|
+ toRemove.getA().getConnections().remove(toRemove);
|
|
|
+ toRemove.getB().getConnections().remove(toRemove);
|
|
|
+ if(edgeIdx < spaceEndIdx){
|
|
|
+ mutant.getAdditionalEdges().remove(edgeIdx);
|
|
|
+ }else{
|
|
|
+ mutant.getOriginalEdges().remove(edgeIdx-spaceEndIdx);
|
|
|
+ }
|
|
|
+ mutant.addLogEntry("Edge (" + toRemove.getA().getId() + ","
|
|
|
+ + toRemove.getB().getId() + ") removed");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addEdge(HolegIndividual mutant) {
|
|
|
+ if(mutant.getAllEdges().size() < maxConnections){
|
|
|
+ if(mutant.getIndexes().size() > 1){
|
|
|
+ ArrayList<Integer> list = new ArrayList<Integer>();
|
|
|
+ list.addAll(mutant.getIndexes());
|
|
|
+ Collections.shuffle(list);
|
|
|
+ int aPos = list.get(0);
|
|
|
+ int bPos = list.get(1);
|
|
|
+ mutant.addEdge(aPos, bPos);
|
|
|
+ mutant.addLogEntry("Edge (" + mutant.indexToObjectMap.get(aPos).getId() +
|
|
|
+ "," + mutant.indexToObjectMap.get(bPos).getId() + ") added");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void changeRandomEdge(HolegIndividual mutant) {
|
|
|
+ ArrayList<GAEdge> edgeSpace;
|
|
|
+ if(editEdges){
|
|
|
+ edgeSpace = mutant.getAllEdges();
|
|
|
+ }else{
|
|
|
+ edgeSpace = mutant.getAdditionalEdges();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(edgeSpace.size() > 0){
|
|
|
+ int edgeIdx = rng.nextInt(edgeSpace.size());
|
|
|
+ GAEdge toChange = edgeSpace.get(edgeIdx);
|
|
|
+ boolean changeA = rng.nextBoolean();
|
|
|
+ int randomIndex = rng.nextInt(mutant.getIndexes().size());
|
|
|
+ randomIndex = mutant.getIndexes().get(randomIndex);
|
|
|
+ if(changeA){
|
|
|
+ toChange.getA().getConnections().remove(toChange);
|
|
|
+ if(toChange.getB() != mutant.getObjectWithIndex(randomIndex)){
|
|
|
+ toChange.setA(mutant.getObjectWithIndex(randomIndex));
|
|
|
+ toChange.aPos = randomIndex;
|
|
|
+ mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
|
|
|
+ }else{
|
|
|
+ toChange.getB().getConnections().remove(toChange);
|
|
|
+ mutant.getAdditionalEdges().remove(toChange);
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ toChange.getB().getConnections().remove(toChange);
|
|
|
+ if(toChange.getA() != mutant.getObjectWithIndex(randomIndex)){
|
|
|
+ toChange.setB(mutant.getObjectWithIndex(randomIndex));
|
|
|
+ toChange.bPos = randomIndex;
|
|
|
+ mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
|
|
|
+ }else{
|
|
|
+ toChange.getA().getConnections().remove(toChange);
|
|
|
+ mutant.getAdditionalEdges().remove(toChange);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void changeSingleEdge(HolegIndividual mutant, GAEdge toChange, boolean isOriginal){
|
|
|
+ boolean changeA = rng.nextBoolean();
|
|
|
+ int randomIndex = rng.nextInt(mutant.getIndexes().size());
|
|
|
+ randomIndex = mutant.getIndexes().get(randomIndex);
|
|
|
+ String logString = "Edge (" + toChange.aPos + "," + toChange.bPos +
|
|
|
+ ") changed to ";
|
|
|
+ if(mutant.getObjectWithIndex(randomIndex) != toChange.getA() &&
|
|
|
+ mutant.getObjectWithIndex(randomIndex) != toChange.getB()){
|
|
|
+ if(changeA && !mutant.edgeExists(randomIndex, toChange.bPos, mutant.getAllEdges())){
|
|
|
+ toChange.getA().getConnections().remove(toChange);
|
|
|
+ toChange.setA(mutant.getObjectWithIndex(randomIndex));
|
|
|
+ toChange.aPos = randomIndex;
|
|
|
+ mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
|
|
|
+ }else if(!mutant.edgeExists(randomIndex, toChange.aPos, mutant.getAllEdges())){
|
|
|
+ toChange.getB().getConnections().remove(toChange);
|
|
|
+ toChange.setB(mutant.getObjectWithIndex(randomIndex));
|
|
|
+ toChange.bPos = randomIndex;
|
|
|
+ mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mutant.addLogEntry(logString + "(" + toChange.aPos + "," + toChange.bPos + ")");
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setParameters(ParameterArray params){
|
|
|
+ this.edgeMutationProb = (double)params.get(params.EDGE_MUTATION_PROB);
|
|
|
+ this.setMutationProbability((double)params.get(params.WILDCARD_MUTATION_PROB));
|
|
|
+ this.maxConnections = (int)params.get(params.MAX_EDGES);
|
|
|
+ this.editEdges = (boolean)params.get(params.EDIT_EDGES);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setObjectSpace(ArrayList<AbstractCpsObject> space){
|
|
|
+ objSpace = space;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setEdgeMutationProb(double prob){
|
|
|
+ this.edgeMutationProb = prob;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|