HydroOJ 从入门到入土(7)Hydro自带数据生成器使用说明(>=4.10.1)(24.06.13更新)

Hydro更新了一个新功能, 可以直接用自带的数据生成器, 在线生成数据, 简单记录一下使用方法

1. 文件准备

  • gen.py / gen.cpp (数据生成器, 后附模版)
  • std.cpp (标准程序, 后附模版)

文件名随意, 其他的类型只要系统支持能执行的都行, 可以自己写, 注意是标准输出, 不需要文件读写, 系统会自动处理.

2. 使用步骤

  1. 将以上两个文件上传到测试数据里
  2. 生成测试数据(Beta)的两个栏里, 分别填上gen.pystd.cpp
  3. 点击生成, 此时会弹出一个界面, running并且generating数据点.
  4. 成功生成完成之后, 检查一下自己的测试数据, 应该已经有若干测试数据了.

3. 注意事项

  1. 生成器只需要生成输入文件, 标准输出, 比如 print
  2. 可以通过读取文件运行的命令行参数 sys argv 来得到当前在生成第几个点, 这样可以根据题目要求控制对应数据规模
  3. 目前默认生成 10 个点, 通过上边第 2 点的数量控制, 可以使数据点生成少于 10 个. 如果需要多于 10 个, 需要修改源码(在这里)
  4. 默认不支持 cyaron, 得自己处理 nix 下的 python 环境, 参考HydroOJ 从入门到入土(10) 配置 nix 支配下的 Python 环境.
  5. 新增了一个 cpp 的模版(2024.06.13),生成大量随机数据时用 cpp 会快点,实测 5mb 级的数据大概比 py 快 5 倍左右(30ms vs 150ms),越大快的越多。

4. 单点数据限制 4mb(2024.06.13)

目前数据生成器的默认单点数据限制是 4mb,控制面板中的 stdio_size 设置对此无效(除非小于 4mb)。

具体原因:源码地址

另根据 undefined 在群内的回复(2024.06.13):“大数据还是本地跑好了传,而不是跑一遍 看一下 再跑一遍,那样流量消耗太大了”。如果 oj 配置的是外部独立评测机,反复生成数据会在评测机和服务器上来回传,大幅增加流量消耗。

如果评测机和 oj 是在同一个服务器上,则不会产生额外流量消耗

手动修改方法:

vi +80 /usr/local/share/.config/yarn/global/node_modules/@hydrooj/hydrojudge/src/sandbox.ts
// 将这行:
const stdioSize = params.cacheStdoutAndStderr ? stdioLimit : 4;

// 改为:
const stdioSize = params.cacheStdoutAndStderr ? stdioLimit : 15;

然后pm2 restart hydro-sandbox hydrooj 生效。

注意不要改太大,因为自测也是这个限制,改大了可能在自测的时候会造成网页卡顿或者消耗更多流量。

5. 文件模版

gen.py

# from cyaron import *
import random
import sys

_n = list(map(int, [0, 1e2, 5e2, 1e3, 1e4, 1e4]))  # 默认生成 10 个点, 数据点不够也没事, 不会生成无效数据
_m = list(map(int, [0, 20, 40, 60, 80, 100]))

k = int(sys.argv[1])  # 读入当前正在生成的数据点编号, 从 1 开始

nums = range(_n[k])
n = random.randint(5, _m[k])
ls = random.sample(nums, n)

for i in range(n):
    ls[i] *= random.choice([-1, 1])

print(n)
print(*ls)

gen.cpp

#include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;


int main(int argc,char *argv[]){
	int i = stoi(argv[1]);
	
	random_device rd;
	mt19937 gen(rd());
	uniform_int_distribution<> t(1, 50);
	uniform_int_distribution<ull> n(11, ull(1e18));
	
	ios::sync_with_stdio(0);
	
	switch (i) {
	case 1 ... 2:
		break;
		case 3 ... 6: 
		t.param(decltype(t)::param_type (1, ull(5e5)));
		n.param(decltype(n)::param_type (11, ull(1e6)));
		break;
		case 7 ... 10: 
		t.param(decltype(t)::param_type (ull(1e4), ull(5e5)));
		n.param(decltype(n)::param_type (ull(1e10), ull(1e18)));
		break;
		
	}
	int tt=t(gen);
	printf("%d\n", tt);
	for (int i = 0; i < tt; i++){
		printf("%lld\n", n(gen));
	}
	
	return 0;
}

std.cpp

#include <bits/stdc++.h>
using namespace std;

int a[110], n;

bool cmp(int a, int b){ return abs(a) > abs(b); }

int main(){
	cin >> n;
	for (int i = 0; i < n; ++i)
		cin >> a[i];

	sort(a, a+n, cmp);

	for (int i = 0; i < n; ++i)
		cout << a[i] << ' ';
	
	return 0;
}
posted @ 2023-12-17 16:48  Bowen404  阅读(1519)  评论(1编辑  收藏  举报