#"562438.files/image002.gif">, (2.1)
Для построения графиков зависимости величин и , а также фазового портрета,
необходимо решить данную систему на фиксированном временном промежутке с
заданными коэффициентами и начальными условиями. В данном случае, исходную
систему можно решить численно, используя метод Рунге-Кутта 4 порядка точности. В отличие от технологии Java, которая не имеет в своем
арсенале стандартных пакетов численных методов, с решением подобных задач
хорошо справляются такие специализированные математические пакеты как Maple,
MATLAB и др. Однако, существует ряд библиотек
численных методов, написанных на Java. Для решения поставленной задачи, я
использовал класс численных методов Рунге-Кутта 4 порядка точности из научной
Java-библиотеки Майкла Томаса Флэнагана. Данный класс ориентирован на решение
как одного дифференциального уравнения, так и систем дифференциальных
уравнений. Разрешение на использование,
копирование и изменение данного программного обеспечения и его документации для
некоммерческих целей предоставлено бесплатно, при условии, что упоминание
автора, доктора Майкла Томаса Фланагана на www.ee.ucl.ac.uk/ ~ mflanaga,
появляется во всех копиях и связанных с ними документациях или публикациях. При соблюдении вышеупомянутых условий, исходный класс был
изменен, в соответствии с конкретной поставленной задачей по следующим
причинам:
· Исходный класс содержал различные методы решения
дифференциальных уравнений, а также их систем, что соответственно увеличивало
размер данного класса. Мною было принято решение сократить его размер и
оставить только необходимые методы решения системы дифференциальных уравнений
методом Рунге-Кутта 4 порядка;
· Исходный класс был построен таким образом, что после
обращения к нему, возвращалось значение функций лишь в конечный момент времени,
что было нерациональным, для последующего построения графиков зависимостей с
использованием этих значений;
В конечном итоге преобразованный класс численного решения системы
дифференциальных уравнений первого порядка методом Рунге-Кутта 4 порядка
точности имеет следующую структуру:
· Инициализация системы дифференциальных уравнений происходит в
классе InitSystem.java, исходный код которого расположен в Приложении 1;
· Процесс численного решения системы дифференциальных уравнений
первого порядка методом Рунге-Кутта 4 порядка точности осуществляется классом RungeKutta_method.java,
исходный код которого расположен в Приложении 3;
· Значения, полученные в процессе вычисления системы, которые
затем используются для анализа и изучения поведения модели, записываются в
объект класса coordinates.java, исходный код которого расположен в Приложении
2;
Алгоритм работы класса RungeKutta_method{} изображен на рис. 3.3.
Рис. 2.2. Алгоритм работы класса RungeKutta_method{}
2. АРХИТЕКТУРА АППЛЕТА
После того, как мы определились с языком программирования и всеми
необходимыми инструментами, можно приступать к разработке приложения. В моей
курсовой работе уже упоминалось, что виртуальная лаборатория математического
моделирования будет размещена в глобальной сети Интернет, что позволит
обеспечить к ней открытый доступ. В связи с этим, передо мной стоит задача
написать не просто приложение, а апплет, который и будет в конечном итоге
размещен на сайте совместной лаборатории Института математических проблем
биологии РАН и Астраханского государственного университета "Математическое
моделирование и информационные технологии в науке и образовании"
(#"562438.files/image006.gif">, (2.1)
где - численность 1-го вида, - численность 2-го вида, - коэффициент прироста 1-го вида, - коэффициент прироста 2-го вида, - коэффициент, описывающий
внутривидовое влияние 1-го вида, - коэффициент, описывающий внутривидовое влияние 2-го вида, - коэффициент, описывающий влияние
со стороны 1-го вида, - коэффициент, описывающий влияние
со стороны 2-го вида.
Пользовательский интерфейс представлен на рисунке 3.1:
Рис. 3.1. Пользовательский интерфейс модели межвидовой конкуренции.
На нем представлены следующие элементы:
· Заголовок с названием модели и соответствующей системой;
· Поля для ввода данных (TextBox) с помощью ползунков
(ScrollBar);
· Командная кнопка "Рисовать" (Button);
· Режим дорисовки (CheckBox);
· Панели для графика и фазового портрета (LineChart);
После нажатия на кнопку "Рисовать", выполняется следующий
алгоритм:
Согласно алгоритму на рис. 3.2, после нажатия на кнопку
"Рисовать", происходит считывание введенных пользователем входных
данных с формы, затем создаются экземпляры следующих классов:
· Coordinates{}. В
этом классе объявлены массивы для хранения числовых значений координат X, Y, T, необходимых для
построения графиков зависимостей и фазового портрета;
· InitSystem{}. В этом классе происходит инициализация системы
2-х дифференциальных уравнений первого порядка согласно формуле 2.1, а также
соответствующих коэффициентов этой системы;
· RungeKutta_method{}. В этом классе реализовано численное
решение системы дифференциальных уравнений первого порядка методом Рунге-Кутта
4-го порядка точности;
Данные классы в программе связаны между собой по принципу, изображенному
UML-диаграммой на рисунке 3.3.
Рис. 3.3. UML - диаграмма, описывающая связь между классами.
Затем выполняется решение исходной системы, с учетом пользовательских
входных данных. После этого происходит построение графиков зависимостей , и фазового портрета, а также
дорисовка графиков, если такая функция активизирована. Пользовательское окно после выполнения программы по нажатию
на кнопку "Рисовать" изображено на рисунке 3.3. В этом случае функция
дорисовки неактивна. Апплет с дорисовкой изображен на рисунке 3.4. Дорисовка
применяется только к фазовому портрету. Графики функций и строятся без дорисовки.
Рис. 3.3. Пользовательский интерфейс. Фазовый портрет без дорисовки.
Рис. 3.4. Пользовательский интерфейс. Фазовый портрет с дорисовкой.
При компиляции апплета JavaFX в Neatbeans в папке dist проекта создаётся
4 файла:
· model.html - страница со встроенным апплетом;
· model.jar
- сам апплет;
· model.jnlp
- для запуска апплета через Webstart;
· model_browser.jnlp
- для запуска апплета встроенного в страницу;
Протокол JNLP (Java Network Launch Protocol - сетевой протокол запуска
приложений на языке Java) описывает запуск приложений Java Web Start. JNLP
состоит из набора правил, определяющих, как конкретно реализуется запускающий
механизм. Файлы JNLP включают такую информацию, как месторасположение jar
архивов (Java ARchive), имя главного класса приложения, ссылки на библиотеки
JavaFX. Правильно сконфигурированный веб-обозреватель передает JNLP файлы среде
JRE (Java Runtime Environment - реализация виртуальной машины), которая
загружает приложение на компьютер клиента и запускает его.
ЗАКЛЮЧЕНИЕ
В курсовой работе был проведен анализ технологий разработки интерактивных
программ, встраиваемых в веб-обозреватель, в частности, Java и JavaFX, а также
рассмотрены программные средства для создания апплетов. В качестве апробации
выбранных методов был разработан Java-апплет математической модели межвидовой
конкуренции с применением достаточно новой и перспективной технологии JavaFX.
Разработанный апплет размещен в сети Интернет и находится по адресу
#"562438.files/image007.gif">, и в виде массивов данных имеет
следующий вид:
.java
package model;class coordinates {[] X=new float[1000];[]
Y=new float[1000];
float[] T=new float[1000];
}
ПРИЛОЖЕНИЕ 3
Класс численного решения дифференциального уравнения, а также системы
дифференциальных уравнений первого порядка методом Рунге-Кутта 4 порядка
точности имеет следующий вид:
RungeKutta_method.java
/*
* Class RungeKutta
* requires interfaces DerivFunction and DerivnFunction
*
* Contains the methods for the Runge-Kutta procedures for
solving
* single or solving sets of ordinary differential equations
(ODEs)
* [draws heavily on the approach adopted in Numerical Recipes
* (C language version)http://www.nr.com]
*
* A single ODE is supplied by means of an interface,
* DerivFunction
* A set of ODEs is supplied by means of an interface,
* DerivnFunction
*
* WRITTEN BY: Dr Michael Thomas Flanagan
*
* DATE: February 2002
* UPDATES: 22 June 2003, April 2004,
* 15 September 2006 (to incorporate improvements suggested by
Klaus Benary [Klaus.Benary@gede.de])
* 11 April 2007, 25 April 2007, 4 July 2008, 26-31 January
2010
*
* DOCUMENTATION:
* See Michael Thomas Flanagan's Java library on-line web
page:
* http://www.ee.ucl.ac.uk/~mflanaga/java/RungeKutta.html
* http://www.ee.ucl.ac.uk/~mflanaga/java/
*
* Copyright (c) 2002 - 2010
*
* PERMISSION TO COPY:
* Permission to use, copy and modify this software and its
documentation for
* NON-COMMERCIAL purposes is granted, without fee, provided
that an acknowledgement
* to the author, Michael Thomas Flanagan at
www.ee.ucl.ac.uk/~mflanaga, appears in all copies.
*
* Dr Michael Thomas Flanagan makes no representations about
the suitability
* or fitness of the software for any or for a particular
purpose.
* Michael Thomas Flanagan shall not be liable for any damages
suffered
* as a result of using, modifying or distributing this
software or its derivatives.
*
*************************************************************/model;class RungeKutta_method{float
x0; float xn; float y0; float[] yy0; int nODE = 0; float step;
RungeKutta_method(){
}void setInitialValueOfX(float x0){.x0 = x0;
}void setFinalValueOfX(float xn){.xn = xn;
}void setInitialValuesOfY(float[] yy0){.yy0 = yy0;.nODE =
yy0.length;(this.nODE==1)this.y0 = yy0[0];
}void setStepSize(float step){.step = step;
}void fourthOrderMass(InitSystem g,coordinates
XY){(Double.isNaN(this.x0))throw new IllegalArgumentException("No initial
x value has been entered");(Double.isNaN(this.xn))throw new
IllegalArgumentException("No final x value has been
entered");(this.yy0==null)throw new IllegalArgumentException("No
initial y values have been entered");(Double.isNaN(this.step))throw new
IllegalArgumentException("No step size has been entered");[] k1 =new
float[this.nODE];[] k2 =new float[this.nODE];[] k3 =new float[this.nODE];[] k4
=new float[this.nODE];[] y =new float[this.nODE];[] yd =new float[this.nODE];[]
dydx =new float[this.nODE];x = 0.0f;ns = (this.xn - this.x0)/this.step;=
(float) Math.rint(ns);nsteps = (int) ns;.nIter = nsteps;stepUsed = (this.xn -
this.x0)/ns;[][] Y=new float[this.nODE][nsteps];(int i=0; i<this.nODE;
i++)y[i] = this.yy0[i];.X[0]=yy0[0];.Y[0]=yy0[1];(int j=0; j<nsteps; j++){=
this.x0 + j*stepUsed;= g.derivn(x, y);(int i=0; i<this.nODE; i++)k1[i] =
stepUsed*dydx[i];(int i=0; i<this.nODE; i++)yd[i] = y[i] + k1[i]/2;=
g.derivn(x + stepUsed/2, yd);(int i=0; i<this.nODE; i++)k2[i] =
stepUsed*dydx[i];(int i=0; i<this.nODE; i++)yd[i] = y[i] + k2[i]/2;=
g.derivn(x + stepUsed/2, yd);(int i=0; i<this.nODE; i++)k3[i] =
stepUsed*dydx[i];(int i=0; i<this.nODE; i++)yd[i] = y[i] + k3[i];=
g.derivn(x + stepUsed, yd);(int i=0; i<this.nODE; i++)k4[i] =
stepUsed*dydx[i];(int i=0; i<this.nODE; i++)y[i] += k1[i]/6 + k2[i]/3 +
k3[i]/3 + k4[i]/6;.X[j]=y[0];.Y[j]=y[1];.T[j]=this.x0+j*this.step;
}
}
ПРИЛОЖЕНИЕ 4
Главный файл апплета Main.fx модели межвидовой конкуренции с
пользовательским интерфейсом:
Main.fx
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/model;javafx.stage.Stage;javafx.scene.Scene;javafx.scene.layout.LayoutInfo;javafx.scene.layout.Tile;javafx.scene.chart.LineChart;javafx.scene.chart.part.NumberAxis;javafx.scene.control.Label;javafx.scene.control.TextBox;javafx.scene.control.ScrollBar;javafx.scene.control.Button;javafx.scene.chart.part.Side;java.lang.*;javafx.scene.image.*;javafx.scene.layout.Flow;javafx.scene.control.CheckBox;
/**
* @author Admin
*/
//var X0= 0;numberGraf=-1;
//var numOfEquat:
Integer;numOfEquat=2;stepSize=0.1;t0=0;tn=100;numSteps=1000;
//var beginValue=[X0,Y0];coordinat=coordinates{};tempX0=bind
Float.valueOf(textX0.text);J=123.456789;Imagesystem=ImageView{image:Image{url:"{__DIR__}system.jpg"
width: 200: 100}
}modelNAME=Label { layoutInfo: LayoutInfo { width: 300}text:
" Модель межвидовая конуренция"}
//var CoordinateOfXY = LineChart. Series
{};CoordinatesOfXY:LineChart. Series[]=[.Series {},.Series {},.Series
{},.Series {},.Series {},.Series {},.Series {},.Series {},.Series {},.Series
{},.Series {},.Series {},.Series {},.Series {},.Series {},.Series {},.Series
{},.Series {},.Series {},.Series {}
];CoordinateOfXT = LineChart. Series {name:
"X(t)"};CoordinateOfYT = LineChart. Series {name:
"Y(t)"};grafikXY = LineChart {: false: false: "Фазовый
портрет": LayoutInfo { width: 400 height: 400}: NumberAxis {: 0: 10:
"x"
}: NumberAxis {: 0: 10: "y"
}
data: CoordinatesOfXY
} //инициализация графика X от Y
var grafikXYT = LineChart {: "График": Side.RIGHT:
false: LayoutInfo { width: 600 height: 200}: NumberAxis {:10: 10: 0: 100:
"t"
}: NumberAxis {: 0: 10: "x y"
}: [CoordinateOfXT,CoordinateOfYT]
} //инициализация графика Y от TlabelX0=Label { width: 20
text: "Xo"}textX0=TextBox {layoutInfo: LayoutInfo {: 100} text: bind String.valueOf(valX0)
columns: 10 selectOnFocus: false:true
}scrollX0 = ScrollBar { layoutInfo: LayoutInfo { width: 140
height: 15}: 0 max: 10 vertical: false value: 10 unitIncrement: 0.1
visibleAmount :0.01
}
//scrollX0.onMouseDragged
//textX0.onKeyReleasedlabelY0=Label {width: 20 text:
"Yo:"}textY0=TextBox { layoutInfo: LayoutInfo { width: 100} text:
bind String.valueOf(valY0) columns: 10:true
}scrollY0 = ScrollBar {layoutInfo: LayoutInfo { width: 140
height: 15}: 0 max: 10 vertical: false value: 10 unitIncrement:0.1
visibleAmount :0.01}labela1=Label {width: 20 text:
"a1:"}texta1=TextBox { layoutInfo: LayoutInfo { width: 100} text:
bind String.valueOf(vala1) columns: 10selectOnFocus: false:true
}scrolla1 = ScrollBar {layoutInfo: LayoutInfo { width: 140
height: 15}: 0.01 max: 1 vertical: false value: 0.1 unitIncrement:0.01
visibleAmount :0.01}labela2=Label {width: 20 text:
"a2:"}texta2=TextBox {layoutInfo: LayoutInfo { width: 100} text: bind
String.valueOf(vala2) columns: 10selectOnFocus: true:true
}scrolla2 = ScrollBar {layoutInfo: LayoutInfo { width: 140
height: 15}: 0.01 max: 1 vertical: false value: 0.2 unitIncrement:0.0099
visibleAmount :0.01}labelb1=Label {width: 20 text:
"b1:"}textb1=TextBox {layoutInfo: LayoutInfo { width: 100} text: bind
String.valueOf(valb1) columns: 10selectOnFocus: true:true
}scrollb1 = ScrollBar {layoutInfo: LayoutInfo { width: 140
height: 15}: 0.01 max: 1 vertical: false value: 0.05 unitIncrement:0.0099
visibleAmount :0.01}labelb2=Label {width: 20 text:
"b2:"}textb2=TextBox {layoutInfo: LayoutInfo { width: 100} text: bind
String.valueOf(valb2) columns: 10selectOnFocus: true:true
}scrollb2 = ScrollBar {layoutInfo: LayoutInfo { width: 140
height: 15}: 0.01 max: 0.15 vertical: false value: 0.1 unitIncrement:0.0014
visibleAmount :0.01}labelg1=Label {width: 20 text:
"g1:"}textg1=TextBox {layoutInfo: LayoutInfo { width: 100} text: bind
String.valueOf(valg1) columns: 10selectOnFocus: true:true
}scrollg1 = ScrollBar {layoutInfo: LayoutInfo { width: 140
height: 15}: 0.01 max: 1 vertical: false value: 0.03 unitIncrement:0.0099
visibleAmount :0.01}labelg2=Label {width: 20 text:
"g2:"}textg2=TextBox {layoutInfo: LayoutInfo { width: 100} text: bind
String.valueOf(valg2) columns: 10selectOnFocus: true:true
}scrollg2 = ScrollBar {layoutInfo: LayoutInfo { width: 140
height: 15}: 0.01 max: 0.15 vertical: false value: 0.15 unitIncrement:0.0014
visibleAmount :0.01}repaint=CheckBox {text: "Дорисовка"allowTriState:
falseselected: false}buttonpaint=Button {text: "Рисовать"action:
function() {X0= scrollX0.value;Y0= scrollY0.value;a1= scrolla1.value;a2=
scrolla2.value;b1= scrollb1.value;b2= scrollb2.value;g1= scrollg1.value;g2=
scrollg2.value;beginValue=[X0,Y0];system = InitSystem{};.setKvalues(a1, b1, g1,
a2, b2, g2);solve = RungeKutta_method{};.setInitialValueOfX(t0);.setFinalValueOfX(tn);.setInitialValuesOfY(beginValue);.setStepSize(stepSize);.fourthOrderMass(system,coordinat);
// delete CoordinatesOfXY[numberGraf+1].data;
//CoordinateOfXY.data=null;CoordinateOfXT.data;CoordinateOfYT.data;
//Определяем режим дорисовки графика(repaint.selected==true)
then numberGraf=numberGraf+1;(repaint.selected==false) then
{numberGraf=-1;CoordinatesOfXY[numberGraf+1].data;(i in [0..9 step
1])CoordinatesOfXY[i].data;
}(i in [0..numSteps-1 step 1]) {LineChart.Data {:
coordinat.X[i]: coordinat.Y[i]
} into CoordinatesOfXY[numberGraf+1].data;LineChart.Data {:
coordinat.T[i]: coordinat.X[i]
} into CoordinateOfXT.data;LineChart.Data {: coordinat.T[i]:
coordinat.Y[i]
} into CoordinateOfYT.data;
}
}
}valX0=bind RoundToThree(scrollX0.value);valY0=bind
RoundToThree(scrollY0.value);vala1=bind RoundToThree(scrolla1.value);vala2=bind
RoundToThree(scrolla2.value);valb1=bind RoundToThree(scrollb1.value);valb2=bind
RoundToThree(scrollb2.value);valg1=bind RoundToThree(scrollg1.value);valg2=bind
RoundToThree(scrollg2.value);RoundToThree(a: Number):
Number{h;=a*1000;=Math.round(h);=h/1000;h;
}{:
"Модель межвидовой конкуренции"
resizable: false
scene: Scene {: 800: 600: [{ layoutInfo: LayoutInfo { width:
800 height: 600}: [,{content: [{ layoutInfo: LayoutInfo { width: 310} hgap: 20
vgap: 10 width: 400: [ modelNAME,Flow{ content:[ Imagesystem]translateX:
45},,textX0,labelY0,textY0,,scrollY0,,texta1,labela2,texta2,,scrolla2,,textb1,labelb2,textb2,,scrollb2,,textg1,labelg2,textg2,,scrollg2,,repaint
] translateY: 10 }
]translateX: 45},
]
}//Tile
]
}
}
Похожие работы на - Применение технологий Java и JavaFX для разработки виртуальных лабораторий математического моделирования
|