Skip to content

Commit

Permalink
Master finalization
Browse files Browse the repository at this point in the history
- improved results and graph details UI so reader directs eye to most relevant data
- improved graph formatting
- tiny refactorings
- fixed README typos, updated screenshots due to UI update
- added master experiment results used in the master document for storage
- added multiple experiments test to verify the software effectiveness
  • Loading branch information
marjan3 committed Sep 15, 2020
1 parent f9b8bf9 commit 47bc4ef
Show file tree
Hide file tree
Showing 60 changed files with 207,026 additions and 225 deletions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2020 Marjan Tanevski

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
26 changes: 14 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ Java implementation of the Crossbar Adaptive Array (WIP) with usage

![screenshot1](https://github.com/Tanevski3/caa-experimentation/blob/master/i1.png)

![screenshot3](https://github.com/Tanevski3/caa-experimentation/blob/master/i3.png)

# Requirements

- Java 1.8
- Maven

# Nice to have
- Intellij
- IntelliJ

# Install
- `git clone https://github.com/Tanevski3/caa-experimentation.git`
Expand All @@ -31,33 +33,33 @@ Java implementation of the Crossbar Adaptive Array (WIP) with usage

# Usage Guide

Once File -> Open Graph is clicked a file selection window will appear, where the user can browse through its filesystem to select a graph for loading into the software.
Once "File -> Open Graph" is clicked a file selection window will appear, where the user can browse through its filesystem to select a graph for loading into the software.

In the bottom right corner just above the Open & Cancel buttons there is a list of all supported formats for loading graphs. At the time of writing this paper, GraphML format is the only format that is supported. Once a graph is loaded into the software the working space should be filled with rendering of the graph.

## Changing preferences
The outlook of the graph displayed in the main area can be modified through File -> Preferences. Besides the color of the nodes & edges within Preferences edge width & vertices labels could also be modified. Additionally, some properties specific to the experiment can be modified; that is the CAA tab.
The outlook of the graph displayed in the main area can be modified through File -> Preferences. Besides, the color of the nodes & edges within Preferences edge width & vertices labels could also be modified. Additionally, some properties specific to the experiment can be modified; that is the CAA tab.

## Experimenting
Experimenting is divided in two menu items:
Experimenting is divided in two menu-items:
1. Agent Traversal
2. Find Happy State

Experiments can be executed with different properties. Clicking on one of the menu items will show a popup for selecting properties of the algorithm used for traversal. Properties are as follows:
Experiments can be executed with different properties. Clicking on one of the menu items will show a popup for selecting properties of the algorithm used for a traversal. Properties are as follows:
• Agent traversing algorithms: original & advanced
• Experiment animation
• Selecting initial values
• Selecting initial values.

Once Find Happy State experiment is run, results will be generated in a separate tab. For agent traversal there are no results.
The results are related to the graph that is being experimented on.
Once "Find Happy State" experiment is being ran, results will be generated in a separate tab. For agent traversal there are no results.
The results relate to the graph that is being experimented on.

## Experiment Results
The experiment results are divided in two parts.
The experiment results split in two parts.
1. Overall vertices traversals tab contains the following data
a. Vertices occurrences per generation is showing how many traversals have occurred for each vertex
b. Happy vs Sad generation is showing how each generation ended
c. Happy to shortest path factor is the percentage of edges that match from the happy path to the shortest path
2. Vertices traversals per generation tab goes more intro details about a single generation. It shows the increments, traversed edges, increments weight & traversal weight. The results are paged depending on the number of generations.
b. "Happy" vs "Sad" generation is showing how each generation ended
c. "Happy to shortest" path factor is the percentage of edges that match from the happy path to the shortest path
2. Vertices traversals per generation tab goes more intro details about a single generation. It shows the increments, traversed edges, increments weight & traversal weight. The results are being paged depending on the number of generations.

## Viewing additional statistics & shortest path
Additionally, the software provides a visualization of the shortest path & vertices distribution. That can be done through the View menu.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public interface DefaultValues {
double HAPPY_INCREMENTER_MIN_VALUE = 1.1;
double HAPPY_INCREMENTER_MAX_VALUE = 10.0;
boolean SHOULD_ANIMATE_CAA = false;
CaaAgentType AGENT_TYPE_VALUE = CaaAgentType.UNTRAVELED_EDGE;
CaaAgentType AGENT_TYPE_VALUE = CaaAgentType.ORIGINAL;

// Supported file types
enum FilterMode {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ public InformationAlert(String title, String header, String content) {
this.setContentText(content);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.mtanevski.master.caa.gui.alerts;

import javafx.scene.control.Alert;
import javafx.scene.control.TextArea;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;

public class TextAlert extends Alert {
public TextAlert(String title, String header, String content) {
super(AlertType.INFORMATION);

this.setTitle(title);
this.setHeaderText(header);

Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle(title);

TextArea textArea = new TextArea(content);
textArea.setEditable(false);
textArea.setWrapText(true);

textArea.setMaxWidth(Double.MAX_VALUE);
textArea.setMaxHeight(Double.MAX_VALUE);
GridPane.setVgrow(textArea, Priority.ALWAYS);
GridPane.setHgrow(textArea, Priority.ALWAYS);

GridPane expContent = new GridPane();
expContent.setMaxWidth(Double.MAX_VALUE);
expContent.add(textArea, 0, 0);

this.getDialogPane().setContent(expContent);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.mtanevski.master.caa.lib.CaaExperimentResults;
import com.mtanevski.master.caa.lib.CaaGraph;
import com.mtanevski.master.caa.lib.CaaTraversalData;
import com.mtanevski.master.caa.lib.impl.edges.SimpleCaaEdge;
import com.mtanevski.master.caa.lib.impl.edges.WeightedCaaEdge;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.Parent;
Expand All @@ -12,6 +14,8 @@
import javafx.scene.chart.StackedBarChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Pagination;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
Expand All @@ -21,8 +25,10 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

import static javafx.collections.FXCollections.observableArrayList;
import static org.apache.commons.lang3.StringUtils.join;

@Component
public class ExperimentResultsController {
Expand All @@ -32,14 +38,16 @@ public class ExperimentResultsController {
@FXML
public Text generationEndText;
@FXML
public Text incrementsText;
public TextArea incrementsTextArea;
@FXML
public Text traversedEdgesText;
@FXML
public Text traversedVerticesText;
public TextArea traversedEdgesTextArea;
@FXML
public Text happyToShortestPathFactor;
@FXML
public Text edgeTraversalsInTotal;
@FXML
public TextField traversedVerticesTextField;
@FXML
public StackedBarChart<String, Number> verticesTraversalsChart;
@FXML
public PieChart generationsHappinessChart;
Expand All @@ -65,6 +73,7 @@ public void setGraphData(CaaExperimentData caaExperimentSaveData) {
}
setVerticesTraversalsChart(history, caaGraph);
setShortestPathEfficiency(caaExperimentSaveData.getResults());
setEdgeTraversalsInTotal(caaExperimentSaveData.getResults());
setGenerationsHappinessChart(history);
setPerGenerationTab(history);
}
Expand All @@ -79,6 +88,11 @@ private void setShortestPathEfficiency(CaaExperimentResults results) {
happyToShortestPathFactor.setText(results.getHappyToShortestPathFactor() * 100 + "%");
}

private void setEdgeTraversalsInTotal(CaaExperimentResults results) {
int sum = results.getHistory().stream().mapToInt(d -> d.getTraversedEdges().size()).sum();
edgeTraversalsInTotal.setText(sum + "");
}

private void setPerGenerationTab(List<CaaTraversalData> history) {
String happyString = messageSource.getMessage("experiment.results.generation.end.happy",
null, Locale.getDefault());
Expand All @@ -91,9 +105,17 @@ private void setPerGenerationTab(List<CaaTraversalData> history) {
generationNumberText.setText("" + (pageIndex + 1));
generationEndText.setText(data.isHappy() ? happyString : sadString);
edgesTableViewController.setTableData(data.getGraph());
incrementsText.setText("" + data.getIncrements());
traversedEdgesText.setText("" + data.getTraversedEdges());
traversedVerticesText.setText("" + data.getTraversedVertices());
List<WeightedCaaEdge> increments = data.getTraversedEdges()
.stream()
.map(WeightedCaaEdge::new)
.collect(Collectors.toList());
incrementsTextArea.setText(join(increments, ", "));
List<SimpleCaaEdge> traversedEdges = data.getTraversedEdges()
.stream()
.map(SimpleCaaEdge::new)
.collect(Collectors.toList());
traversedEdgesTextArea.setText(join(traversedEdges, ", "));
traversedVerticesTextField.setText(join(data.getTraversedVertices(), ", "));
return new VBox();
});
}
Expand Down Expand Up @@ -129,7 +151,7 @@ private void setGenerationsHappinessChart(List<CaaTraversalData> history) {
new Object[]{happyGenerationsCounter}, Locale.getDefault());
PieChart.Data happyGenerations = new PieChart.Data(happyGenerationsCounterName, happyGenerationsCounter);
String sadGenerationsCounterName = messageSource.getMessage("experiment.results.sad.generations",
new Object[]{happyGenerationsCounter}, Locale.getDefault());
new Object[]{sadGenerationsCounter}, Locale.getDefault());
PieChart.Data sadGenerations = new PieChart.Data(sadGenerationsCounterName, sadGenerationsCounter);
ObservableList<PieChart.Data> pieChartData =
observableArrayList(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ public void setGraphData(CaaGraph caaGraph, PreferencesRepository preferencesRep

List<String> otherVertices = caaGraph.getAllVertices().stream()
.filter(v -> !caaGraph.getSad().contains(v) && !caaGraph.getHappy().contains(v)).collect(Collectors.toList());
String title = messageSource.getMessage("graph.details.chart.title", null, Locale.getDefault());
verticesTypesChart.setTitle(title);
String happyDataTitle = messageSource.getMessage("graph.details.chart.data.happy",
new Object[]{caaGraph.getHappy().size()}, Locale.getDefault());
String sadDataTitle = messageSource.getMessage("graph.details.chart.data.sad",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ public class TopMenuController {
@FXML
public MenuItem saveResultsItem;

@FXML
public CheckMenuItem viewShortestPathsItem;

public TopMenuController(ApplicationContext context,
RecentFilesRepository recentFilesRepository) {
this.context = context;
Expand All @@ -59,6 +62,7 @@ public void openGraphFile(ActionEvent event) {
if (chosenGraphFile != null) {
this.context.publishEvent(new OpenGraphEvent(chosenGraphFile));
this.addAllRecentFilesToMenu();
viewShortestPathsItem.setSelected(false);
}
}

Expand Down Expand Up @@ -121,7 +125,7 @@ public void animateCaaExperiment() {
}

@FXML
public void viewShortestPaths(ActionEvent event) {
public void viewShortestPath(ActionEvent event) {
CheckMenuItem source = (CheckMenuItem) event.getSource();
this.context.publishEvent(new GraphShortestPathEvent(source.isSelected()));
}
Expand Down Expand Up @@ -157,6 +161,7 @@ private Function<String, MenuItem> toRecentFileMenu() {
menuItem.setOnAction(action -> {
if (f.endsWith(".graphml")) {
this.context.publishEvent(new OpenGraphEvent(chosenFile));
viewShortestPathsItem.setSelected(false);
} else if (f.endsWith(".json")) {
this.context.publishEvent(new OpenResultsEvent(chosenFile));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,29 @@ public OpenResultsListener(RecentFilesRepository recentFilesRepository,
public void onApplicationEvent(OpenResultsEvent event) {
try {
CaaExperimentData caaExperimentData = caaExperimentDataService.loadExperimentData(event.getFile());
// /* NOTE: Applies for generating data in the master document. */
// String content = getContent(caaExperimentData);
// new TextAlert("Results", event.getFile().getName(), content).show();
Tab newTab = workspaceController.newResultsPane(caaExperimentData, event.getFile().getName());
workspaceController.workspace.getTabs().add(newTab);
recentFilesRepository.add(event.getFile().getAbsolutePath());
} catch (Exception anyException) {
recentFilesRepository.remove(event.getFile().getAbsolutePath());
}
}

// /* NOTE: Applies for generating data in the master document. */
// private String getContent(CaaExperimentData caaExperimentData) {
// StringBuilder builder = new StringBuilder();
// final CaaExperimentResults results = caaExperimentData.getResults();
// builder.append("30|").append(join(toSimpleCaaEdgeList(results.getPathToHappyState()), ",")).append("|");
// builder.append(results.getPathToHappyState().size()).append("|");
// builder.append(String.format("%.2f", results.getHappyToShortestPathFactor() * 100)).append("%\n");
// builder.append("|||\n");
// return builder.toString();
// }

// private static List<SimpleCaaEdge> toSimpleCaaEdgeList(List<? extends CaaEdge> caaEdges){
// return caaEdges.stream().map(SimpleCaaEdge::new).collect(Collectors.toList());
// }
}
40 changes: 22 additions & 18 deletions caa-experimentation-gui/src/main/resources/fxml/graph-details.fxml
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>


<?import javafx.geometry.Insets?>
<?import javafx.scene.chart.PieChart?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<HBox xmlns:fx="http://javafx.com/fxml/1" prefHeight="647.0" prefWidth="875.0" xmlns="http://javafx.com/javafx/11.0.1"
<?import javafx.scene.text.Font?>
<HBox xmlns:fx="http://javafx.com/fxml/1" prefHeight="972.0" prefWidth="526.0" xmlns="http://javafx.com/javafx/11.0.1"
fx:controller="com.mtanevski.master.caa.gui.controllers.GraphDetailsController">
<VBox alignment="CENTER_LEFT" prefHeight="410.0" prefWidth="500.0" spacing="20.0" HBox.hgrow="ALWAYS">
<VBox alignment="CENTER" prefHeight="942.0" prefWidth="513.0" spacing="20.0" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets bottom="10.0" left="20.0" right="10.0" top="20.0"/>
</HBox.margin>
<Label text="%graph.details.starting.vertex"/>
<TextField fx:id="startingVertexText" editable="false"/>
<Label text="%graph.details.happy.vertices"/>
<TextField fx:id="happyVerticesText" editable="false"/>
<Label text="%graph.details.sad.vertices"/>
<TextField fx:id="sadVerticesText" editable="false"/>
<Label text="%graph.details.all.vertices"/>
<TextField fx:id="verticesText" editable="false"/>
<Label text="%graph.details.all.edges"/>
<fx:include fx:id="edgesTableView" source="edges-table.fxml"/>
<Label text="%graph.details.title" VBox.vgrow="NEVER">
<font>
<Font size="18.0"/>
</font>
<VBox.margin>
<Insets bottom="10.0"/>
</VBox.margin>
</Label>
<PieChart fx:id="verticesTypesChart" VBox.vgrow="ALWAYS"/>
<Label text="%graph.details.starting.vertex" VBox.vgrow="NEVER"/>
<TextField fx:id="startingVertexText" editable="false" VBox.vgrow="NEVER"/>
<Label text="%graph.details.happy.vertices" VBox.vgrow="NEVER"/>
<TextField fx:id="happyVerticesText" editable="false" VBox.vgrow="NEVER"/>
<Label text="%graph.details.sad.vertices" VBox.vgrow="NEVER"/>
<TextField fx:id="sadVerticesText" editable="false" VBox.vgrow="NEVER"/>
<Label text="%graph.details.all.vertices" VBox.vgrow="NEVER"/>
<TextField fx:id="verticesText" editable="false" VBox.vgrow="NEVER"/>
<Label text="%graph.details.all.edges" VBox.vgrow="NEVER"/>
<fx:include fx:id="edgesTableView" source="edges-table.fxml" VBox.vgrow="ALWAYS"/>
</VBox>
<PieChart fx:id="verticesTypesChart" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
</HBox.margin>
</PieChart>
</HBox>
Loading

0 comments on commit 47bc4ef

Please sign in to comment.