Skip to main content

parse_lp

PyPI version

A LP file format parser, writer, and modifier for Python, powered by Rust.

Features

  • Complete LP Support: Handles all standard LP file format features
  • Problem Modification: Programmatically modify objectives, constraints, and variables
  • LP File Writing: Generate LP files from modified problems with round-trip compatibility
  • Problem Analysis: Comprehensive statistics, structure analysis, and issue detection with configurable thresholds
  • Easy Data Access: Direct access to problem components (variables, constraints, objectives)
  • CSV Export: Export parsed data to CSV files for further analysis
  • Type Safety: Full type hints for better IDE support and development experience

Installation

pip install parse_lp

Quick Start

from parse_lp import LpParser

# Parse an LP file
parser = LpParser("path/to/problem.lp")
parser.parse()

# Access problem information
print(f"Problem: {parser.name}")
print(f"Sense: {parser.sense}")
print(f"Variables: {parser.variable_count()}")
print(f"Constraints: {parser.constraint_count()}")

# Modify the problem
parser.update_objective_coefficient("OBJ", "x1", 5.0)
parser.rename_variable("x2", "production")
parser.update_constraint_rhs("C1", 100.0)

# Write back to LP format
modified_lp = parser.to_lp_string()
parser.save_to_file("modified_problem.lp")

# Analyze problem structure and detect issues
analysis = parser.analyze()
print(f"Matrix density: {analysis['summary']['density']:.4f}")
print(f"Issues found: {len(analysis['issues'])}")

# Export to CSV files
parser.to_csv("output_directory/")

Usage Examples

Basic Parsing and Information

from parse_lp import LpParser

parser = LpParser("optimization_problem.lp")
parser.parse()

# Get problem overview
print(f"Problem Name: {parser.name}")
print(f"Optimization Sense: {parser.sense}")
print(f"Variables: {parser.variable_count()}")
print(f"Constraints: {parser.constraint_count()}")
print(f"Objectives: {parser.objective_count()}")

Accessing Problem Data

# Access objectives
for i, objective in enumerate(parser.objectives):
    print(f"Objective {i+1}: {objective['name']}")
    for coef in objective['coefficients']:
        print(f"  {coef['name']}: {coef['value']}")

# Access variables
for var_name, var_info in parser.variables.items():
    print(f"Variable {var_name}:")
    # var_type carries any bounds inline, e.g. "DoubleBound(0.0, 100.0)"
    print(f"  Type: {var_info['var_type']}")

# Access constraints
for constraint in parser.constraints:
    print(f"Constraint {constraint['name']}:")
    print(f"  Type: {constraint['type']}")
    if constraint['type'] == 'standard':
        print(f"  Operator: {constraint['operator']}")
        print(f"  RHS: {constraint['rhs']}")
        print(f"  Coefficients: {len(constraint['coefficients'])}")

CSV Export

import os

# Create output directory
os.makedirs("output", exist_ok=True)

# Export to CSV files
parser.to_csv("output/")

# Files created:
# - output/variables.csv
# - output/constraints.csv
# - output/objectives.csv

Problem Analysis

Analyze problem structure, detect potential issues, and get comprehensive statistics.

from parse_lp import LpParser

parser = LpParser("problem.lp")
parser.parse()

# Get complete analysis
analysis = parser.analyze()

# Summary statistics
summary = analysis['summary']
print(f"Problem: {summary['name']}")
print(f"Sense: {summary['sense']}")
print(f"Variables: {summary['variable_count']}")
print(f"Constraints: {summary['constraint_count']}")
print(f"Nonzeros: {summary['total_nonzeros']}")
print(f"Matrix density: {summary['density']:.4f}")

# Sparsity metrics
sparsity = analysis['sparsity']
print(f"Variables per constraint: {sparsity['min_vars_per_constraint']} - {sparsity['max_vars_per_constraint']}")

# Variable type distribution
var_types = analysis['variables']['type_distribution']
print(f"Variable types: {var_types}")

# Coefficient ranges
coeffs = analysis['coefficients']
print(f"Constraint coefficients: {coeffs['constraint_coeff_range']}")
print(f"Objective coefficients: {coeffs['objective_coeff_range']}")
print(f"Coefficient ratio: {coeffs['coefficient_ratio']:.2f}")

# Check for issues (warnings and errors)
for issue in analysis['issues']:
    print(f"[{issue['severity']}] {issue['category']}: {issue['message']}")

Analysis with custom thresholds:

# Customize thresholds for issue detection
analysis = parser.analyze_with_config(
    large_coeff_threshold=1e8,      # Flag coefficients above this
    small_coeff_threshold=1e-10,    # Flag coefficients below this
    ratio_threshold=1e5             # Flag if max/min ratio exceeds this
)

Get issues only:

# Get just the detected issues without full analysis
issues = parser.get_issues()

for issue in issues:
    print(f"[{issue['severity']}] {issue['category']}: {issue['message']}")
    if issue['details']:
        print(f"  Details: {issue['details']}")

Issue types detected:

  • Invalid variable bounds (lower > upper)
  • Numerical scaling warnings (large coefficients, high ratios)
  • Empty constraints (no variables)
  • Unused variables (not in any constraint or objective)
  • Fixed variables (lower bound = upper bound)
  • Singleton constraints (only one variable)

Problem Modification

from parse_lp import LpParser

# Parse an existing LP file
parser = LpParser("optimization_problem.lp")
parser.parse()

# Modify objectives
parser.update_objective_coefficient("profit", "x1", 5.0)
parser.rename_objective("profit", "total_profit")

# Modify constraints
parser.update_constraint_coefficient("capacity", "x1", 2.0)
parser.update_constraint_rhs("capacity", 200.0)
parser.rename_constraint("capacity", "production_limit")

# Modify variables
parser.rename_variable("x1", "production_a")
parser.update_variable_type("production_a", "integer")

# Set problem properties
parser.set_problem_name("Modified Optimization Problem")
parser.set_sense("minimize")

# Write back to LP format
modified_lp_content = parser.to_lp_string()
parser.save_to_file("modified_problem.lp")

# Verify round-trip compatibility
new_parser = LpParser("modified_problem.lp")
new_parser.parse()
print(f"Successfully modified and re-parsed: {new_parser.name}")

Objectives Structure

[
    {
        "name": "objective_name",
        "coefficients": [
            {"name": "variable_name", "value": 1.5},
            {"name": "another_var", "value": -2.0}
        ]
    }
]

Variables Structure

{
    "variable_name": {
        "name": "variable_name",
        # Debug-formatted VariableType. Bounds are encoded inline:
        #   "Free", "General", "Binary", "Integer", "SemiContinuous",
        #   "LowerBound(0.0)", "UpperBound(100.0)", "DoubleBound(0.0, 100.0)"
        "var_type": "DoubleBound(0.0, 100.0)"
    }
}

Constraints Structure

[
    {
        "name": "constraint_name",
        "type": "standard",  # or "sos"
        "operator": "LTE",  # "GT", "GTE", "EQ", "LT", "LTE"
        "rhs": 10.0,
        "coefficients": [
            {"name": "variable_name", "value": 2.0}
        ]
    },
    {
        "name": "sos_constraint",
        "type": "sos",
        "sos_type": "S1",  # or "S2"
        "weights": [
            {"name": "var1", "value": 1.0},
            {"name": "var2", "value": 2.0}
        ]
    }
]

Modification Methods

Objective Methods

  • update_objective_coefficient(obj_name, var_name, coefficient) - Update or add coefficient
  • rename_objective(old_name, new_name) - Rename an objective
  • remove_objective(obj_name) - Remove an objective

Constraint Methods

  • update_constraint_coefficient(const_name, var_name, coefficient) - Update or add coefficient
  • update_constraint_rhs(const_name, new_rhs) - Update right-hand side value
  • rename_constraint(old_name, new_name) - Rename a constraint
  • remove_constraint(const_name) - Remove a constraint

Variable Methods

  • rename_variable(old_name, new_name) - Rename variable across problem
  • update_variable_type(var_name, var_type) - Change variable type
  • remove_variable(var_name) - Remove variable from problem

Problem Methods

  • set_problem_name(name) - Set problem name
  • set_sense(sense) - Set optimization sense ("maximize" or "minimize")

Writing Methods

  • to_lp_string() - Generate LP format string
  • to_lp_string_with_options(**options) - Generate with custom formatting
  • save_to_file(filepath) - Save to LP file

Analysis Methods

  • analyze() - Get complete problem analysis including statistics and issues
  • analyze_with_config(large_coeff_threshold, small_coeff_threshold, ratio_threshold) - Analysis with custom thresholds
  • get_issues() - Get only detected issues/warnings without full analysis

Variable Types

Supported variable types for update_variable_type():

  • "binary" - Binary variables (0 or 1)
  • "integer" - General integer variables
  • "general" - General integer variables
  • "free" - Free variables (no bounds)
  • "semicontinuous" - Semi-continuous variables

Supported LP Format Features

  • Multiple objective functions
  • Standard constraints (≤, =, ≥)
  • Variable bounds
  • Variable types (continuous, binary, integer)
  • SOS (Special Ordered Sets) constraints
  • Problem names and comments
  • Scientific notation in coefficients

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Contributing

Issues and pull requests are welcome at: https://github.com/dandxy89/lp_parser_rs

make build
make install
make unit-test

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

parse_lp-4.0.1.tar.gz (1.8 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

parse_lp-4.0.1-cp39-abi3-win_amd64.whl (343.1 kB view details)

Uploaded CPython 3.9+Windows x86-64

parse_lp-4.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (453.9 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

parse_lp-4.0.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (463.6 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARMv7l

parse_lp-4.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (446.1 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

parse_lp-4.0.1-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl (476.9 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.5+ i686

parse_lp-4.0.1-cp39-abi3-macosx_11_0_arm64.whl (419.8 kB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

parse_lp-4.0.1-cp39-abi3-macosx_10_12_x86_64.whl (426.5 kB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file parse_lp-4.0.1.tar.gz.

File metadata

  • Download URL: parse_lp-4.0.1.tar.gz
  • Upload date:
  • Size: 1.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.14.1

File hashes

Hashes for parse_lp-4.0.1.tar.gz
Algorithm Hash digest
SHA256 f2da7ef58bc3333d9ade2aad6cad8e2153b84b7f67ff6d5a14cedee665c451f6
MD5 27aae69a639387c814d9d9945408e874
BLAKE2b-256 f0768241d1ebfeabc60480eb0308c74fb441526c8dab3df86ad2e4fc32468578

See more details on using hashes here.

File details

Details for the file parse_lp-4.0.1-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: parse_lp-4.0.1-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 343.1 kB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.14.1

File hashes

Hashes for parse_lp-4.0.1-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 f6423d428518967d91654a2d0c24600af4a99a6c8156a4c52ef9d4e26221fb99
MD5 691df133371e16200b5731a15254aace
BLAKE2b-256 a60207783d980fff728a93478899f7a8c0c3d68b86fe048c7e0c3b2ff2596510

See more details on using hashes here.

File details

Details for the file parse_lp-4.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for parse_lp-4.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 123c8c1a148fd07e7173363ae5b21890bc7fcd1490ae8b3b4a6e957d47380817
MD5 79dca8b38b8bc7f6915220caff6380ee
BLAKE2b-256 5c41df4c57316a5f009d9dcd32e4a101e8d3a7fdf5881497d4b161113a235d37

See more details on using hashes here.

File details

Details for the file parse_lp-4.0.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for parse_lp-4.0.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 3548422fe8698bb51b5c9a36e62967dc604b441eab13b54fc6f4e1349ef231ba
MD5 40571f25fa76a65d1cb430d6878d19a9
BLAKE2b-256 905d37bfa572b6676f0e9e292df5a110006844b9af65a9a5816cd00b4e2bfb89

See more details on using hashes here.

File details

Details for the file parse_lp-4.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for parse_lp-4.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 7d7f67c47e39650b9354dd96de357905d48b49eaa5e13db22557c234ff904e71
MD5 83e9f0e7e43f174124f30d1c720d0feb
BLAKE2b-256 f1bdd8f0a435b5b463452cbbc0c305c43490203abd3832c51f9eed80f0c7a548

See more details on using hashes here.

File details

Details for the file parse_lp-4.0.1-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl.

File metadata

File hashes

Hashes for parse_lp-4.0.1-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl
Algorithm Hash digest
SHA256 ce88ac8f6657ac7a4829fc02fd7d80f7568f826ea38487cf510438114af47512
MD5 f815dabb05e9f861af6ffcb07306f010
BLAKE2b-256 b791f7fa9eb433f59fe493f376db6e8e545a0a43dd421a7819cc19ee050dce53

See more details on using hashes here.

File details

Details for the file parse_lp-4.0.1-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for parse_lp-4.0.1-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fa21c6c7c9cc0ac92d946f9637aae208758c36d11b0eee6098f8b6ffa05e993e
MD5 7af18d33e98f63a3e9576a1618c8d0b1
BLAKE2b-256 330436bb1d814282481c4ef1c0583d4725247c8fe1e335d2c5e7b8f3ebcee898

See more details on using hashes here.

File details

Details for the file parse_lp-4.0.1-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for parse_lp-4.0.1-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 4176418ce7e0f28b1ef2bf1c8f879e6e70e0b91047a98550ce85e1316fd4af4f
MD5 5a05f975c868943f869eb47c4d7be155
BLAKE2b-256 89119ecc5175411a07a73a87ce2c94e5cc52991e1f251d67d3d5b6a9a489076b

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

4.0.1 This release

8 files

3.3.0

12 files

3.2.0

12 files

3.1.0

12 files

3.0.3

12 files

3.0.2

12 files

3.0.0

12 files

2.6.2

12 files

2.6.1

12 files

2.6.0

11 files

2.5.0

11 files

2.4.3

11 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page