diff --git a/src/main/java/net/berack/upo/ai/decision/PrototypeGUI.java b/src/main/java/net/berack/upo/ai/decision/PrototypeGUI.java index 25a2609..b361309 100644 --- a/src/main/java/net/berack/upo/ai/decision/PrototypeGUI.java +++ b/src/main/java/net/berack/upo/ai/decision/PrototypeGUI.java @@ -1,20 +1,35 @@ package net.berack.upo.ai.decision; import javax.swing.JMenu; +import javax.swing.JMenuItem; -import net.berack.upo.ai.MyPanel; +import net.berack.upo.ai.gui.MyDecisionPanel; +import net.berack.upo.ai.problem3.SmileLib; /** * Classe che mostra le decisioni possibili, insieme ai guadagni * per la rete Prototipo.xdsl * @author Berack */ -public class PrototypeGUI extends MyPanel { +public class PrototypeGUI extends MyDecisionPanel { + + private static final String PROTOTIPO = "Prototipo.xdsl"; + private static final String[] NODES = new String[] { + "Effettuare_la_Ricerca", "Ricerca_di_Mercato", + "Migliorare_la_Qualità", "Produzione", + "Valore_Profitto", + }; + + public PrototypeGUI() { + super(SmileLib.getNetworkFrom(PROTOTIPO), NODES); + } @Override public JMenu getMenu() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getMenu'"); + var menu = new JMenu("Network"); + var item = new JMenuItem("Reset"); + item.addActionListener(a -> { this.net.clearAllEvidence(); this.updateAll(); }); + menu.add(item); + return menu; } - } diff --git a/src/main/java/net/berack/upo/ai/decision/VehicleGUI.java b/src/main/java/net/berack/upo/ai/decision/VehicleGUI.java index e878118..0c56dbd 100644 --- a/src/main/java/net/berack/upo/ai/decision/VehicleGUI.java +++ b/src/main/java/net/berack/upo/ai/decision/VehicleGUI.java @@ -2,18 +2,33 @@ package net.berack.upo.ai.decision; import javax.swing.JMenu; -import net.berack.upo.ai.MyPanel; +import net.berack.upo.ai.gui.MyDecisionPanel; +import net.berack.upo.ai.problem3.SmileLib; /** * Classe che mostra le decisioni possibili, insieme ai guadagni * per la rete Veicolo.xdsl + * @author Berack */ -public class VehicleGUI extends MyPanel { +public class VehicleGUI extends MyDecisionPanel { + + private static final String VEICOLO = "Veicolo unrolled.xdsl"; + private static final String[] NODES = new String[] { + "Sensore_Posizione", "Comando", + "Sensore_Posizione_1", "Comando_1", + "Sensore_Posizione_2", "Comando_2", + "Sensore_Posizione_3", "Comando_3", + "Sensore_Posizione_4", "Comando_4", + "Somma_Utilità" + }; + + public VehicleGUI() { + super(SmileLib.getNetworkFrom(VEICOLO), NODES); + } @Override public JMenu getMenu() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getMenu'"); + return null; } } diff --git a/src/main/java/net/berack/upo/ai/MainGUI.java b/src/main/java/net/berack/upo/ai/gui/MainGUI.java similarity index 77% rename from src/main/java/net/berack/upo/ai/MainGUI.java rename to src/main/java/net/berack/upo/ai/gui/MainGUI.java index bc17a0f..00123e2 100644 --- a/src/main/java/net/berack/upo/ai/MainGUI.java +++ b/src/main/java/net/berack/upo/ai/gui/MainGUI.java @@ -1,9 +1,12 @@ -package net.berack.upo.ai; +package net.berack.upo.ai.gui; + +import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; +import javax.swing.JScrollPane; import javax.swing.JSeparator; import net.berack.upo.ai.decision.PrototypeGUI; @@ -19,16 +22,16 @@ import net.berack.upo.ai.problem3.LikelihoodWeightingGUI; */ public class MainGUI extends JFrame { + public static void main(String[] args) { + new MainGUI(); + } + public final Puzzle8GUI Puzzle8GUI = new Puzzle8GUI(); public final TrisGUI TrisGUI = new TrisGUI(); public final LikelihoodWeightingGUI LikelihoodWeightingGUI = new LikelihoodWeightingGUI(); public final PrototypeGUI PrototypeGUI = new PrototypeGUI(); public final VehicleGUI VehicleGUI = new VehicleGUI(); - public static void main(String[] args) { - new MainGUI(); - } - private final JMenuBar menuBar = new JMenuBar(); /** @@ -41,7 +44,7 @@ public class MainGUI extends JFrame { this.setJMenuBar(menuBar); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - this.setSize(400, 400); + this.setSize(500, 400); this.setResizable(false); this.setLocationRelativeTo(null); this.setVisible(true); @@ -74,16 +77,29 @@ public class MainGUI extends JFrame { menu.add(vehicle); menuBar.add(menu); - for(var m : menus) menuBar.add(m); + for(var m : menus) if(m != null) menuBar.add(m); } /** * Cambia il pannello principale con quello passato in input + * Nel caso sia un pannello MyDecision allora mette anche uno scroll panel per far si che si + * possano vedere tutti i nodi necessari * @param panel il pannello da mostrare */ private void setPanel(MyPanel panel) { - this.setContentPane(panel); + if(panel instanceof MyDecisionPanel) { + var scroll = new JScrollPane(panel); + scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scroll.getVerticalScrollBar().setUnitIncrement(20); + scroll.setPreferredSize(new Dimension(500, 400)); + this.setContentPane(scroll); + } + else this.setContentPane(panel); + this.buildMenu(panel.getMenu()); + panel.updateAll(); + this.pack(); this.invalidate(); this.validate(); diff --git a/src/main/java/net/berack/upo/ai/gui/MyDecisionPanel.java b/src/main/java/net/berack/upo/ai/gui/MyDecisionPanel.java new file mode 100644 index 0000000..8fae2df --- /dev/null +++ b/src/main/java/net/berack/upo/ai/gui/MyDecisionPanel.java @@ -0,0 +1,94 @@ +package net.berack.upo.ai.gui; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.BorderFactory; +import javax.swing.GroupLayout; +import javax.swing.JTextArea; + +import net.berack.upo.ai.gui.nodes.NodeGUI; +import net.berack.upo.ai.gui.nodes.NodeGUIFactory; +import smile.Network; + +/** + * Classe creata per espandere la classe MyPanel aggiungendo la possibilità di mostrare + * a schermo una rete e dei suoi nodi passati in input. + * Il costruttore costruisce automaticamente i nodi indicati ma non ne mostra i valori. + * Per farlo bisognerà utilizzare il metodo updateAll() appena creato il pannello. + * NOTA: updateAll() richiama il metodo della rete updateBeliefs() che può essere lento con molti nodi. + * @author Berack + */ +public abstract class MyDecisionPanel extends MyPanel { + + public final Network net; + private final List update = new ArrayList<>(); + + /** + * Costruisce il dinamicamente da una rete e da una lista di nodi da mostrare. + * Il risultato sarà già inserito nel pannello e per vedere i valori bisognerà utilizzare il metodo updateAll() + * @param net la rete da mostrare + * @param nodes il sottoinsieme di nodi da mostrare + */ + protected MyDecisionPanel(Network net, String...nodes) { + this.net = net; + var layout = new GroupLayout(this); + + var size = new Dimension(500, 400); + this.setSize(size); + this.setLayout(layout); + layout.setAutoCreateGaps(true); + + var factory = new NodeGUIFactory(net, () -> this.updateAll()); + var gLabel = layout.createParallelGroup(); + var gBarch = layout.createParallelGroup(); + var vGroup = layout.createSequentialGroup(); + + for(var node: nodes) { + var handle = net.getNode(node); + var panel = factory.create(handle); + update.add(panel); + + var label = new JTextArea(net.getNodeName(handle)); + label.setEditable(false); + label.setLineWrap(true); + label.setWrapStyleWord(true); + label.setOpaque(false); + label.setBorder(BorderFactory.createEmptyBorder()); + this.setFont(label); + + gLabel.addComponent(label); + gBarch.addComponent(panel); + vGroup.addGroup(layout.createParallelGroup() + .addComponent(label) + .addComponent(panel)); + } + + var hGroup = layout.createSequentialGroup(); + hGroup.addGroup(gLabel).addGroup(gBarch); + + layout.setVerticalGroup(vGroup); + layout.setHorizontalGroup(hGroup); + } + + /** + * Utile per cambiare il font in BOLD e aumentarne la grandezza + * @param component il componente da cambiare il font + */ + private void setFont(Component component) { + var font = component.getFont(); + font = new Font(font.getName(), Font.BOLD, font.getSize() + 2); + component.setFont(font); + } + + @Override + public void updateAll() { + net.updateBeliefs(); + + for (var node : update) + node.updateNode(); + } +} diff --git a/src/main/java/net/berack/upo/ai/MyPanel.java b/src/main/java/net/berack/upo/ai/gui/MyPanel.java similarity index 65% rename from src/main/java/net/berack/upo/ai/MyPanel.java rename to src/main/java/net/berack/upo/ai/gui/MyPanel.java index e2326b3..ac26903 100644 --- a/src/main/java/net/berack/upo/ai/MyPanel.java +++ b/src/main/java/net/berack/upo/ai/gui/MyPanel.java @@ -1,4 +1,4 @@ -package net.berack.upo.ai; +package net.berack.upo.ai.gui; import javax.swing.JMenu; import javax.swing.JPanel; @@ -17,4 +17,11 @@ public abstract class MyPanel extends JPanel { * @return il menu contestuale da aggiungere */ abstract public JMenu getMenu(); + + /** + * Permette di fare l'update di qualunque componente interno del pannello. + * Questo verrà utilizzato quando il pannello verrà mostrato in modo da + * disegnare correttamente il pannello. + */ + abstract public void updateAll(); } diff --git a/src/main/java/net/berack/upo/ai/gui/nodes/DecisionNodeGUI.java b/src/main/java/net/berack/upo/ai/gui/nodes/DecisionNodeGUI.java new file mode 100644 index 0000000..7b247a5 --- /dev/null +++ b/src/main/java/net/berack/upo/ai/gui/nodes/DecisionNodeGUI.java @@ -0,0 +1,86 @@ +package net.berack.upo.ai.gui.nodes; + +import java.awt.Font; +import java.awt.GridLayout; +import java.util.function.Consumer; + +import javax.swing.AbstractButton; +import javax.swing.ButtonGroup; +import javax.swing.JCheckBox; +import javax.swing.JLabel; + +import smile.Network; + +/** + * La rappresentazione grafica di un nodo a decisione. + * Esso mostrerà gli outcome e i valori associati ad essi, e permetterà di sceglierne uno o l'altro. + * Nel caso in cui ci siano più valori per outcome allora il nodo non sarà abilitato + * @author Berack + */ +public class DecisionNodeGUI extends NodeGUI { + + private final AbstractButton[] buttons; + private final JLabel[] values; + private final ButtonGroup group; + + /** + * Costruisce il nodo decisionale in modo che si possa interagire con esso + * @param net la rete del nodo + * @param node il nodo + * @param action la azione da fare quando si preme su una decisione + */ + public DecisionNodeGUI(Network net, int node, Consumer action) { + super(net, node); + + var outcomes = net.getOutcomeCount(node); + this.buttons = new AbstractButton[outcomes]; + this.values = new JLabel[outcomes]; + + this.group = new ButtonGroup(); + var grid = new GridLayout(outcomes, 2); + this.setLayout(grid); + + for(var i = 0; i < outcomes; i++) { + final var index = i; + var label = net.getOutcomeId(node, i); + var value = new JLabel(); + var button = new JCheckBox(label); + button.setContentAreaFilled(false); + button.setFocusable(false); + button.addActionListener(a -> action.accept(index)); + + this.buttons[i] = button; + this.values[i] = value; + this.add(button); + this.add(value); + this.group.add(button); + } + } + + @Override + public void updateNode() { + var selected = this.net.isEvidence(this.node)? this.net.getEvidence(this.node) : -1; + var values = this.net.getNodeValue(this.node); + var max = -1; + if(values.length == this.buttons.length) { + max = 0; + for(int i = 1; i < values.length; i++) + if(values[max] < values[i]) + max = i; + } + + this.group.clearSelection(); + + for(var i = 0; i < this.buttons.length; i++) { + var font = buttons[i].getFont(); + var style = (i == max)? (Font.BOLD + Font.ITALIC) : Font.PLAIN; + var newFont = new Font(font.getName(), style, font.getSize()); + var value = max < 0? "" : String.format("% 5.2f", values[i]); + + this.buttons[i].setFont(newFont); + this.buttons[i].setSelected(i == selected); + this.buttons[i].setEnabled(max != -1); + this.values[i].setText(value); + } + } +} diff --git a/src/main/java/net/berack/upo/ai/gui/nodes/NodeGUI.java b/src/main/java/net/berack/upo/ai/gui/nodes/NodeGUI.java new file mode 100644 index 0000000..e87c8b0 --- /dev/null +++ b/src/main/java/net/berack/upo/ai/gui/nodes/NodeGUI.java @@ -0,0 +1,35 @@ +package net.berack.upo.ai.gui.nodes; + +import javax.swing.JPanel; + +import smile.Network; + +/** + * Classe astratta che implementa un nodo base data la rete in input. + * @author Berack + */ +public abstract class NodeGUI extends JPanel { + + public final Network net; + public final int node; + + /** + * Salva informazioni essenziali del nodo + * I costruttori delle sottoclassi dovranno creare il contenuto del pannello + * ed utilizzare questo costruttore. + * I valori passati saranno poi disponibili alle proprietà pubbliche net e node. + * + * @param net la rete a cui appartiene + * @param node il valore dell'handle + */ + protected NodeGUI(Network net, int node) { + this.net = net; + this.node = node; + } + + /** + * In questo metodo si deve fare un refresh dei valori mostrati nel pannello. + * I valori potranno essere presi direttamente dalla rete utilizzando le proprietà pubbliche net e node. + */ + abstract public void updateNode(); +} diff --git a/src/main/java/net/berack/upo/ai/gui/nodes/NodeGUIFactory.java b/src/main/java/net/berack/upo/ai/gui/nodes/NodeGUIFactory.java new file mode 100644 index 0000000..4fc1c98 --- /dev/null +++ b/src/main/java/net/berack/upo/ai/gui/nodes/NodeGUIFactory.java @@ -0,0 +1,54 @@ +package net.berack.upo.ai.gui.nodes; + +import java.util.function.Consumer; + +import smile.Network; +import smile.Network.NodeType; + +/** + * Classe che raggruppa tutte le rappresentazioni grafiche dei nodi. + * È una classe comoda per la creazione dei nodi dato che crea automaticamente + * anche la funzione di update e scelta della evidenza per ogni nodo. + * @author Berack + */ +public class NodeGUIFactory { + + private final Network net; + private final Runnable updateAll; + + /** + * Crea una factory pronta per la creazione dei nodi + * @param net la rete + * @param updateAll una funzione richiesta per l'update di tutti gli altri nodi + */ + public NodeGUIFactory(Network net, Runnable updateAll) { + this.net = net; + this.updateAll = updateAll; + } + + /** + * Crea una nuova rappresentazione grafica di un nodo passato in input. + * + * @throws IllegalArgumentException nel caso in cui il nodo non sia ancora supportato + * @param handle il nodo + * @return la rappresentazione grafica del nodo + */ + public NodeGUI create(int handle) { + Consumer action = outcome -> { + if(net.isEvidence(handle) && net.getEvidence(handle) == outcome) this.net.clearEvidence(handle); + else this.net.setEvidence(handle, outcome); + + this.updateAll.run(); + }; + + return switch(net.getNodeType(handle)) { + case NodeType.DECISION -> new DecisionNodeGUI(net, handle, action); + case NodeType.UTILITY -> new UtilityNodeGUI(net, handle); + case NodeType.MAU -> new UtilityNodeGUI(net, handle); + case NodeType.NOISY_MAX -> new ProbabilityNodeGUI(net, handle, action); + case NodeType.CPT -> new ProbabilityNodeGUI(net, handle, action); + + default -> throw new IllegalArgumentException("Node type not supported! "); + }; + } +} diff --git a/src/main/java/net/berack/upo/ai/gui/nodes/ProbabilityNodeGUI.java b/src/main/java/net/berack/upo/ai/gui/nodes/ProbabilityNodeGUI.java new file mode 100644 index 0000000..0c9d1fd --- /dev/null +++ b/src/main/java/net/berack/upo/ai/gui/nodes/ProbabilityNodeGUI.java @@ -0,0 +1,114 @@ +package net.berack.upo.ai.gui.nodes; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.GridLayout; +import java.awt.Label; +import java.util.function.Consumer; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; + +import smile.Network; + +/** + * La rappresentazione grafica di un nodo probabilistico. + * Esso mostrerà gli outcome ele probabilità associate ad essi, e permetterà di sceglierne uno o l'altro. + * Nel caso in cui ci siano più valori per outcome allora il nodo non sarà abilitato + * @author Berack + */ +public class ProbabilityNodeGUI extends NodeGUI { + + public static final Color[] COLORS = { + new Color(255,127,0), + new Color(0,127,255), + new Color(0,255,127), + new Color(255,0,127), + new Color(127,0,255), + new Color(127,255,0), + }; + + private final JButton[] outcomes; + private final Label[] valuesChart; + private final JLabel[] valuesPercent; + + /** + * Costruisce il nodo probabilistico in modo che si possa interagire con esso + * @param net la rete del nodo + * @param node il nodo + * @param action la azione da fare quando si preme su un outcome + */ + public ProbabilityNodeGUI(Network net, int node, Consumer action) { + super(net, node); + var labels = net.getOutcomeIds(node); + + var layout = new GridLayout(labels.length, 2); + this.setLayout(layout); + this.setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(1, 0, 0, 0), BorderFactory.createLineBorder(Color.GRAY))); + + this.outcomes = new JButton[labels.length]; + this.valuesChart = new Label[labels.length]; + this.valuesPercent = new JLabel[labels.length]; + + for(var i = 0; i < labels.length; i++) { + var lName = new JButton(labels[i]); + var lValue = new JLabel(); + var barchart = new Label(); + + this.outcomes[i] = lName; + this.valuesChart[i] = barchart; + this.valuesPercent[i] = lValue; + + final var index = i; + lName.setContentAreaFilled(false); + lName.setFocusable(false); + if(action == null) lName.setBorder(null); + else lName.addActionListener(a -> action.accept(index)); + + var size = barchart.getPreferredSize(); + size.width = 100; + size.height = 10; + barchart.setPreferredSize(size); + barchart.setBackground(COLORS[i % COLORS.length]); + + + var panel1 = new JPanel(); + panel1.setLayout(new GridLayout(1, 2)); + panel1.add(lName); + panel1.add(lValue); + + var panel2 = new JPanel(); + panel2.setLayout(new BorderLayout()); + panel2.add(barchart, BorderLayout.LINE_START); + + this.add(panel1); + this.add(panel2); + } + } + + @Override + public void updateNode() { + var values = this.net.getNodeValue(this.node); + var evidence = this.net.isEvidence(this.node)? this.net.getEvidence(node) : -1; + var enable = (values.length == this.outcomes.length); + + for(var i = 0; i < this.outcomes.length; i++) { + var value = values[i] * 100; + var barchart = this.valuesChart[i]; + + var size = barchart.getPreferredSize(); + size.width = enable? (int) (value * 1.5) : 0; + barchart.setSize(size); + barchart.setPreferredSize(size); + + this.valuesPercent[i].setText(enable? String.format("% 4.2f%%", value) : " "); + if(evidence == i) this.outcomes[i].setForeground(Color.RED); + else this.outcomes[i].setForeground(Color.BLACK); + this.outcomes[i].setEnabled(enable); + } + } + +} diff --git a/src/main/java/net/berack/upo/ai/gui/nodes/UtilityNodeGUI.java b/src/main/java/net/berack/upo/ai/gui/nodes/UtilityNodeGUI.java new file mode 100644 index 0000000..cfa837d --- /dev/null +++ b/src/main/java/net/berack/upo/ai/gui/nodes/UtilityNodeGUI.java @@ -0,0 +1,47 @@ +package net.berack.upo.ai.gui.nodes; + +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.Font; + +import javax.swing.JLabel; + +import smile.Network; + +/** + * La rappresentazione grafica di un nodo utilità. + * Esso mostrerà il valore solamente nel caso in cui esso sia l'unico. + * @author Berack + */ +public class UtilityNodeGUI extends NodeGUI { + + private final JLabel utility; + + /** + * Costruisce il nodo utilità che mostra il valore corrente + * @param net la rete del nodo + * @param node il nodo + */ + UtilityNodeGUI(Network net, int node) { + super(net, node); + + this.utility = new JLabel(); + var font = this.utility.getFont(); + font = new Font(font.getName(), Font.BOLD, font.getSize() + 5); + + this.setLayout(new FlowLayout()); + + this.utility.setFont(font); + this.utility.setForeground(Color.RED); + + this.add(utility); + } + + @Override + public void updateNode() { + var values = this.net.getNodeValue(this.node); + var val = (values.length == 1) ? String.format("% 5.2f", values[0]) : " "; + this.utility.setText(val); + } + +} diff --git a/src/main/java/net/berack/upo/ai/problem1/Puzzle8GUI.java b/src/main/java/net/berack/upo/ai/problem1/Puzzle8GUI.java index aae3017..c1d81cd 100644 --- a/src/main/java/net/berack/upo/ai/problem1/Puzzle8GUI.java +++ b/src/main/java/net/berack/upo/ai/problem1/Puzzle8GUI.java @@ -10,7 +10,7 @@ import javax.swing.JButton; import javax.swing.JMenu; import javax.swing.JMenuItem; -import net.berack.upo.ai.MyPanel; +import net.berack.upo.ai.gui.MyPanel; import net.berack.upo.ai.problem1.Puzzle8.Move; /** @@ -67,7 +67,8 @@ public class Puzzle8GUI extends MyPanel { */ public void shuffleGame() { do { this.puzzle.shuffle(); } while(!this.puzzle.isSolvable()); - redraw(); + this.solution.clear(); + this.updateAll(); } /** @@ -77,7 +78,7 @@ public class Puzzle8GUI extends MyPanel { */ public void solveGame() { this.solution = this.puzzle.solve(); - this.redraw(); + this.updateAll(); } /** @@ -86,7 +87,8 @@ public class Puzzle8GUI extends MyPanel { * allora verrà evidenziata una tessera con il colore rosso per indicare * la mossa migliore da fare per la risoluzione. */ - public void redraw() { + @Override + public void updateAll() { MyComponent zero = null; for(var arr: this.buttons) { @@ -101,7 +103,7 @@ public class Puzzle8GUI extends MyPanel { } } - higlightNextMove(zero); + this.higlightNextMove(zero); } /** @@ -155,7 +157,7 @@ public class Puzzle8GUI extends MyPanel { if(solution.size() > 0 && solution.remove(0) != move) solution.clear(); - redraw(); + updateAll(); }); } } diff --git a/src/main/java/net/berack/upo/ai/problem2/TrisGUI.java b/src/main/java/net/berack/upo/ai/problem2/TrisGUI.java index fb7ce32..e80bf7d 100644 --- a/src/main/java/net/berack/upo/ai/problem2/TrisGUI.java +++ b/src/main/java/net/berack/upo/ai/problem2/TrisGUI.java @@ -11,7 +11,7 @@ import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JSeparator; -import net.berack.upo.ai.MyPanel; +import net.berack.upo.ai.gui.MyPanel; /** * Classe che permette di visualizzare graficamente il gioco Tris @@ -72,14 +72,15 @@ public class TrisGUI extends MyPanel { this.tris = new Tris(); this.ai = this.ai == null? null:new TrisAi(this.tris); if(this.ai != null && aiFirst.getState()) this.ai.playNext(); - redraw(); + this.updateAll(); } /** * Dopo questo metodo la finestra verrà ridisegnata (sempre se ci sono stati dei cambiamenti) * Nel caso in cui ci sia un vincitore il tris verrà colorato di rosso */ - public void redraw() { + @Override + public void updateAll() { for(var arr: this.buttons) { for(var button: arr) { var value = tris.get(button.x, button.y); @@ -128,7 +129,7 @@ public class TrisGUI extends MyPanel { if(tris.isPlayAvailable(x, y) && !tris.isFinished()) { tris.play(x, y); if(ai != null && !tris.isFinished()) ai.playNext(); - redraw(); + updateAll(); } }); } diff --git a/src/main/java/net/berack/upo/ai/problem3/LikelihoodWeightingGUI.java b/src/main/java/net/berack/upo/ai/problem3/LikelihoodWeightingGUI.java index ff664a4..1cfb2e4 100644 --- a/src/main/java/net/berack/upo/ai/problem3/LikelihoodWeightingGUI.java +++ b/src/main/java/net/berack/upo/ai/problem3/LikelihoodWeightingGUI.java @@ -7,14 +7,16 @@ import java.util.Collection; import javax.swing.BorderFactory; import javax.swing.GroupLayout; +import javax.swing.JComboBox; import javax.swing.JFrame; +import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.JTextArea; -import net.berack.upo.ai.MyPanel; +import net.berack.upo.ai.gui.MyPanel; /** * Classe usata per far vedere il risultato di una run di lw su un network @@ -26,7 +28,7 @@ public class LikelihoodWeightingGUI extends MyPanel { private OutcomeChartGUI[] chartGUI = null; private final JPanel scroll = new JPanel(); // tried using JScrollPane but nothing shows up - private final int totalRuns = 1000; + private int totalRuns = 1000; /** * Crea il pannello con gli elementi di default. @@ -65,7 +67,7 @@ public class LikelihoodWeightingGUI extends MyPanel { var net = SmileLib.getNetworkFrom(fileName); this.lw = new LikelihoodWeighting(net); this.chartGUI = null; - this.updateLW(); + this.updateAll(); } catch (Exception e) { e.printStackTrace(); } @@ -74,7 +76,10 @@ public class LikelihoodWeightingGUI extends MyPanel { /** * Esegue l'algoritmo sul network corrente e mostra i risultati */ - private void updateLW() { + @Override + public void updateAll() { + if(this.lw == null) return; + this.lw.updateNetwork(totalRuns); var nodes = this.lw.getAllNodes(); @@ -103,6 +108,20 @@ public class LikelihoodWeightingGUI extends MyPanel { var gBarch = layout.createParallelGroup(); var vGroup = layout.createSequentialGroup(); + var totLabel = new JLabel("Total Runs"); + var totValue = new JComboBox<>(new Integer[] {this.totalRuns, 5 * this.totalRuns, 10 * this.totalRuns, 20 * this.totalRuns}); + totValue.addItemListener(a -> this.totalRuns = (Integer) totValue.getSelectedItem()); + + var font = totLabel.getFont(); + font = new Font(font.getName(), Font.BOLD, font.getSize() + 2); + totLabel.setFont(font); + + gLabel.addComponent(totLabel); + gBarch.addComponent(totValue); + vGroup.addGroup(layout.createParallelGroup() + .addComponent(totLabel) + .addComponent(totValue)); + this.chartGUI = new OutcomeChartGUI[nodes.size()]; var i = 0; @@ -121,11 +140,11 @@ public class LikelihoodWeightingGUI extends MyPanel { if(net.isEvidence(handle) && net.getEvidence(handle) == e) net.clearEvidence(handle); else net.setEvidence(handle, e); - this.updateLW(); + this.updateAll(); }); this.chartGUI[i++] = barch; - var font = label.getFont(); + font = label.getFont(); font = new Font(font.getName(), Font.BOLD, font.getSize() + 2); label.setFont(font); diff --git a/src/main/resources/Prototipo.xdsl b/src/main/resources/Prototipo.xdsl index a646bfa..be6a54b 100644 --- a/src/main/resources/Prototipo.xdsl +++ b/src/main/resources/Prototipo.xdsl @@ -6,7 +6,7 @@ - + Effettuare_la_Ricerca @@ -14,7 +14,7 @@ - Migliorare_la_Qualià + Migliorare_la_Qualità 0.15 0.85 0.5 0.5 @@ -27,24 +27,25 @@ -1000 0 - Migliorare_la_Qualià + Migliorare_la_Qualità -5000 0 - - - + + + Domanda_Mercato Qualità_Prodotto - 0.99 0.008999999999999999 0.001 0.85 0.145 0.005 0.1 0.8 0.1 0.001 0.85 0.149 - + 1 0 1 0 + 0.9 0.099 0.001 0 0 1 0.7 0.27 0.03000000000000003 0 0 1 0.1 0.5 0.4 + - Migliorare_la_Qualià Effettuare_la_Ricerca + Migliorare_la_Qualità Effettuare_la_Ricerca - + Produzione Profitto - 0 10000 50000 0 0 0 + 50000 10000 0 0 0 0 @@ -56,6 +57,10 @@ Produzione -2500 0 + + Costo_di_Ricerca Costo_Prototipo Costo_Produzione Valore_Ricavo + 1 1 1 1 + @@ -84,8 +89,8 @@ 209 88 290 154 - - Migliorare la Qualià + + Migliorare la Qualità @@ -105,8 +110,8 @@ - 39 216 127 262 - + 36 216 124 262 + Profitto @@ -116,8 +121,8 @@ 600 228 651 259 - - Valore Profitto + + Valore Ricavo @@ -145,8 +150,16 @@ - 44 337 132 390 - + 37 339 125 392 + + + + Valore Profitto + + + + 28 458 138 539 + diff --git a/src/main/resources/Veicolo unrolled.xdsl b/src/main/resources/Veicolo unrolled.xdsl new file mode 100644 index 0000000..057946d --- /dev/null +++ b/src/main/resources/Veicolo unrolled.xdsl @@ -0,0 +1,706 @@ + + + + + + + + + 0 1 0 + + + + + 0.5 0.5 + + + + + 0.5 0.5 + + + + + Condizioni_Meteo Stato_Terreno + 1 0 1 0 + 0.1 0.9 0 1 0.5 0.5 0 1 0.001 0.999 + + + + + + Guasto Condizioni_Meteo Stato_Terreno + 0 1 1 0 1 0 + 1 0 0 0 0 1 0.3 0.15 0.5499999999999999 0 0 1 0.6 0.3 0.1 0 0 1 0.000299999999999967 0.0007 0.999 + + + + + + Accuratezza_Sensore Posizione + 0.35 0.325 0.325 0.325 0.35 0.325 0.325 0.325 0.35 0.9 0.05 0.05 0.05 0.8999999999999999 0.05 0.05 0.05 0.8999999999999999 0.99 0.005 0.005 0.005 0.99 0.005 0.005 0.005 0.99 + + + + + + Sensore_Posizione + + + Posizione + -100 100 -100 + + + + + Condizioni_Meteo + 0.9 0.1 0.1 0.9 + + + + + Condizioni_Meteo_1 + 0.9 0.1 0.1 0.9 + + + + + Condizioni_Meteo_2 + 0.9 0.1 0.1 0.9 + + + + + Condizioni_Meteo_3 + 0.9 0.1 0.1 0.9 + + + + + Stato_Terreno + 0.8 0.2 0.7 0.3 + + + + + Stato_Terreno_1 + 0.8 0.2 0.7 0.3 + + + + + Stato_Terreno_2 + 0.8 0.2 0.7 0.3 + + + + + Stato_Terreno_3 + 0.8 0.2 0.7 0.3 + + + + + Condizioni_Meteo_1 Stato_Terreno_1 Guasto + 1 0 1 0 0 1 + 0.1 0.9 0 1 0.5 0.5 0 1 1 0 0 1 0.001 0.999 + + + + + Condizioni_Meteo_2 Stato_Terreno_2 Guasto_1 + 1 0 1 0 0 1 + 0.1 0.9 0 1 0.5 0.5 0 1 1 0 0 1 0.001 0.999 + + + + + Condizioni_Meteo_3 Stato_Terreno_3 Guasto_2 + 1 0 1 0 0 1 + 0.1 0.9 0 1 0.5 0.5 0 1 1 0 0 1 0.001 0.999 + + + + + Condizioni_Meteo_4 Stato_Terreno_4 Guasto_3 + 1 0 1 0 0 1 + 0.1 0.9 0 1 0.5 0.5 0 1 1 0 0 1 0.001 0.999 + + + + + + Guasto_4 Condizioni_Meteo_4 Stato_Terreno_4 + 0 1 1 0 1 0 + 1 0 0 0 0 1 0.3 0.15 0.5499999999999999 0 0 1 0.6 0.3 0.1 0 0 1 0.000299999999999967 0.0007 0.999 + + + + + + Posizione Comando + 0.9 0.05 0.04999999999999998 0.9 0.05 0.05 0.05 0.9 0.05 0.9 0.05 0.05 0.04999999999999998 0.9 0.05 0.04999999999999993 0.05 0.9 0.05 0.9 0.05 0.05 0.05 0.9 0.05 0.05 0.9 + + + + + + Guasto_1 Condizioni_Meteo_1 Stato_Terreno_1 + 0 1 1 0 1 0 + 1 0 0 0 0 1 0.3 0.15 0.5499999999999999 0 0 1 0.6 0.3 0.1 0 0 1 0.000299999999999967 0.0007 0.999 + + + + + + Accuratezza_Sensore_1 Posizione_1 + 0.35 0.325 0.325 0.325 0.35 0.325 0.325 0.325 0.35 0.9 0.05 0.05 0.05 0.8999999999999999 0.05 0.05 0.05 0.8999999999999999 0.99 0.005 0.005 0.005 0.99 0.005 0.005 0.005 0.99 + + + + + + Sensore_Posizione_1 Comando + + + + + + Posizione_1 Comando_1 + 0.9 0.05 0.04999999999999998 0.9 0.05 0.05 0.05 0.9 0.05 0.9 0.05 0.05 0.04999999999999998 0.9 0.05 0.04999999999999993 0.05 0.9 0.05 0.9 0.05 0.05 0.05 0.9 0.05 0.05 0.9 + + + + + + Guasto_2 Condizioni_Meteo_2 Stato_Terreno_2 + 0 1 1 0 1 0 + 1 0 0 0 0 1 0.3 0.15 0.5499999999999999 0 0 1 0.6 0.3 0.1 0 0 1 0.000299999999999967 0.0007 0.999 + + + + + + Accuratezza_Sensore_2 Posizione_2 + 0.35 0.325 0.325 0.325 0.35 0.325 0.325 0.325 0.35 0.9 0.05 0.05 0.05 0.8999999999999999 0.05 0.05 0.05 0.8999999999999999 0.99 0.005 0.005 0.005 0.99 0.005 0.005 0.005 0.99 + + + + + + Sensore_Posizione_2 Comando_1 + + + + + + Posizione_2 Comando_2 + 0.9 0.05 0.04999999999999998 0.9 0.05 0.05 0.05 0.9 0.05 0.9 0.05 0.05 0.04999999999999998 0.9 0.05 0.04999999999999993 0.05 0.9 0.05 0.9 0.05 0.05 0.05 0.9 0.05 0.05 0.9 + + + + + + Guasto_3 Condizioni_Meteo_3 Stato_Terreno_3 + 0 1 1 0 1 0 + 1 0 0 0 0 1 0.3 0.15 0.5499999999999999 0 0 1 0.6 0.3 0.1 0 0 1 0.000299999999999967 0.0007 0.999 + + + + + + Accuratezza_Sensore_3 Posizione_3 + 0.35 0.325 0.325 0.325 0.35 0.325 0.325 0.325 0.35 0.9 0.05 0.05 0.05 0.8999999999999999 0.05 0.05 0.05 0.8999999999999999 0.99 0.005 0.005 0.005 0.99 0.005 0.005 0.005 0.99 + + + + + + Sensore_Posizione_3 Comando_2 + + + + + + Posizione_3 Comando_3 + 0.9 0.05 0.04999999999999998 0.9 0.05 0.05 0.05 0.9 0.05 0.9 0.05 0.05 0.04999999999999998 0.9 0.05 0.04999999999999993 0.05 0.9 0.05 0.9 0.05 0.05 0.05 0.9 0.05 0.05 0.9 + + + + + + Accuratezza_Sensore_4 Posizione_4 + 0.35 0.325 0.325 0.325 0.35 0.325 0.325 0.325 0.35 0.9 0.05 0.05 0.05 0.8999999999999999 0.05 0.05 0.05 0.8999999999999999 0.99 0.005 0.005 0.005 0.99 0.005 0.005 0.005 0.99 + + + + + + Sensore_Posizione_4 Comando_3 + + + + + + Comando_4 Posizione_4 + 0.9 0.05 0.04999999999999998 0.9 0.05 0.05 0.05 0.9 0.05 0.9 0.05 0.05 0.04999999999999998 0.9 0.05 0.04999999999999993 0.05 0.9 0.05 0.9 0.05 0.05 0.05 0.9 0.05 0.05 0.9 + + + Posizione_Finale + -100 100 -100 + + + Utilità + 1 + + + Posizione_4 + -100 100 -100 + + + Posizione_3 + -100 100 -100 + + + Posizione_2 + -100 100 -100 + + + Posizione_1 + -100 100 -100 + + + Utilità_1 Somma_Parziale + 1 1 + + + Utilità_2 Somma_Parziale_1 + 1 1 + + + Utilità_3 Somma_Parziale_2 + 1 1 + + + Utilità_4 Somma_Parziale_3 + 1 1 + + + Utilità_Finale Somma_Parziale_4 + 1 1 + + + + + + Posizione + + + + 232 386 308 432 + + + + Condizioni Meteo + + + + 140 47 231 103 + + + + Stato Terreno + + + + 314 180 392 228 + + + + Guasto + + + + 313 51 393 100 + + + + Accuratezza Sensore + + + + 142 179 228 229 + + + + Sensore Posizione + + + + 148 285 223 337 + + + + Comando + + + + 308 292 398 334 + + + + Utilità + + + + 234 507 305 551 + + + + Posizione Finale + + + + 2653 289 2729 335 + + + + Utilità Finale + + + + 2657 386 2728 430 + + + + Somma Parziale + + + + 430 513 509 545 + + + + Somma Utilità + + + + 2656 503 2729 551 + + + + Step0 + + 247 576 271 588 + + + Step1 + + 754 576 778 588 + + + Step2 + + 1261 576 1285 588 + + + Step3 + + 1768 576 1792 588 + + + Step4 + + 2275 576 2299 588 + + + Posizione (t=1) + + + + 739 406 815 452 + + + + Condizioni Meteo (t=1) + + + + 647 67 738 123 + + + + Stato Terreno (t=1) + + + + 821 200 899 248 + + + + Guasto (t=1) + + + + 820 71 900 120 + + + + Accuratezza Sensore (t=1) + + + + 649 199 735 249 + + + + Sensore Posizione (t=1) + + + + 655 305 730 357 + + + + Comando (t=1) + + + + 815 312 905 354 + + + + Utilità (t=1) + + + + 741 527 812 571 + + + + Somma Parziale (t=1) + + + + 937 533 1016 565 + + + + Posizione (t=2) + + + + 1246 386 1322 432 + + + + Condizioni Meteo (t=2) + + + + 1154 47 1245 103 + + + + Stato Terreno (t=2) + + + + 1328 180 1406 228 + + + + Guasto (t=2) + + + + 1327 51 1407 100 + + + + Accuratezza Sensore (t=2) + + + + 1156 179 1242 229 + + + + Sensore Posizione (t=2) + + + + 1162 285 1237 337 + + + + Comando (t=2) + + + + 1322 292 1412 334 + + + + Utilità (t=2) + + + + 1248 507 1319 551 + + + + Somma Parziale (t=2) + + + + 1444 513 1523 545 + + + + Posizione (t=3) + + + + 1753 406 1829 452 + + + + Condizioni Meteo (t=3) + + + + 1661 67 1752 123 + + + + Stato Terreno (t=3) + + + + 1835 200 1913 248 + + + + Guasto (t=3) + + + + 1834 71 1914 120 + + + + Accuratezza Sensore (t=3) + + + + 1663 199 1749 249 + + + + Sensore Posizione (t=3) + + + + 1669 305 1744 357 + + + + Comando (t=3) + + + + 1829 312 1919 354 + + + + Utilità (t=3) + + + + 1755 527 1826 571 + + + + Somma Parziale (t=3) + + + + 1951 533 2030 565 + + + + Posizione (t=4) + + + + 2260 386 2336 432 + + + + Condizioni Meteo (t=4) + + + + 2168 47 2259 103 + + + + Stato Terreno (t=4) + + + + 2342 180 2420 228 + + + + Guasto (t=4) + + + + 2341 51 2421 100 + + + + Accuratezza Sensore (t=4) + + + + 2170 179 2256 229 + + + + Sensore Posizione (t=4) + + + + 2176 285 2251 337 + + + + Comando (t=4) + + + + 2336 292 2426 334 + + + + Utilità (t=4) + + + + 2262 507 2333 551 + + + + Somma Parziale (t=4) + + + + 2458 513 2537 545 + + + + + diff --git a/src/main/resources/Veicolo.xdsl b/src/main/resources/Veicolo.xdsl index bd64e6e..ef5b3e7 100644 --- a/src/main/resources/Veicolo.xdsl +++ b/src/main/resources/Veicolo.xdsl @@ -57,10 +57,18 @@ Comando Posizione 0.9 0.05 0.04999999999999998 0.9 0.05 0.05 0.05 0.9 0.05 0.9 0.05 0.05 0.04999999999999998 0.9 0.05 0.04999999999999993 0.05 0.9 0.05 0.9 0.05 0.05 0.05 0.9 0.05 0.05 0.9 - + Posizione_Finale -100 100 -100 + + Utilità + 1 + + + Utilità_Finale Somma_Parziale + 1 1 + @@ -83,6 +91,10 @@ Comando + + Somma_Parziale + 1 1 + @@ -160,7 +172,7 @@ 625 289 701 335 - + Utilità Finale @@ -168,6 +180,20 @@ 629 386 700 430 + + Somma Parziale + + + + 430 513 509 545 + + + Somma Utilità + + + + 628 503 701 551 +