FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browser

Python notebooks

Description

Python notebooks available in the GitHub repository python-notebooks.


pythonnotebooks.zip[download all files]

Source Files





load_problem.ipynb

{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **Comparing the low-level API function *loadproblem()* with high-level API functions in model building time performance**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***load_problem.ipynb***\n",
    "\n",
    "This example uses the *time* package to measure the differences in model building performance between the low-level API [p.loadproblem()](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.loadproblem.html) and the higher level API functions [p.addConstraint()](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.addConstraint.html) and [p.setObjective()](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.setObjective.html) for a randomly created problem.\n",
    "\n",
    "© Copyright 2025 Fair Isaac Corporation\n",
    "\n",
    "Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.\n",
    " \n",
    "Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n",
    "\n",
    "This example uses FICO® Xpress software. By running it, you agree to the Community License terms of the [Xpress Shrinkwrap License Agreement](https://community.fico.com/s/contentdocument/06980000002h0i5AAA) with respect to the FICO® Xpress software. See the [licensing options](https://www.fico.com/en/fico-xpress-trial-and-licensing-options) overview for additional details and information about obtaining a paid license."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Install the xpress package\n",
    "%pip install -q xpress"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The [p.loadproblem()](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.loadproblem.html) function provides a low-level interface to the FICO® Xpress Optimizer libraries. It is the preferable option for very large problems and when efficiency in model creation is crucial, although it **may require extra modeling effort, and it is typically harder to maintain**. The low-level interface can be used to create problems with linear/quadratic constraints, a linear/quadratic objective function, and with continuous/discrete variables.\n",
    "\n",
    "Other API functions such as [p.addrows()](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.addrows.html), [p.addcols()](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.addcols.html) or [p.addpwlcons()](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.addpwlcons.html) can also be used at the low level to enhance efficiency in model building performance."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Data generation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Start by importing the necessary packages and create randomly sampled data for the problem with **1 million variables and constraints**. \n",
    "\n",
    "Read the comments after each data object creation for a description of the arguments needed for the low-level API function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import xpress as xp\n",
    "import numpy as np\n",
    "import time\n",
    "import random\n",
    "\n",
    "rndseed = 10\n",
    "random.seed(rndseed)\n",
    "\n",
    "# Variables and Constraints\n",
    "V=1000000\n",
    "C=1000000\n",
    "\n",
    "# Generate random data\n",
    "rowtype = ['G' for i in range(C)]                           # Character array containing row types\n",
    "rhs = [random.randint(0, 100) for _ in range(C)]            # Right hand side coefficients of the rows\n",
    "obj = np.array([random.randint(0, V) for i in range(V)])    # Objective function coefficients\n",
    "start = [s*2 for s in range(V+1)]                           # Offsets in the rowind and rowcoef arrays of the start of the elements for each column\n",
    "rowind = [j for _ in range(2*(int(V/C))) for j in range(C)] # Row indices for the nonzero elements\n",
    "rowcoef = [random.randint(1,5) for _ in range(start[-1])]   # Nonzero coefficients; length as for rowind\n",
    "lb = [0 for _ in range(V)]                                  # Lower bound\n",
    "ub = [random.randint(50, 100) for _ in range(V)]            # Upper bound"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Low-level API with [p.loadproblem()](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.loadproblem.html)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now use the low-level API [p.loadproblem()](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.loadproblem.html) to build the model, measuring the total time taken by recording a time stamp right before and after the call to the function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# LOW LEVEL API\n",
    "p = xp.problem(\"low-level\")\n",
    "\n",
    "start_t = time.time() # records start time\n",
    "p.loadproblem(\"lowlevel\",\n",
    "              rowtype,\n",
    "              rhs,\n",
    "              None,\n",
    "              obj,\n",
    "              start,\n",
    "              None,\n",
    "              rowind,\n",
    "              rowcoef,\n",
    "              lb,\n",
    "              ub)\n",
    "end_t = time.time() # record end time\n",
    "print(f\"\\nModel building time with low-level api: {(end_t-start_t)} secs.\")\n",
    "\n",
    "# p.write(\"lowlevel\", \"lp\")\n",
    "# p.optimize()\n",
    "# print(\"Objective value w/ low-level api:\", p.attributes.objval)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## High-level API functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The cell below builds exactly the same model, but using the higher level API functions [p.addConstraint()](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.addConstraint.html) and [p.setObjective()](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.setObjective.html), after getting the proper expressions from the same data objects.\n",
    "\n",
    "The time needed to extract the data from the previous data objects (and are not part of the model building process) is excluded from the time recording, which only includes creation of variables, constraints and objective.\n",
    "\n",
    "Run the code cell below and compare the time taken to build the model with the time previously recorded for the low-level API function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# HIGH LEVEL API\n",
    "p = xp.problem(\"high-level\") # re-set problem\n",
    "\n",
    "start_t = time.time() # records start time\n",
    "x = np.array([p.addVariable(lb=0, ub=ub[i]) for i in range(V)])\n",
    "end_t = time.time() # record end time\n",
    "time1 = end_t-start_t\n",
    "\n",
    "# Get constraint expressions from above data\n",
    "expr = [0 for _ in range(C)]\n",
    "cnt = 0\n",
    "for j in start[:len(start)-1]:\n",
    "    for i in range(start[cnt],start[cnt+1]):\n",
    "        expr[rowind[i]] += rowcoef[i] * x[cnt]\n",
    "    cnt += 1\n",
    "\n",
    "start_t = time.time() # records start time\n",
    "p.addConstraint(expr[i] >= rhs[i] for i in range(C))\n",
    "p.setObjective(xp.Dot(obj,x))\n",
    "end_t = time.time() # record end time\n",
    "time2 = end_t-start_t\n",
    "print(f\"Model building time with high-level api: {(time1+time2)} secs.\")\n",
    "\n",
    "# p.write(\"highlevel\", \"lp\")\n",
    "# p.optimize()\n",
    "# print(\"Objective value w/ high-level api:\", p.attributes.objval)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}

Back to examples browser