此次完成了操作系统中移动臂调度的三个算法:先来先排序算法,最短路径优先算法,电梯调度算法。实现功能:输入序列或随机生成序列,对生成的序列进行三种算法的分别排序,并计算出移动臂移动距离和,寻道时间和平均寻道距离。并用树形图统计结果和折线图演示。
一、算法类
调度类的方法体和删除方法(算法中用来将已读取序列元素去除方便计算)
public Dispath(int array,int count,int perTime,int Array[]) {
this.array=array;
this.count=count;
this.perTime=perTime;
for(int i=0;i<Array.length;i++){
this.Array[i]=Array[i];
}
}
public void Delete(int arr[],int n) {
for(int i=n;i<arr.length-1;i++)
arr[i]=arr[i+1]; }
public void Please(){
System.out.print("请求序列:");
for(int i=0;i<count;i++){
if(i==count-1)
System.out.print(Array[count-1]+"。");
else
System.out.print(Array[i]+",");
}
System.out.println();
}
<1>先来先服务算法
这个算法比较简单计算并累计两磁道之间距离
对磁盘请求序列按照先后顺序从磁头号依次移动
采用先来先服务算法后,对请求序列进行排序,函数返回服务序列int[]型。
public int[] First(){
int j=0 ;
int min;
int arrayc=array;
int ArrayC[]=new int[count];
while(j<count) {
int num=0;
min=(Array[0]>=arrayc)?(Array[0]-arrayc):(arrayc-Array[0]);
ArrayC[j++]=Array[num]; //将找到的磁道号赋值给服务序列【0-9】
Distance+=min;
arrayc=Array[num]; //当前磁道号指向新找到的磁道号
Delete(Array,num); //删除排序好后的磁道号
}
AvgDistance=(double)Distance/(count);
FindTime=perTime*Distance;
return ArrayC;
}
<2>最短寻找时间优先算法
对磁盘请求序列比较磁头号,寻找移动距离累计最短的下一磁头号,保存在另一数组内,并从原数组内删去排序后的元素,直到原数组为空,将另存的数组2保存为服务序列。
采用最短寻找时间优先算法后,函数返回服务序列int[]型
public int[] Short() {
int j=0,count2=count;
int min;
int arrayc=array;
int ArrayC[]=new int[count];
while(j<count) {
int num=0;
min=(Array[0]>=arrayc)?(Array[0]-arrayc):(arrayc-Array[0]);
for(int i=0;i<count2;i++) {
if(((Array[i]>=arrayc)&&(Array[i]-arrayc<min))||((Array[i]<arrayc)&&(arrayc-Array[i]<min))) {
min=(Array[i]>=arrayc)?(Array[i]-arrayc):(arrayc-Array[i]);
num=i;
}
}
ArrayC[j++]=Array[num]; //将找到的磁道号赋值给服务序列【0-9】
Distance+=min;
arrayc=Array[num]; //当前磁道号指向新找到的磁道号
Delete(Array,num); //删除排序好后的磁道号
count2--; //内循环
}
AvgDistance=(double)Distance/(count);
FindTime=perTime*Distance;
return ArrayC;
}
<3>电梯调度算法
对磁盘请求序列第一个柱面与磁头号比较,判断移动臂首次移动的方向(最内柱面和最外柱面):如为最内柱面,则将数组1从小到大排序,保存在数组3,返回序列则为从数组3内第一个柱面所在位置到数组3尾端,再接上第一个柱面所在位置到数组3首端;如为最外柱面则相反。
对数组1排序采用冒泡排序
采用电梯调度算法后,函数返回服务类型int[]型
public int[] Elevator() {
int a=0,count2=count;
int min;
int n=0;
int arrayc=array;
int ArrayB[]=new int[count]; //升序或降序排列
int ArrayC[]=new int[count]; //电梯排列
int ArrayD[]=new int[count]; //输出顺序
int num=0;
min=(Array[0]>=arrayc)?(Array[0]-arrayc):(arrayc-Array[0]);
for(int i=0;i<count;i++) {
if(((Array[i]>=arrayc)&&
(Array[i]-arrayc<min))||((Array[i]<arrayc)&&(arrayc-Array[i]<min))){
min=(Array[i]>=arrayc)?(Array[i]-arrayc):(arrayc-Array[i]);
num=i; //找出与指向的磁道号距离最近的磁道号
}
}
ArrayC[0]=Array[num]; //将找到的磁道号赋值给服务序列【0-9】
arrayc=Array[num]; //当前磁道号指向新找到的磁道号
for(int i=0;i<count;i++){
ArrayB[i]=Array[i];
}
if(arrayc>=array){ //从小到大
int temp=0;
for(int i=0;i<count-1;i++){
for(int j=0;j<count-1-i;j++){
if(ArrayB[j] >= ArrayB[j+1]){ //交换两数位置
temp = ArrayB[j];
ArrayB[j] = ArrayB[j+1];
ArrayB[j+1] = temp;
}
}
}
for(int i=0;i<count;i++){
if(ArrayB[i]==arrayc)
n=i;
}
int o=n-1;
int m=n;
for(int i=0;i<count;){
while(m<count){
ArrayC[i]=ArrayB[m];
i++;
m++;
}
ArrayC[i]=ArrayB[o];
i++;
o--;
}
arrayc=array;
while(a<count) {
int k=0;
min=(ArrayC[0]>=arrayc)?(ArrayC[0]-arrayc):(arrayc-ArrayC[0]);
ArrayD[a++]=ArrayC[k];
Distance+=min;
arrayc=ArrayC[k];
Delete(ArrayC,k);
}
}
else{ //从大到小
int temp=0;
for(int i=0;i<count-1;i++){
for(int j=0;j<count-1-i;j++){
if(ArrayB[j] <= ArrayB[j+1]){ //交换两数位置
temp = ArrayB[j];
ArrayB[j] = ArrayB[j+1];
ArrayB[j+1] = temp;
}
}
}
for(int i=0;i<count;i++){
if(ArrayB[i]==arrayc)
n=i;
}
int o=n-1;
int m=n;
for(int i=0;i<count;){
while(m<count){
ArrayC[i]=ArrayB[m];
i++;
m++;
}
ArrayC[i]=ArrayB[o];
i++;
o--;
}
arrayc=array;
while(a<count) {
int k=0;
min=(ArrayC[0]>=arrayc)?(ArrayC[0]-arrayc):(arrayc-ArrayC[0]);
ArrayD[a++]=ArrayC[k];
Distance+=min;
arrayc=ArrayC[k];
Delete(ArrayC,k);
}
}
AvgDistance=(double)Distance/(count);
FindTime=perTime*Distance;
return ArrayD;
}
二、界面图形类
<1>折线图绘制类
这样演示也是突发奇想,演示结果后图有,可能有点丑不要见怪
用的方法是早期学java时动画的画图画布类方法
动画小程序后面博客也会更新
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.Timer;
public class Display extends JFrame{
public boolean sign;
private DisplayCanvas canvas;
public Display(int a,int[] array)
{
this.setTitle("演示");
this.setBounds(500,200,900,500);
this.setFont(new Font("Arial",Font.BOLD,18));
//this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
Dimension dim=getToolkit().getScreenSize();
this.setBounds(dim.width/4,dim.height/4,dim.width/2,dim.height/2);
setLocationRelativeTo(null);
//this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.canvas=new DisplayCanvas(a,array);
canvas.setBackground(Color.lightGray);
this.getContentPane().add(this.canvas,"Center");
this.setVisible(true);
}
}
class DisplayCanvas extends Canvas implements ActionListener{
private int Array[] = new int[10];
private int n;
public DisplayCanvas(int a,int[] array){
this.setArray(a,array);
}
public void setArray(int a,int[] array){
this.Array=array;
this.n=a;
}
public void paint(Graphics g){
int x=this.getWidth()/100;
int y=this.getHeight()/100;
g.setColor(Color.black);
g.drawLine(n*x,0,Array[0]*x,10*y);
for(int i=0;i<9;i++){
g.drawLine(Array[i]*x,(i+1)*10*y,Array[i+1]*x,(i+2)*10*y);
g.fillOval(Array[i]*x-5,(i+1)*10*y-5, 10,10);
}
g.fillOval(Array[9]*x-5,100*y-5, 10,10);
}
public void actionPerformed(ActionEvent ev){
repaint();
}
}
<2>树状统计图类
用到的java图形的JFreeChart报表图表绘制类库,这里就不多加说明,万能百度
import java.awt.Font;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
public class Bar {
ChartPanel frame1;
public Bar(int a1,double a2, int b1,double b2,int c1,double c2){
CategoryDataset dataset = getDataSet(a1,a2,b1,b2, c1, c2);
JFreeChart chart = ChartFactory.createBarChart3D(
"磁盘调度算法", // 图表标题
"算法类别", // 目录轴的显示标签
"长度", // 数值轴的显示标签
dataset, // 数据集
PlotOrientation.VERTICAL, // 图表方向:水平、垂直
true, // 是否显示图例(对于简单的柱状图必须是false)
false, // 是否生成工具
false // 是否生成URL链接
);
//从这里开始
CategoryPlot plot=chart.getCategoryPlot();//获取图表区域对象
CategoryAxis domainAxis=plot.getDomainAxis(); //水平底部列表
domainAxis.setLabelFont(new Font("黑体",Font.BOLD,14)); //水平底部标题
domainAxis.setTickLabelFont(new Font("宋体",Font.BOLD,12)); //垂直标题
ValueAxis rangeAxis=plot.getRangeAxis();//获取柱状
rangeAxis.setLabelFont(new Font("黑体",Font.BOLD,15));
chart.getLegend().setItemFont(new Font("黑体", Font.BOLD, 15));
chart.getTitle().setFont(new Font("宋体",Font.BOLD,20));//设置标题字体
//到这里结束,虽然代码有点多,但只为一个目的,解决汉字乱码问题
frame1=new ChartPanel(chart,true); //这里也可以用chartFrame,可以直接生成一个独立的Frame
}
private static CategoryDataset getDataSet(int a1,double a2,int b1,double b2,int c1,double c2) {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(a1, "Distance", "先来先服务");
dataset.addValue(a2, "AvgDistance", "先来先服务");
dataset.addValue(b1, "Distance", "最短寻找时间");
dataset.addValue(b2, "AvgDistance", "最短寻找时间");
dataset.addValue(c1, "Distance", "电梯调度");
dataset.addValue(c2, "AvgDistance", "电梯调度");
return dataset;
}
public ChartPanel getChartPanel(){
return frame1;
}
}
<3>界面类
主程序界面类,可能是一个陋习吧,写界面时总是写得太繁琐,控件添加和监听器添加cv写虽然舒服,但代码量过多也不够简洁
import javafx.scene.chart.BarChart;
import javax.swing.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.*;
import java.util.Random;
public class DispathJFrame extends JFrame implements ActionListener{
private JTextField text_array,text_first,text_short,text_elevator;
private JTextField text_in[]=new JTextField[11];
private JTextField text_dis,text_avg,text_time;
private JButton button_enter,button_first,button_short,button_elevator,button_st;
private JLabel label_first,label_short,label_elevator;
private JLabel label_dis,label_avg,label_time;
private JPanel jpanel_1,jpanel_2,jpanel_3,jpanel_4,jpanel_5,jpanel_6;
public DispathJFrame()
{
this.setTitle("移动臂调度");
this.setBounds(500,200,900,500);
this.setBackground(Color.lightGray);
this.setFont(new Font("Arial",Font.BOLD,18));
this.setLayout(new GridLayout(6,1,6,6));
text_array=new JTextField("",55);
text_first=new JTextField("",50);
text_short=new JTextField("",50);
text_elevator=new JTextField("",50);
text_dis=new JTextField("",5);
text_avg=new JTextField("",5);
text_time=new JTextField("",5);
for(int i=0;i<=10;i++){
text_in[i]=new JTextField("",5);
}
button_enter=new JButton("随机生成序列");
button_enter.setFont(new Font("楷体",Font.BOLD,25));
button_enter.addActionListener(this);
button_first=new JButton("演示");
button_first.setFont(new Font("楷体",Font.BOLD,20));
button_first.setVisible(false);
button_short=new JButton("演示");
button_short.setFont(new Font("楷体",Font.BOLD,20));
button_short.setVisible(false);
button_elevator=new JButton("演示");
button_elevator.setFont(new Font("楷体",Font.BOLD,20));
button_elevator.setVisible(false);
button_st=new JButton("输入序列");
button_st.setFont(new Font("楷体",Font.BOLD,20));
button_st.addActionListener(this);
label_first=new JLabel (" 先来先服务序列:");
label_first.setFont(new Font("楷体",Font.BOLD,22));
label_short=new JLabel("最短寻找时间优先序列:");
label_short.setFont(new Font("楷体",Font.BOLD,22));
label_elevator=new JLabel(" 电梯调度序列:");
label_elevator.setFont(new Font("楷体",Font.BOLD,22));
label_dis=new JLabel("移动距离:");
label_dis.setFont(new Font("楷体",Font.BOLD,22));
label_avg=new JLabel("平均寻道长度:");
label_avg.setFont(new Font("楷体",Font.BOLD,22));
label_time=new JLabel("寻道时间:");
label_time.setFont(new Font("楷体",Font.BOLD,22));
jpanel_1=new JPanel();
jpanel_2=new JPanel();
jpanel_3=new JPanel();
jpanel_4=new JPanel();
jpanel_5=new JPanel();
jpanel_6=new JPanel();
jpanel_1.add(button_enter);
jpanel_1.add(text_array);
jpanel_2.add(label_first);
jpanel_2.add(text_first);
jpanel_2.add(button_first);
jpanel_3.add(label_short);
jpanel_3.add(text_short);
jpanel_3.add(button_short);
jpanel_4.add(label_elevator);
jpanel_4.add(text_elevator);
jpanel_4.add(button_elevator);
jpanel_5.add(label_dis);
jpanel_5.add(text_dis);
jpanel_5.add(label_avg);
jpanel_5.add(text_avg);
jpanel_5.add(label_time);
jpanel_5.add(text_time);
jpanel_5.setVisible(false);
for(int i=0;i<=10;i++){
jpanel_6.add(text_in[i]);
}
jpanel_6.add(button_st);
this.add(jpanel_1);
this.add(jpanel_6);
this.add(jpanel_2);
this.add(jpanel_3);
this.add(jpanel_4);
this.add(jpanel_5);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
text_array.setFont(new Font("楷体",Font.BOLD,22));
text_first.setFont(new Font("楷体",Font.BOLD,22));
text_short.setFont(new Font("楷体",Font.BOLD,22));
text_elevator.setFont(new Font("楷体",Font.BOLD,22));
text_dis.setFont(new Font("楷体",Font.BOLD,22));
text_avg.setFont(new Font("楷体",Font.BOLD,22));
text_time.setFont(new Font("楷体",Font.BOLD,22));
for(int i=0;i<=10;i++){
text_in[i].setFont(new Font("楷体",Font.BOLD,22));
}
}
public void actionPerformed(ActionEvent ev){
if(ev.getSource()==button_enter){
int t[]=new int[10];
Random random=new Random();
for(int i=0;i<10;i++)
t[i]=random.nextInt(99)%(99)+1;
int r=random.nextInt(99)%(99)+1;;
Dispath x1=new Dispath(r,10,5,t);
Dispath x2=new Dispath(r,10,5,t);
Dispath x3=new Dispath(r,10,5,t);
String array="";
for(int i=0;i<10;i++)
if(i==9)
array+=t[9]+"。";
else
array+=t[i]+" , ";
text_array.setText(array);
String str1="";
int[] arr1=x1.First();
str1+=r+", ";
for(int i=0;i<10;i++)
if(i==9)
str1+=arr1[9]+"。";
else
str1+=arr1[i]+", ";
String str2="";
int arr2[]=x2.Short();
str2+=r+", ";
for(int i=0;i<10;i++)
if(i==9)
str2+=arr2[9]+"。";
else
str2+=arr2[i]+", ";
String str3="";
int[] arr3=x3.Elevator();
str3+=r+", ";
for(int i=0;i<10;i++)
if(i==9)
str3+=arr3[9]+"。";
else
str3+=arr3[i]+", ";
text_first.setText(str1);
text_short.setText(str2);
text_elevator.setText(str3);
button_first.setVisible(true);
button_short.setVisible(true);
button_elevator.setVisible(true);
button_first.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
jpanel_5.setVisible(true);
text_dis.setText(x1.Distance+"");
text_avg.setText(x1.AvgDistance+"");
text_time.setText(x1.FindTime+"");
new Display(r,arr1);
}
});
button_short.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
jpanel_5.setVisible(true);
text_dis.setText(x2.Distance+"");
text_avg.setText(x2.AvgDistance+"");
text_time.setText(x2.FindTime+"");
new Display(r,arr2);
}
});
button_elevator.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
jpanel_5.setVisible(true);
text_dis.setText(x3.Distance+"");
text_avg.setText(x3.AvgDistance+"");
text_time.setText(x3.FindTime+"");
new Display(r,arr3);
}
});
JFrame frame=new JFrame("Java数据统计图");
frame.setLayout(new GridLayout(1,2,10,10));
frame.add(new Bar(x1.Distance,x1.AvgDistance,x2.Distance,x2.AvgDistance,x3.Distance,x3.AvgDistance).getChartPanel());
frame.setBounds(50, 50, 800, 600);
frame.setVisible(true);
}
else if((ev.getSource()==button_st)){
int z=Integer.parseInt(text_in[0].getText());
int m[]=new int[10];
for(int i=0;i<10;i++){
m[i]=Integer.parseInt(text_in[i+1].getText());
}
Dispath s1=new Dispath(z,10,5,m);
Dispath s2=new Dispath(z,10,5,m);
Dispath s3=new Dispath(z,10,5,m);
String stra1="";
int[] arra1=s1.First();
stra1+=z+", ";
for(int i=0;i<10;i++)
if(i==9)
stra1+=arra1[9]+"。";
else
stra1+=arra1[i]+", ";
String stra2="";
int arra2[]=s2.Short();
stra2+=z+", ";
for(int i=0;i<10;i++)
if(i==9)
stra2+=arra2[9]+"。";
else
stra2+=arra2[i]+", ";
String stra3="";
int[] arra3=s3.Elevator();
stra3+=z+", ";
for(int i=0;i<10;i++)
if(i==9)
stra3+=arra3[9]+"。";
else
stra3+=arra3[i]+", ";
text_first.setText(stra1);
text_short.setText(stra2);
text_elevator.setText(stra3);
button_first.setVisible(true);
button_short.setVisible(true);
button_elevator.setVisible(true);
button_first.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
jpanel_5.setVisible(true);
text_dis.setText(s1.Distance+"");
text_avg.setText(s1.AvgDistance+"");
text_time.setText(s1.FindTime+"");
new Display(z,arra1);
}
});
button_short.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
jpanel_5.setVisible(true);
text_dis.setText(s2.Distance+"");
text_avg.setText(s2.AvgDistance+"");
text_time.setText(s2.FindTime+"");
new Display(z,arra2);
}
});
button_elevator.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
jpanel_5.setVisible(true);
text_dis.setText(s3.Distance+"");
text_avg.setText(s3.AvgDistance+"");
text_time.setText(s3.FindTime+"");
new Display(z,arra3);
}
});
JFrame frame=new JFrame("Java数据统计图");
frame.setLayout(new GridLayout(1,2,10,10));
frame.add(new Bar(s1.Distance,s1.AvgDistance,s2.Distance,s2.AvgDistance,s3.Distance,s3.AvgDistance).getChartPanel());
frame.setBounds(50, 50, 800, 600);
frame.setVisible(true);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new DispathJFrame();
}
}
三、结果显示
最终程序运行图,这张为随机生成序列排序的,随机生成也是用随机生成数函数写的
树形统计图显示
这个是输入序列的,其他都大同小异
折线图