基于JavaGUI的高校教务排课管理系统设计与实现

目录
基于着色理论的排课问题研究 1
一、绪论 1
(一)、研究背景和意义 2
(二)、国内外研究现状 2
1.国外研究现状 2
2.国内研究现状 3
(三)、本文主要任务 3
二、图论基本概念和理论 4
(一)图的分类 4
(二)、着色理论 5
1.图的染色 5
三、 排课问题算法分析与比较 6
1.动态规划法 6
2.模拟退火算法 7
3.遗传算法 7
4.蚁群算法 8
5.禁忌搜索算法 8
四、排课问题研究 9
(一)、排课问题因素 9
(二)、排课约束条件 9
(三)、排课问题的求解目标 10
(四)、基于着色理论的排课算法及实例 10
1.教师与班级建立关系图 10
2.边着色理论分配时间 11
3.实例 13
4.排课模型图的优化 16
5.排课模型图的赋值 16
五、Java编程实现排课问题的解决 17
1.设计过程 17
2.效果截图 23
五、总结与展望 25
(三)、本文主要任务
本文从排课问题的研究背景、意义及研究现状,分析排课问题的必要性,研究探讨了几种解决排课问题的算法,结合实例分析比较它们的优点和缺点,最终结合图论着色理论给出一种排课算法。
第一章绪论。介绍本文的研究背景及意义、排课问题研究现状和本文研究内容。
第二章图论基本概念和理论。概述图论有关概念以及着色理论,包括图的分类、点染色、边染色和全染色等着色理论。
第三章排课问题算法分析与比较。分析研究几种经典的排课问题算法,比较其优缺点。
第四章排课问题研究。分析排课问题因素和约束条件,并且结合学校排课实例给出图染色排课算法的应用,解决教师、班级、教室的时间冲突现象。
第五章总结与展望。总结本文工作,指出本文研究不足之处,以及下一步要做的进一步研究工作。
二、图论基本概念和理论
(一)图的分类
1.无向图:边集E(G)为无方向边的集合,任意一条边都代表u连v,以及v连u,每条边都是双向的。如图1所示。
2.有向图:边集E(G)为有方向边的集合,每条边都是单向的,即只能由一个点指向另一个点。如图2所示。
3.带权图:边集E(G)是每条边上有权值的边的集合,同理,带权图也有有向带权图和无向带权图之分,当然,不加权的图可以看成所有边上的权值都是 1。如图3
4.完全图:对于图中任意两个顶点都是相邻的,称之为完全图,如图4所示。
5.无向完全图:在阶无向图中,图中任意两个顶点间都有一条边相连,则该图称为无向完全图,如图4所示。
6.有向完全图:在阶有向图中,图中任意两个顶点间都有方向相反的边相连,该图称为有向完全图,如图5所示。
7.二部图:设无向图图中,如果图中顶点集 V 可划分为两个互不相交的非空子集X和Y,并且图中的每条边有一个端点属于子集X,另一个端点属于子集Y,则称图G为一个二部图,如图6所示。
8.简单图:在无向图中,如果关联一对顶点的无向边多于一条,则称这些边为平行边,平行边的条数称为重数。而自环是两端连接着同一端点的边,那么既无环也无平行边的图就是简单图。

package view;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableCellRenderer;

import clazz.ClassRoom;
import clazz.Course;
import clazz.CourseForm;
import clazz.Teacher;
import clazz.Class;

import javax.swing.JLabel;
import javax.swing.JOptionPane;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Random;

import java.util.Set;

import javax.swing.JButton;
import javax.swing.JSpinner;
import javax.swing.JTextField;

/**
 * @author WeiPingLiu 排课显示主界面
 */
public class Show extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private JPanel contentPane;
	private static LinkedList<Class> classList = new LinkedList<>();
	private static LinkedList<ClassRoom> classroomList = new LinkedList<>();
	private static LinkedList<Course> courseList = new LinkedList<>();
	private static LinkedList<Teacher> teacherList = new LinkedList<>();
	private static Set<String> preCouse = new HashSet<>();
	private static Set<String> having_preCourse = new HashSet<>();
	private static LinkedList<String> temList1;
	private static LinkedList<String> temList2;
	private JTextField textField;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Show frame = new Show();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public Show() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 461, 371);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		JLabel Label1 = new JLabel("排课程序");
		Label1.setFont(new Font("造字工房言宋(非商用)常规体", Font.PLAIN, 38));
		Label1.setBounds(148, 27, 165, 72);
		contentPane.add(Label1);

		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(
					new FileInputStream(new File("src/data/Class.txt")), "GBK"));
			String line;
			while ((line = br.readLine()) != null) {
				String[] result = line.split(" ");
				classList.add(new Class(Integer.parseInt(result[0]), result[1],
						Integer.parseInt(result[2])));
			}
			br = new BufferedReader(new InputStreamReader(new FileInputStream(
					new File("src/data/ClassRoom.txt")), "GBK"));
			while ((line = br.readLine()) != null) {
				String[] result = line.split(" ");
				classroomList.add(new ClassRoom(Integer.parseInt(result[0]),
						result[1], Integer.parseInt(result[2])));
			}
			br = new BufferedReader(new InputStreamReader(new FileInputStream(
					new File("src/data/Course.txt")), "GBK"));
			while ((line = br.readLine()) != null) {
				String[] result = line.split(" ");
				courseList.add(new Course(Integer.parseInt(result[0]),
						result[1], Integer.parseInt(result[2])));
				for (int i = 3; i < result.length; i++) {
					courseList.getLast().precourse.add(result[i]);
					preCouse.add(result[i]);
					having_preCourse.add(result[1]);
				}
			}
			br = new BufferedReader(new InputStreamReader(new FileInputStream(
					new File("src/data/Teacher.txt")), "GBK"));
			while ((line = br.readLine()) != null) {
				String[] result = line.split(" ");
				teacherList.add(new Teacher(Integer.parseInt(result[0]),
						result[1]));
				for (int i = 2; i < result.length; i++) {
					if (result[i].length() == 1 && result[i].charAt(0) <= 'z'
							&& result[i].charAt(0) >= 'a') {
						teacherList.getLast().getSq().getList()
								.remove(result[i].charAt(0) - 'a');
					} else
						teacherList.getLast().teachCourse.add(result[i]);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		JButton Button1 = new JButton("开始排课");
		Button1.setBounds(100, 100, 100, 27);
		contentPane.add(Button1);

		JButton Button2 = new JButton("指定学期课表");
		Button2.setBounds(210, 151, 140, 27);
		contentPane.add(Button2);

		JButton Button3 = new JButton("指定老师课表");
		Button3.setBounds(211, 207, 139, 27);
		contentPane.add(Button3);

		JButton Button4 = new JButton("所有学期课表");
		Button4.setBounds(102, 261, 248, 27);
		contentPane.add(Button4);

		JButton Button5 = new JButton("退出程序");
		Button5.setBounds(237, 100, 113, 27);
		contentPane.add(Button5);

		final JSpinner spinner1 = new JSpinner(new SpinnerNumberModel(1, 1, 5,
				1));
		spinner1.setBounds(100, 152, 80, 24);
		contentPane.add(spinner1);

		textField = new JTextField();
		textField.setBounds(100, 208, 86, 24);
		contentPane.add(textField);
		textField.setColumns(10);

		Button1.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				System.out.println("排课中。。。");
				Arranging();
				System.out.println("排课成功。");
				JOptionPane.showMessageDialog(contentPane, "排课成功", "成功", 1);
			}
		});

		Button2.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				int number = (int) spinner1.getValue();
				showClass(number);
			}
		});

		Button3.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				String name = textField.getText();
				showTeacher(name);
			}
		});

		Button4.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				for (Class x : classList) {
					ShowAll(x.observed, x.getName() + "的班级课表");
				}
			}
		});

		Button5.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				System.exit(0);
			}
		});
	}

	/**
	 * @param grade
	 * 显示班级学期的课程表
	 */
	private static void showClass(int grade) {
		for (Class x : classList) {
			if (x.getGrade() == grade) {
				ShowAll(x.observed, x.getName() + "的班级课表");
				return;
			}
		}

	}

	/**
	 * @param teachername
	 * 显示老师的课程表
	 */
	private static void showTeacher(String teachername) {
		for (Teacher x : teacherList) {
			System.out.println(x.getName());
			if (x.getName().equals(teachername)) {
				ShowAll(x.observed, x.getName() + "的课表");
				// return;
			}
		}
	}

	/**
	 * @param list
	 * @param string
	 * 显示所有学期的课程表
	 */
	private static void ShowAll(String[] list, String string) {
		JFrame frame = new JFrame(string);
		JTable table = new JTable(new CourseForm(list));
		// 设置表数据居中显示
		DefaultTableCellRenderer cr = new DefaultTableCellRenderer();
		cr.setHorizontalAlignment(JLabel.CENTER);
		table.setDefaultRenderer(Object.class, cr);
		table.setRowHeight(120);
		JScrollPane pane = new JScrollPane(table);
		frame.getContentPane().add(pane);
		// frame.pack();
		frame.setSize(1200, 600);
		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frame.setVisible(true);
	}

	/**
	 * 开始排课
	 */
	private static void Arranging() {
		//contains(),该方法是判断字符串中是否有子字符串。如果有则返回true,如果没有则返回false。
		for (Course cou : courseList) { // for循环遍历课程集合
			Teacher tea = null; // 老师实体类初始化
			Class cla = null; // 班级实体类初始化
			// 将set对象集合的内容作为条件进行分支判断
			if (preCouse.contains(cou.getName())) {
				for (Class x : classList) {	//遍历班级对象
					if (x.getGrade() == 1) {
						cla = x;
						break;
					}
				}
				for (Teacher x : teacherList) {	//遍历教师对象
					if (x.teachCourse.contains(cou.getName())) {
						tea = x;
						break;
					}
				}

				order(tea, cla, cou);

			} else if (having_preCourse.contains(cou.getName())) {
				int max = 0;
				for (Class x : classList) {	//遍历班级对象
					if (x.getSq().getList().size() > max && x.getGrade() != 1) {
						cla = x;
						max = x.getSq().getList().size();
					}
				}
				for (Teacher x : teacherList) {	//遍历教师对象
					if (x.teachCourse.contains(cou.getName())) {
						tea = x;
						break;
					}
				}
				order(tea, cla, cou);
			} else {
				int max = 0;
				for (Class x : classList) {	//遍历班级对象
					if (x.getSq().getList().size() > max) {
						cla = x;
						max = x.getSq().getList().size();
					}
				}
				for (Teacher x : teacherList) {	//遍历教师对象
					if (x.teachCourse.contains(cou.getName())) {
						tea = x;
						break;
					}
				}
				//调用排课算法
				order(tea, cla, cou);
			}
		}
	}

	// 从LinkedList<String>中随机取出timesPerWeek个元素组成的LinkedList<String>
	private static LinkedList<String> randList(LinkedList<String> list,
			int timesPerWeek) {
		LinkedList<String> subList = new LinkedList<String>();
		Random rand = new Random();
		int j = 0;
		while (true) {
			String m = list.get(rand.nextInt(list.size()));

			if (!subList.contains(m)) {
				subList.add(m);
				j++;
			}
			if (j == timesPerWeek) {
				break;
			}
		}
		return subList;
	}

	/**
	 * @param te 教师对象
	 * @param cl 班级对象
	 * @param co 课程对象
	 * 排序算法
	 */
	@SuppressWarnings("unchecked")
	private static void order(Teacher te, Class cl, Course co) {
		temList1 = (LinkedList<String>) (te.getSq().getList().clone());	//temList1存放原教师空闲时间
		te.getSq().getList().retainAll(cl.getSq().getList());	//求教师与学生时间交集  
		if (te.getSq().getList().size() < co.getTimesWeek()) {
			JOptionPane.showMessageDialog(null, "老师和同学公共可利用时间不足安排", "安排失败", 1);
			System.out.println("老师和同学公共可利用时间不足安排" + co.getName());
		}
		temList2 = randList(te.getSq().getList(), co.getTimesWeek());	//temList2存放教师与学生时间交集,取出教师和学生的一定次数的随机组合  
		cl.getSq().getList().removeAll(temList2);	//移去被分去的时间  
		te.getSq().setList(temList1);	//恢复temList1中时间  
		te.getSq().getList().removeAll(temList2);	//移去被分去的时间
		// System.out.println(cl.getSq().getList().size());
		for (String x : temList2) {
			int max = 1000;
			ClassRoom selectRoom = null;
			for (ClassRoom y : classroomList) {	//课程教室地点分配,循环遍历教室对象
				if (y.getSq().getList().contains(x)
						&& y.getCapacity() - cl.getSum() < max
						&& y.getCapacity() - cl.getSum() >= 0) {	//将集合内的对象进行比较
					max = y.getCapacity() - cl.getSum();
					selectRoom = y;
				}
			}
			if (selectRoom != null) {
				selectRoom.getSq().getList().remove(x);
			} else {
				System.out.println("教室资源不够。");
				JOptionPane.showMessageDialog(null, "教室资源不够。", "提示", 1);
				return;
			}
			//向教师实体类中的数组存入排课后的信息内容
			te.observed[x.charAt(0) - 'a'] = co.getName() + " " + cl.getName()
					+ " " + selectRoom.getName();
			cl.observed[x.charAt(0) - 'a'] = co.getName() + " " + te.getName()
					+ " " + selectRoom.getName();
		}
	}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shejizuopin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值