Skip to content
SECTLPublic

About

PokeSeats 戳座:基于约束求解的排座桌面应用

Resources

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

PokeSeats 戳座

PokeSeats 是一个给老师排座位的桌面小程序。你把花名册、教室布局和几条座位规则交给它,它用约束求解算出一份满足全部规则的座位表。

排座位这件事本身不难,难的是规则一多就互相打架:既要照顾视力差的学生坐前排,又要把两个爱说话的分开,还得保证每组人数均衡。手工排完往往顾此失彼。PokeSeats 把这堆要求写成明确的约束,交给 OR-Tools CP-SAT 求解并优化;如果证明无解,再调用 Z3 提取 UNSAT 核心,告诉你哪几条规则凑在一起导致了冲突。

它现在能做什么

  • 从 Excel 导入花名册,按姓名、学号、全拼或拼音首字母搜索学生。
  • 用网格画出教室:学生座位、讲台、主走道(宽过道)、行间过道(窄过道),行列数 1 到 32 可调。
  • 编写四类规则:固定某人坐某位、限定某人只能坐某个区域、指定两名学生的相对位置、限制某排或某列的人数。
  • 一键求解,在满足全部规则的前提下优先让空座靠后,再让空座左右均匀分散,并按教室布局显示姓名和行列位置。
  • 无解时标红导致冲突的那几条规则。

求解先满足全部硬规则,再按优先级优化空座:先最小化空座距最后一排的总距离;在这个目标最优的方案中,再让空座沿左右方向均匀分散。后排能容纳全部空座时,不会为了左右分散而把空座移到前排。横向均匀按各列边界左侧累计空座数与理想均匀分布的偏差衡量,走道保留实际宽度;固定座位、区域、相对位置和人数规则始终优先。没有空座时只求可行解。

界面默认使用 OR-Tools CP-SAT 进行排座及空座优化,仅在 CP-SAT 判定无解时调用 Z3 定位冲突规则;预检查拒绝或求解异常不触发 Z3。Core 同时支持 Z3 与 CP-SAT,两套后端使用相同的空座目标。这个优化不保证学生之间的其他公平性,也不保证多次排座得到不同结果。

运行要求

Linux 下理论上可以运行,界面部分共用同一套代码,但我还没实际验证过。Android 在计划中,目前还不能用。

上手流程

下载或自行发布后运行 PokeSeats.UI.exe,按下面的顺序操作:

  1. 学生名单 —— 点"浏览文件"选择 Excel,解析表头后指定哪一列是姓名、哪一列是学号(学号可不填),确认导入。也可以手动增删。名单会记住,下次打开自动载入。
  2. 教室布局 —— 按住左键拖出一个矩形,松开后选择这片区域是什么(课桌、讲台、宽过道、窄过道、空白);右键可以单独改一格。教室前方朝上。
  3. 规则编辑 —— 先在左上角选规则类型,再挑学生、填条件。右侧列出已保存的规则,点一下就能改,也能删除。
  4. 开始自动排座 —— 菜单栏里的命令,会打开"排座结果"面板。求解在后台进行,期间可以继续操作。

改完名单、布局或规则之后需要重新排一次;结果面板会提示你当前显示的是旧结果。

四类规则

类型 说明
固定特定座位 某位学生必须坐在指定的那张课桌上
限定就座区域 某位学生只能坐在(或不能坐在)框选出的区域内
学生相对位置 指定两名学生之间的方位关系,见下
单排行列人数 限制某一排或某一列上坐多少人,可以只设下限、只设上限或设成固定值

相对位置支持这些关系:指定相对偏移(比如"坐在正后方第二排")、坐在正前方/正后方/正左侧/正右侧、安排在同一排/同一列、相邻就座。方向类关系只管方向,不限距离——"坐在正后方"包含正后方任意一排。

相对位置和区域规则都可以勾选"反向限制"。例如把"相邻"变成"不相邻",或者把"只能坐在这一片"变成"不许坐这一片"。

相邻的三种范围

相邻就座可以选横向、四向或八向:

  • 横向 —— 同一排的左右邻座。
  • 四向 —— 前后左右四个方向的邻座。
  • 八向 —— 再加上斜对角的四个位置。

两侧只隔着一条窄过道的课桌也算相邻。也就是说,横排中间开一条行间过道,过道两边的同桌关系不会断。宽过道不算,连续两三格的空隙也不算。

抽象的相对位置画布上没有过道,所以那里只显示直接紧邻的位置;实际教室预览、预检查和求解都按上面这套规则来。

数据存放位置

名单、布局和规则都保存在本地:

%LOCALAPPDATA%\PokeSeats\plugins\pokeseats.defaultpayload\
  students.json    花名册
  layout.json      教室布局
  rules.json       排座规则

都是明文 JSON,可以直接备份、复制到另一台机器,或者手工改。删掉文件等于恢复空白状态。排座结果不会写入磁盘,关掉程序就没了——需要留档的话自己截图或抄下来。

最近一次选择的工作区记录在 %LOCALAPPDATA%\PokeSeats\selected-workspace.txt。

从源码构建

需要 .NET SDK 6.0 或更高的 6.x 版本(仓库里的 global.json 会自动选版本)。首次构建会从 NuGet 拉取 Z3 和 OR-Tools,需要联网。

构建和运行:

dotnet build PokeSeats.sln
dotnet run --project PokeSeats.UI

注意 dotnet run --project PokeSeats.UI 只构建界面工程本身,不会顺带部署内置插件。所以第一次跑要么先执行上面的解决方案构建,要么运行加 --no-build 使用已有产物。

发布:

dotnet publish PokeSeats.UI -c Release

发布输出在 PokeSeats.UI/bin/Release/net6.0/,整个目录拷走即可运行。求解器依赖的原生库只有 64 位版本,构建目标固定为 x64。

项目结构

PokeSeats.IR              规则、人员、网格的数据结构和基础类型
PokeSeats.Core            预检查、图距离分析、Z3 / CP-SAT 求解
PokeSeats.UI.PluginContracts  插件接口和共享的界面缩放
PokeSeats.UI              桌面宿主:窗口、渲染、插件发现、工作区切换
PokeSeats.UI.DefaultWorkspace 默认工作区(菜单栏和面板布局)
PokeSeats.UI.DefaultPayload   业务面板:名单、布局、规则、排座结果
PokeSeats.UI.TestPlugin   插件开发用的示例,不随程序发布

PokeSeats.UI 只是一个宿主。界面内容全部来自插件,默认工作区加上默认业务面板才是你看到的样子。想自己写插件看 PokeSeats.UI/PLUGIN.md。

字体

界面使用 HarmonyOS Sans SC,字体已随程序打包,不需要额外安装。字体版权归华为所有,按 HarmonyOS Sans Fonts License Agreement 使用,许可证文本随程序一起分发(LICENSE_Fonts),程序内的"关于"对话框也有署名。

版权与许可

Copyright (c) 2025-2026 SECTL Studio & chenjintang-shrimp

本项目以 GNU General Public License 第 3 版或更高版本(GPL-3.0-or-later)发布,完整协议文本见 LICENSE。你可以自由使用、修改和分发,包括商用;分发修改后的版本时需要一并提供源码,并保留版权声明。

第三方依赖的许可证:Z3、Dear ImGui/ImGui.NET、Silk.NET、pinyin4net 为 MIT;OR-Tools、NPOI、SixLabors.Fonts 为 Apache-2.0。HarmonyOS Sans 字体单独适用字体许可,见上一节。

About

PokeSeats 戳座:基于约束求解的排座桌面应用

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages