嗨,我正在尝试实现一种算法并实现该功能:当一个分子编号变为0时,整个while循环将结束,并使用JFreeChart自动进行下一个图表绘制步骤。 现在,使用“ return”后,eclipse不会显示任何错误并完全处理主要方法。但是,我看不到我的图表显示出来。想知道是否有任何步骤出错。 我想显示不同物种在不同时间的分子数量。每个物种将代表一个新行。 所以我创建了一个新的图表
static JPanel chartPanel;
然后在构造函数中设置类似(只需遵循在线教程)
super("Line Chart of molecule numbers at different times");
add(chartPanel, BorderLayout.CENTER);
setSize(640, 480);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
在主要方法中,我想显示折线图中输入并计算的数字(因为害怕空指针异常,所以没有创建另一个类)
public static void main(String args[]) throws Exception {
//input the number of species
System.out.println("Enter the number of species:");
int n = sc.nextInt();
//input the number of reactions
System.out.println("Enter the number of reactions:");
int m = sc.nextInt();
//
int[][]matrixPre = new int[m][n];
enterMatrixDataPre(sc, matrixPre, m, n);
printMatrixPre(matrixPre, m, n);
//convert the 2d int to 2d double
double [][] matrixPre2 = new double[m][n];
for(int i = 0; i <m; i++)
{
for(int j = 0; j < n; j++)
matrixPre2[i][j] = (double) matrixPre[i][j];
}
RealMatrix PreMatrix = new Array2DRowRealMatrix(matrixPre2);
// remember to add space key when doing the typing
int[][]matrixPost = new int[m][n];
enterMatrixDataPost(sc, matrixPost, m, n);
printMatrixPost(matrixPost, m, n);
//convert the 2d int to 2d double
double [][] matrixPost2 = new double[m][n];
for(int i = 0; i <m; i++)
{
for(int j = 0; j < n; j++)
matrixPost2[i][j] = (double) matrixPost[i][j];
}
RealMatrix PostMatrix = new Array2DRowRealMatrix(matrixPost2);
//
RealMatrix matrixSubtract = PreMatrix.subtract(PostMatrix);
System.out.println("So the transpose matrix after subtraction is:\t"+matrixSubtract.transpose());
//input the default maxium time of the whole reaction
System.out.println("Enter the maxium time of the whole reaction:");
double Tmax =sc.nextDouble();
//input the name of all the species
System.out.println("Enter the name of all species");
String[] strs=new String[n];
for(int i = 0; i< n; i++) {
strs[i]=sc.nextLine();
}
//input the rate constant of all the reactions(the coefficient), must be a double
System.out.println("Enter the rate constant of each reaction:");
Double[] rate=new Double[m];
for(int r = 0; r< m; r++) {
rate[r]=sc.nextDouble();
}
//
Vector<Double> timeList = new Vector<Double>(0);
Vector<int[]> allStateList = new Vector<int[]>(0);
timeList.add(newTime);
//input the initial states of numbers of molecules
System.out.println("Enter the initial molecule numbers of all species:");
int[]state = new int[n];
for (int i = 0; i< n; i++)
{
state[i]=sc.nextInt();
}
allStateList.add(state);
while(newTime<Tmax) {
for(int loopIndex =0; loopIndex<allStateList.size(); loopIndex++) {
// calculate the hazard for each reaction and the general hazard
double[] h = new double[m];
H = 0;
try {
for(int i =0; i<m; i++) {
for(int j =0; j<n; j++) {
h[i]=rate[i]*CombinatoricsUtils.binomialCoefficientDouble(allStateList.get(loopIndex)[j],(int)(PreMatrix.getRowVector(i).toArray()[j]));
H +=h[i];
}
}
}
catch(NumberIsTooLargeException exceptionn) {
System.out.println("One of the species has been exhausted and there is no next firing");
return;
}
System.out.println("So the general hazard is:"+H);
// select a random reaction time
Random random = new Random();
double tau = (1*Math.log(1/random.nextDouble()))/H;
System.out.println("So the random reaction time is"+tau);
//put the newTime
newTime = timeList.get(loopIndex)+tau;
System.out.println("So the new reaction time is:" + newTime);
timeList.add(newTime);
//select a random reaction j
Random random2 = new Random();
int index =0;
for (int i=0; i<m; i++) {
if(h[i]>random2.nextDouble()*H)
index =i;
}
System.out.println("So the next simulated event is:"+index);
//Update the state
double[] vectorDoubleArray = matrixSubtract.transpose().getColumnVector(index).toArray();
int[] intArray = new int[n];
for (int i=0; i<n; i++) {
intArray[i] = (int) vectorDoubleArray[i];
}
int[] newState = new int[n];
int newS =0;
for (int p =0; p<n; p++){
newS= intArray[p]+allStateList.get(loopIndex)[p];
newState[p]=newS;
}
System.out.println("Right now the molecule number of all species are:"+Arrays.toString(newState));
allStateList.add(newState);
}
//close the scanner
sc.close();
}
}
所有准备工作完成后,我想使用jfreechart打印两个向量列表的数量,timeList和allStateList
String chartTitle = "Line chart of molecule numbers";
String categoryAxisLabel = "time";
String valueAxisLabel = "molecule numbers";
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
int[] eachSpecieState = new int[allStateList.size()];
for (int i =0; i<n; i++) {
for (int j=0; j<allStateList.size(); j++) {
eachSpecieState[i]=allStateList.get(j)[i];
}
}
for (int i =0; i<m;i++) {
String series[]= new String[m];
series[i]=""+strs[i];
for(int k =0; k<n;k++) {
for (int j=0; j<allStateList.size(); j++) {
eachSpecieState[k]=allStateList.get(j)[k];
dataset.addValue(eachSpecieState[k],series[i+1],""+timeList.get(j));
}
}
}
JFreeChart chart = ChartFactory.createLineChart(chartTitle,
categoryAxisLabel, valueAxisLabel, dataset);
chartPanel = new ChartPanel(chart);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new StochasticProcess().setVisible(true);
}
});
但是没有图表显示。由于我的摇摆语言不太好,有人可以帮我指出是否有任何部分出错?(代码的最后一个绘图和图表部分)谢谢〜
答案 0 :(得分:1)
最简单的解决方案之一就是将中断条件添加到一个简单的<!DOCTYPE HTML>
<html ng-app="todoApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
</head>
<body>
<div ng-controller="todoList" class="jumbotron">
<h2><strong>To-Do List</strong></h2>
<br/>
<form ng-submit="addTodo()">
<input type="text" ng-model="todoText"
placeholder="Add new task" size="30">
<button type="submit" class="btn btn-primary glyphicon glyphicon-plus">Add</button>
</form>
<br/>
<ul>
<li ng-repeat="todo in todos">
<label class="checkbox">
<input type="checkbox" ng-model="todo.done">
<span class="done-{{todo.done}}">{{todo.text}}</span>
<span class="glyphicon glyphicon-trash" ng-click="removeTodo()"></span>
</label>
</li>
</ul>
</div>
<script>
var app = angular.module('todoApp', []);
app.controller('todoList', function ($scope, $localStorage) {
$scope.getTodos = function() {
var str = $localStorage.getItem("todos");
$scope.todos = JSON.parse(str);
if (!todos) {
$scope.todos = [{ text: 'Feed the cat', done: true }, { text: 'Mow the lawn', done: false }];
}
}
$scope.saveToDos = function() {
var str = JSON.stringify(todos);
$localStorage.SetItem("todos", str);
}
$scope.addTodo = function () {
if($scope.todoText !== '') {
$scope.todos.push({text:$scope.todoText, done:false});
$scope.todoText = '';
saveToDos();
}
};
$scope.removeToDo = function() {
todos.splice($index, 1);
saveToDos();
}
});
</script>
</body>
</html>
循环中
for
答案 1 :(得分:0)
我不得不承认,在没有特定知识的情况下,要理解和调试整个代码并不容易。但是,总的来说,我看到了,在一定程度上,您写道:
***while(allStateList.get(loopIndex)[j]==0) {
break;
}***
我认为,作为一般规则,如果要检查条件,则必须使用IF语句,例如:if(condition == true){break; }
我认为这对您有用。
答案 2 :(得分:0)
因此,为了解决该问题,我创建了XYSeries列表,并为循环内的每个XYSeries添加了新名称。在为每个XYSeries添加值之后,使用另一个循环将其添加到XYCollection中。问题是在一周前提出的,对许多部分进行了修改以获取最终结果。我将在下面发布整个代码的新版本以将其设置为例。
import java.util.*;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.lang.Math;
import org.apache.commons.math3.exception.NumberIsTooLargeException;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.RealMatrix;
import org.apache.commons.math3.util.CombinatoricsUtils;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
主要方法部分在这里:
public class StochasticSimulationProcess extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
static int matrixPre[][];
static int matrixPost[][];
static int m;// the number of reactions
static int n;// the number of species
static double[] h;// the hazard for each reaction
static double[] rate;
static int[] state;
static double newTime;
static int max;
static double Tmax;// the overall reaction time
Vector<Double> timeList;
static double H;
Vector<int[]> allStateList;
static String[] strs;
XYSeriesCollection dataset;
public StochasticSimulationProcess(String s) {
super(s);
newTime = 0;
}
static Scanner sc = new Scanner(System.in);
public static void main(String args[]) throws Exception {
// input the number of species
System.out.println("Enter the number of species:");
int n = sc.nextInt();
// input the number of reactions
System.out.println("Enter the number of reactions:");
int m = sc.nextInt();
//
int[][] matrixPre = new int[m][n];
enterMatrixDataPre(sc, matrixPre, m, n);
printMatrixPre(matrixPre, m, n);
// convert the 2d int to 2d double
double[][] matrixPre2 = new double[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++)
matrixPre2[i][j] = (double) matrixPre[i][j];
}
RealMatrix PreMatrix = new Array2DRowRealMatrix(matrixPre2);
// remember to add space key when doing the typing
int[][] matrixPost = new int[m][n];
enterMatrixDataPost(sc, matrixPost, m, n);
printMatrixPost(matrixPost, m, n);
// convert the 2d int to 2d double
double[][] matrixPost2 = new double[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++)
matrixPost2[i][j] = (double) matrixPost[i][j];
}
RealMatrix PostMatrix = new Array2DRowRealMatrix(matrixPost2);
//
RealMatrix matrixSubtract = PreMatrix.subtract(PostMatrix);
System.out.println("So the transpose matrix after subtraction is:\t" + matrixSubtract.transpose());
// input the default maxium time of the whole reaction
System.out.println("Enter the maxium time of the whole reaction:");
double Tmax = sc.nextDouble();
// input the name of all the species
System.out.println("Enter the name of all species");
String[] strs = new String[n];
for (int i = 0; i < n; i++) {
strs[i] = sc.nextLine();
}
// input the rate constant of all the reactions(the coefficient), must be a
// double
System.out.println("Enter the rate constant of each reaction:");
Double[] rate = new Double[m];
for (int r = 0; r < m; r++) {
rate[r] = sc.nextDouble();
}
//
Vector<Double> timeList = new Vector<Double>(0);
Vector<int[]> allStateList = new Vector<int[]>(0);
timeList.add(newTime);
// input the initial states of numbers of molecules
System.out.println("Enter the initial molecule numbers of all species:");
int[] state = new int[n];
for (int i = 0; i < n; i++) {
state[i] = sc.nextInt();
}
allStateList.add(state);
timeLoop:
while (newTime < Tmax) {
for (int loopIndex = 0; loopIndex < allStateList.size(); loopIndex++) {
// calculate the hazard for each reaction and the general hazard
double[] h = new double[m];
H = 0;
try {
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
h[i] = rate[i] * CombinatoricsUtils.binomialCoefficientDouble(
allStateList.get(loopIndex)[j], (int) (PreMatrix.getRowVector(i).toArray()[j]));
H += h[i];
}
}
}
catch (NumberIsTooLargeException exceptionn) {
System.out.println("One of the species has been exhausted and there is no next firing");
break timeLoop;
}
System.out.println("So the general hazard is:" + H);
// select a random reaction time
Random random = new Random();
double tau = (1 * Math.log(1 / random.nextDouble())) / H;
System.out.println("So the random reaction time is" + tau);
// put the newTime
newTime = timeList.get(loopIndex) + tau;
System.out.println("So the new reaction time is:" + newTime);
timeList.add(newTime);
// select a random reaction j
Random random2 = new Random();
int index = 0;
double hi =0;
for (int i = 0; i < m; i++) {
hi +=h[i];
if (hi >= random2.nextDouble() * H) {
index = i;
break;
}
}
System.out.println("So the next simulated event is:" + index);
// Update the state
double[] vectorDoubleArray = matrixSubtract.transpose().getColumnVector(index).toArray();
int[] intArray = new int[n];
for (int i = 0; i < n; i++) {
intArray[i] = (int) vectorDoubleArray[i];
}
int[] newState = new int[n];
int newS = 0;
for (int p = 0; p < n; p++) {
newS = intArray[p] + allStateList.get(loopIndex)[p];
newState[p] = newS;
}
System.out.println("Right now the molecule number of all species are:" + Arrays.toString(newState));
allStateList.add(newState);
}
// close the scanner
sc.close();
}
XYSeriesCollection dataset = new XYSeriesCollection();
XYSeries[] species = new XYSeries[n];
for (int j =0; j<n; j++) {
species[j]=new XYSeries(""+strs[j]+Integer.toString(j));
}
for (int j =0; j<n; j++) {
for (int k=0; k< allStateList.size();k++) {
species[j].add(timeList.get(k).doubleValue(), allStateList.get(k)[j]);
}
dataset.addSeries(species[j]);
}
// plot out the graph
System.out.println("TEST");
JFreeChart chart = ChartFactory.createXYLineChart(
"SSA Modeling",
"time",
"Number of Molecules",
dataset,
PlotOrientation.VERTICAL,
true,
true,
false
);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
chartPanel.setBackground(Color.white);
XYPlot plot = chart.getXYPlot();
XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
for (int j =0; j<n;j++){
renderer.setSeriesPaint(j, Color.RED);
renderer.setSeriesStroke(j, new BasicStroke(2.0f));
}
plot.setRenderer(renderer);
plot.setBackgroundPaint(Color.white);
plot.setRangeGridlinesVisible(false);
plot.setDomainGridlinesVisible(false);
chart.getLegend().setFrame(BlockBorder.NONE);
chart.setTitle(new TextTitle("Stochastic Simulation Algorithm",
new Font("Serif", Font.BOLD, 18)
)
);
SwingUtilities.invokeLater(() -> {
StochasticSimulationProcess ex = new StochasticSimulationProcess("SSA");
ex.setContentPane(chartPanel);
ex.pack();
ex.setLocationRelativeTo(null);
ex.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ex.setVisible(true);
});
}
public static void enterMatrixDataPre(Scanner sc, int[][] matrixPre, int m, int n) {
System.out.println("Enter Matrix pre data");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
matrixPre[i][j] = sc.nextInt();
}
}
}
public static void printMatrixPre(int[][] matrixPre, int m, int n) {
System.out.println("Matrix pre is:");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.print(matrixPre[i][j] + "\t");
}
System.out.println();
}
}
public static void enterMatrixDataPost(Scanner sc, int[][] matrixPost, int m, int n) {
System.out.println("Enter Matrix post data");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
matrixPost[i][j] = sc.nextInt();
}
}
}
public static void printMatrixPost(int[][] matrixPost, int m, int n) {
System.out.println("Matrix post is:");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.print(matrixPost[i][j] + "\t");
}
System.out.println();
}
}
}
随机更改颜色,因为表示物种的XYSeries的数量是不确定的,所以我选择了随机设置hgb方法,因为只要值在0-255之间,它们就可以随机组合,因此我更改了代码为:
renderer.setSeriesPaint(j, Color.getHSBColor(0 + (float)(Math.random() * ((255 - 0) + 1)), 0 + (float)(Math.random() * ((255 - 0) + 1)), 0 + (float)(Math.random() * ((255 - 0) + 1))));