Parma多面体库(PPL)顶点枚举如何启用有理数运算?
解决PPL顶点枚举中获取有理数顶点的问题
嘿,我明白你的困扰——PPL默认用整数运算确实会把你的线段顶点截断成整数,要得到精确的有理数顶点,关键是切换到PPL的有理数类型多面体进行计算,而不是依赖浮点(浮点会有精度风险,PPL的有理数是精确分数运算)。下面一步步给你讲清楚怎么做:
核心要点:切换到有理数类型
PPL的多面体类(比如NNC_Polyhedron或C_Polyhedron)是模板类,默认可能用的是整数类型(比如long long),你需要把模板参数换成PPL::Rational,这样整个计算都会基于精确的有理数进行,不会丢失小数部分。
具体实现步骤
1. 定义有理数多面体
把原来的整数多面体替换成PPL::NNC_Polyhedron<PPL::Rational>(或者C_Polyhedron,根据你的需求是闭多面体还是非闭)。
2. 用精确有理数添加约束
不要直接用浮点数(比如0.3)定义约束,因为浮点数有精度误差,而是用PPL::Rational构造精确分数:
- 0.3 = 3/10 →
PPL::Rational(3, 10) - 3.7 = 37/10 →
PPL::Rational(37, 10)
然后把约束转化为线性表达式,比如x >= 0.3等价于10x - 3 >= 0,这样可以避免浮点数运算。
3. 枚举并输出有理数顶点
使用对应有理数类型的Vertex_Enumerator<PPL::Rational>来遍历顶点,顶点的坐标是PPL::Rational类型,你可以直接输出分数形式,或者转换成double查看小数。
示例代码
#include <iostream> #include <ppl.hh> using namespace PPL; int main() { // 初始化1维的有理数非闭多面体 NNC_Polyhedron<Rational> polyhedron(1); // 构建约束系统:x ≥ 3/10 且 x ≤ 37/10 Constraint_System constraints; // 10x - 3 ≥ 0 → 对应x ≥ 0.3 constraints.insert(Linear_Expression(Rational(10), 0) - Rational(3) >= 0); // 10x - 37 ≤ 0 → 对应x ≤ 3.7 constraints.insert(Linear_Expression(Rational(10), 0) - Rational(37) <= 0); // 将约束添加到多面体 polyhedron.add_constraints(constraints); // 枚举顶点 Vertex_Enumerator<Rational> vertex_enum(polyhedron); std::cout << "精确有理数顶点:" << std::endl; for (; !vertex_enum.end(); ++vertex_enum) { const Point<Rational>& vertex = *vertex_enum; // 输出分数形式和小数形式 std::cout << "顶点坐标:" << vertex[0] << "(小数形式:" << static_cast<double>(vertex[0]) << ")" << std::endl; } return 0; }
编译与运行
编译时记得链接PPL库,比如用g++:
g++ -o ppl_rational_vertices ppl_rational_vertices.cpp -lppl
运行后就能看到输出的精确顶点:3/10(0.3)和37/10(3.7),而不是被截断的整数。
注意事项
- 永远用
PPL::Rational构造精确分数,不要直接传浮点数,否则会引入精度误差,导致约束或顶点不准确。 - 所有相关的类(比如
Linear_Expression、Point、Vertex_Enumerator)都会自动适配Rational类型,不用额外配置,只要模板参数正确即可。
内容的提问来源于stack exchange,提问作者aorthey
相关产品推荐
相关产品推荐

