123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- package algorithms.geneticAlgorithm.holegGA.Components;
- import java.math.BigDecimal;
- import java.math.RoundingMode;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Random;
- import classes.CpsEdge;
- import classes.HolonWildCard;
- import classes.Position;
- import ui.controller.Control;
- import ui.controller.SimulationManager;
- import ui.model.Model;
- import algorithms.geneticAlgorithm.Components.GAFittnessFunctionStrategy;
- import algorithms.geneticAlgorithm.holegGA.GAEdge;
- import algorithms.geneticAlgorithm.holegGA.ParameterArray;
- public class HolegFittnessScenario implements GAFittnessFunctionStrategy<HolegIndividual>{
- 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();
-
- }
-
- @Override
- 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(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();
- }
- }
|