- gui no longer recreate itself every update
- fixed node name
- added another net
This commit is contained in:
2024-01-05 15:51:17 +01:00
parent c2cd4e3fb2
commit a0dd2dce2e
4 changed files with 194 additions and 35 deletions

View File

@@ -3,14 +3,16 @@ package net.berack.upo.ai.problem3;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.FileDialog; import java.awt.FileDialog;
import java.awt.Font; import java.awt.Font;
import java.util.Collection;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout; import javax.swing.GroupLayout;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu; import javax.swing.JMenu;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JSeparator; import javax.swing.JSeparator;
import javax.swing.JTextArea;
import net.berack.upo.ai.MyPanel; import net.berack.upo.ai.MyPanel;
@@ -21,8 +23,9 @@ import net.berack.upo.ai.MyPanel;
public class LikelihoodWeightingGUI extends MyPanel { public class LikelihoodWeightingGUI extends MyPanel {
private LikelihoodWeighting lw = null; private LikelihoodWeighting lw = null;
private OutcomeChartGUI[] chartGUI = null;
private final JPanel scroll = new JPanel(); private final JPanel scroll = new JPanel(); // tried using JScrollPane but nothing shows up
private final int totalRuns = 1000; private final int totalRuns = 1000;
/** /**
@@ -61,6 +64,7 @@ public class LikelihoodWeightingGUI extends MyPanel {
try { try {
var net = SmileLib.getNetworkFrom(fileName); var net = SmileLib.getNetworkFrom(fileName);
this.lw = new LikelihoodWeighting(net); this.lw = new LikelihoodWeighting(net);
this.chartGUI = null;
this.updateLW(); this.updateLW();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -72,8 +76,23 @@ public class LikelihoodWeightingGUI extends MyPanel {
*/ */
private void updateLW() { private void updateLW() {
this.lw.updateNetwork(totalRuns); this.lw.updateNetwork(totalRuns);
var nodes = this.lw.getAllNodes(); var nodes = this.lw.getAllNodes();
if(chartGUI == null) buildPanel(nodes);
var i = 0;
for(var node : nodes) chartGUI[i++].updateValues(node.values, node.evidence);
this.invalidate();
this.validate();
this.repaint();
}
/**
* Crea il pannello da zero usando i nodi passati in input come valori
* @param nodes i nodi da mostrare
*/
private void buildPanel(Collection<NetworkNode> nodes) {
var panel = new JPanel(); var panel = new JPanel();
var layout = new GroupLayout(panel); var layout = new GroupLayout(panel);
@@ -84,16 +103,31 @@ public class LikelihoodWeightingGUI extends MyPanel {
var gBarch = layout.createParallelGroup(); var gBarch = layout.createParallelGroup();
var vGroup = layout.createSequentialGroup(); var vGroup = layout.createSequentialGroup();
this.chartGUI = new OutcomeChartGUI[nodes.size()];
var i = 0;
for(var node : nodes) { for(var node : nodes) {
var label = new JLabel(node.name); var net = node.net;
var barch = new OutcomeChartGUI(node, i -> { var handle = node.handle;
if(node.evidence == i) node.net.clearEvidence(node.handle);
else node.net.setEvidence(node.handle, i); var label = new JTextArea(node.name);
label.setEditable(false);
label.setLineWrap(true);
label.setWrapStyleWord(true);
label.setOpaque(false);
label.setBorder(BorderFactory.createEmptyBorder());
var barch = new OutcomeChartGUI(node.outcomes, e -> {
if(net.isEvidence(handle) && net.getEvidence(handle) == e)
net.clearEvidence(handle);
else net.setEvidence(handle, e);
this.updateLW(); this.updateLW();
}); });
this.chartGUI[i++] = barch;
var font = label.getFont(); var font = label.getFont();
label.setFont(new Font(font.getName(), font.getStyle(), font.getSize() + 4)); font = new Font(font.getName(), Font.BOLD, font.getSize() + 2);
label.setFont(font);
gLabel.addComponent(label); gLabel.addComponent(label);
gBarch.addComponent(barch); gBarch.addComponent(barch);
@@ -108,13 +142,13 @@ public class LikelihoodWeightingGUI extends MyPanel {
layout.setVerticalGroup(vGroup); layout.setVerticalGroup(vGroup);
layout.setHorizontalGroup(hGroup); layout.setHorizontalGroup(hGroup);
var sizes = this.scroll.getPreferredSize();
sizes.height = panel.getMinimumSize().height;
sizes.width -= 10;
panel.setPreferredSize(sizes);
this.scroll.removeAll(); this.scroll.removeAll();
this.scroll.add(panel); this.scroll.add(panel);
this.repaint();
this.invalidate();
this.validate();
this.repaint();
} }
@Override @Override
@@ -124,17 +158,19 @@ public class LikelihoodWeightingGUI extends MyPanel {
var open = new JMenuItem("Open"); var open = new JMenuItem("Open");
open.addActionListener(action -> this.openFile()); open.addActionListener(action -> this.openFile());
var net1 = new JMenuItem("WetGrass net"); var nets = new JMenuItem[3];
net1.addActionListener(action -> this.openFile("lw/WetGrass.xdsl")); nets[0] = new JMenuItem("Alarm net");
nets[0].addActionListener(action -> this.openFile("lw/Alarm.xdsl"));
var net2 = new JMenuItem("Malaria net"); nets[1] = new JMenuItem("WetGrass net");
net2.addActionListener(action -> this.openFile("lw/Malaria.xdsl")); nets[1].addActionListener(action -> this.openFile("lw/WetGrass.xdsl"));
nets[2] = new JMenuItem("Malaria net");
nets[2].addActionListener(action -> this.openFile("lw/Malaria.xdsl"));
menu.add(open); menu.add(open);
menu.add(new JSeparator()); menu.add(new JSeparator());
menu.add(net1); for(var net : nets) menu.add(net);
menu.add(net2);
return menu; return menu;
} }

View File

@@ -37,7 +37,7 @@ public class NetworkNode {
NetworkNode(Network net, int handle, Map<Integer, NetworkNode> nodes) { NetworkNode(Network net, int handle, Map<Integer, NetworkNode> nodes) {
this.handle = handle; this.handle = handle;
this.type = net.getNodeType(handle); this.type = net.getNodeType(handle);
this.name = net.getNodeId(handle); this.name = net.getNodeName(handle);
this.net = net; this.net = net;
this.outcomes = net.getOutcomeIds(handle); this.outcomes = net.getOutcomeIds(handle);

View File

@@ -8,6 +8,7 @@ import java.util.function.Consumer;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
@@ -26,39 +27,45 @@ public class OutcomeChartGUI extends JPanel {
new Color(127,255,0), new Color(127,255,0),
}; };
private JButton[] outcomes;
private Label[] valuesChart;
private JLabel[] valuesPercent;
/** /**
* Crea il JPanel da visualizzare a partire da un NetworkNode appropriamente inizializzato. * Crea il JPanel da visualizzare a partire da un NetworkNode appropriamente inizializzato.
* Quando verrà visualizzato, il nodo avrà il nome degli output e i suoi valori in % * Quando verrà visualizzato, il nodo avrà il nome degli output e i suoi valori in %
* con una barra colorata per indicare la grandezza visivamente. * con una barra colorata per indicare la grandezza visivamente.
* *
* @param node il nodo di cui si vogliono visualizzare gli outcome * @param labels i label degli output del nodo
* @param action una azione da fare nel caso in cui venga premuto su un outcome * @param action una azione da fare nel caso in cui venga premuto su un outcome
*/ */
public OutcomeChartGUI(NetworkNode node, Consumer<Integer> action) { public OutcomeChartGUI(String[] labels, Consumer<Integer> action) {
var labels = node.outcomes;
var values = node.values;
if(labels.length != values.length) throw new IllegalArgumentException("Arrays length myst be equals!");
this.setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(1, 0, 0, 0), BorderFactory.createLineBorder(Color.GRAY)));
var layout = new GridLayout(labels.length, 2); var layout = new GridLayout(labels.length, 2);
this.setLayout(layout); 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++) { for(var i = 0; i < labels.length; i++) {
var value = values[i] * 100;
var lName = new JButton(labels[i]); var lName = new JButton(labels[i]);
var lValue = new Label(String.format("% 4.2f%%", value)); var lValue = new JLabel();
var barchart = new Label(); var barchart = new Label();
var size = barchart.getPreferredSize();
this.outcomes[i] = lName;
this.valuesChart[i] = barchart;
this.valuesPercent[i] = lValue;
final var index = i; final var index = i;
lName.setContentAreaFilled(false); lName.setContentAreaFilled(false);
lName.setFocusable(false); lName.setFocusable(false);
lName.addActionListener(a -> action.accept(index)); if(action == null) lName.setBorder(null);
if(node.evidence == i) lName.setForeground(Color.RED); else lName.addActionListener(a -> action.accept(index));
size.width = (int) (value * 1.5); var size = barchart.getPreferredSize();
size.width = 100;
size.height = 100;
barchart.setPreferredSize(size); barchart.setPreferredSize(size);
barchart.setBackground(COLORS[i % COLORS.length]); barchart.setBackground(COLORS[i % COLORS.length]);
@@ -76,4 +83,28 @@ public class OutcomeChartGUI extends JPanel {
this.add(panel2); this.add(panel2);
} }
} }
/**
* Modifica i valori mostrati a schermo cambiando anche la grandezza
* della barra indicante il valore
* @param values i nuovi valori da mostrare
* @param evidence indica l'evidenza del nodo
*/
public void updateValues(double[] values, int evidence) {
if(this.outcomes.length != values.length) throw new IllegalArgumentException("Arrays length myst be equals!");
for(var i = 0; i < this.outcomes.length; i++) {
var value = values[i] * 100;
var barchart = this.valuesChart[i];
var size = barchart.getSize();
size.width = (int) (value * 1.5);
barchart.setSize(size);
barchart.setPreferredSize(size);
this.valuesPercent[i].setText(String.format("% 4.2f%%", value));
if(evidence == i) this.outcomes[i].setForeground(Color.RED);
else this.outcomes[i].setForeground(Color.BLACK);
}
}
} }

View File

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This network was created in GeNIe Academic, which can be used for academic teaching and research purposes only -->
<smile version="1.0" id="Network1" numsamples="1000" discsamples="10000">
<nodes>
<cpt id="Burglary">
<state id="true" />
<state id="false" />
<probabilities>0.001 0.9990000000000001</probabilities>
</cpt>
<cpt id="Earthquake">
<state id="true" />
<state id="false" />
<probabilities>0.002 0.998</probabilities>
</cpt>
<cpt id="Alarm">
<state id="true" />
<state id="false" />
<parents>Burglary Earthquake</parents>
<probabilities>0.95 0.05000000000000004 0.9399999999999999 0.06000000000000005 0.29 0.71 0.001 0.999</probabilities>
</cpt>
<cpt id="JohnCall">
<state id="true" />
<state id="false" />
<parents>Alarm</parents>
<probabilities>0.9 0.09999999999999998 0.05 0.95</probabilities>
</cpt>
<cpt id="MaryCall">
<state id="true" />
<state id="false" />
<parents>Alarm</parents>
<probabilities>0.7 0.3 0.001 0.999</probabilities>
</cpt>
<cpt id="Radio">
<state id="Yes" />
<state id="No" />
<parents>Earthquake</parents>
<probabilities>0.9 0.09999999999999998 0.01 0.99</probabilities>
</cpt>
</nodes>
<extensions>
<genie version="1.0" app="GeNIe 4.1.3402.0 ACADEMIC" name="Network1">
<node id="Burglary">
<name>Burglary</name>
<interior color="e5f6f7" />
<outline color="000080" />
<font color="000000" name="Arial" size="14" />
<position>55 39 141 92</position>
<barchart active="true" width="128" height="78" />
</node>
<node id="Alarm">
<name>Alarm</name>
<interior color="e5f6f7" />
<outline color="000080" />
<font color="000000" name="Arial" size="14" />
<position>178 176 248 219</position>
<barchart active="true" width="128" height="78" />
</node>
<node id="Earthquake">
<name>Earthquake</name>
<interior color="e5f6f7" />
<outline color="000080" />
<font color="000000" name="Arial" size="14" />
<position>259 32 368 100</position>
<barchart active="true" width="128" height="78" />
</node>
<node id="JohnCall">
<name>JohnCall</name>
<interior color="e5f6f7" />
<outline color="000080" />
<font color="000000" name="Arial" size="14" />
<position>46 290 139 345</position>
<barchart active="true" width="128" height="78" />
</node>
<node id="MaryCall">
<name>MaryCall</name>
<interior color="e5f6f7" />
<outline color="000080" />
<font color="000000" name="Arial" size="14" />
<position>302 286 391 341</position>
<barchart active="true" width="128" height="78" />
</node>
<node id="Radio">
<name>Radio</name>
<interior color="e5f6f7" />
<outline color="000080" />
<font color="000000" name="Times New Roman" size="16" />
<position>441 176 512 220</position>
<barchart active="true" width="128" height="81" />
</node>
</genie>
</extensions>
</smile>