OptQuest

Documentation

Request a Trial License

OptQuest 10.2.0


Documentation (HTML)


Release Notes:


New Variable Types, OptQuest with AI Coding Agents, New Features, and Performance Improvements!

OptQuest 10.2 adds more than sixty new functions that declare new variables types. With each one, you can declare a common kind of decision in one call, such as an order of jobs, a route through a network or a smooth schedule. OptQuest 10.2 also adds guides and API calls for AI coding agents, two new search features and two changes to the search algorithm. These notes highlight the additions, changes and deprecations.

New Variable Types

OptQuest 10.2 adds three new families of variable types: special purpose variables, container variables and random variables.

Special Purpose Variables

A special purpose variable is a custom variable type that enables an analyst to efficiently model a wide array of specific application area use cases. Inside OptQuest, new algorithms are included to efficiently solve optimization problems involving each of these new variable types without requiring any special handling, additional constraints, or extra logic from the analyst.

A special purpose variable holds one decision that has a structure, such as an order of items, a set of links between nodes or a point inside a region. In every solution that OptQuest generates, the values are feasible and constrained to the set. You do not add constraints, penalties, or repair logic to your model to keep those rules. OptQuest uses a search method made for each type.

Combinatorial variables
  • Mixture. A mixture variable is a set of weights, one for each component, that add up to a total that you set. Each component has its own lower and upper bound. A lower bound can be negative, for short positions or net flows.
    • Example: Set portfolio weights for stocks, bonds and cash. Stocks are from -20% to 70%, bonds from 0% to 60% and cash from 10% to 80%.
  • Item Selection. An item selection variable selects exactly k of n items, or from k to j of n items. OptQuest adds the count rule to the model as a constraint. You can add your own constraints between the items.
    • Example: Select 5 servers from a pool of 10.
    • Example: Select from 5 to 7 servers from a pool of 10, where servers 1 and 2 cannot both be selected.
  • Budgeted Selection. A budgeted selection variable selects items whose total cost stays within a budget. You can also set a smallest total cost and a range for the number of items.
    • Example: Select from 5 to 7 of 15 possible projects with a capital budget from $1.5M to $2M.
  • Choice. A choice variable selects one option from a list of options that have no order. It replaces the design variable, which is now deprecated.
    • Example: Choose one casting process from six available methods.
  • Multi-Choice. A multi-choice variable selects from a minimum to a maximum number of items from a list of named items. If there are rules between the items, such as “if item 1 is selected, you can’t pick item 2 or 3”, use Item Selection. If the only rule is a count range, such as “pick 3 to 5”, OptQuest finds the best selection sooner with Multi-Choice.
    • Example: Pick 2 to 4 preferred suppliers from a list of vendors.
  • Assignment. An assignment variable puts each of M items into one of N bins. You can require that every item is assigned, and you can set a smallest and a largest number of items for each bin.
    • Example: Assign 8 production jobs to 4 machines. Every job must be assigned, and each machine gets no more than 3 jobs.
  • Partition. A partition variable divides M items into exactly K groups. No group is empty, and the groups have no labels. Use it for clustering, team formation and districting.
    • Example: Divide 20 employees into 3 regional teams.
  • Sequence. A sequence variable is an order of N items. It can rank all of the items, or only the top k items and leave the others unranked. It replaces the permutation variable, which is now deprecated.
    • Example: Rank the top 5 candidates from 50 applicants.
    • Example: Sequence 10 jobs for the production line.
  • Multi-Stage Sequence. A multi-stage sequence variable is one order of items for each stage of a process.
    • Example: Rank 5 jobs at each of three production stations. A solution is three rankings, one for each station.
  • Policy Sequence. A policy sequence variable ranks items by a score. You give a table of feature values for the items, such as the due date, the expected profit and the machines that each job needs. OptQuest searches for one weight for each feature. The score of an item is the sum of its feature values multiplied by their weights. OptQuest reports the weights with the ranking, so you can see which features matter, and you can use the same weights to score new items.
    • Example: Find a dispatch order for a set of jobs from their due dates, expected profits, inventory use and machine needs.
  • Topological Sequence. A topological sequence variable is an order of items that satisfies the precedences that you give, such as “task A comes before task B”.
    • Example: Order the steps of a construction project, where some steps must finish before others start.
  • Path. A path variable is a route through some of a set of named nodes, where no node appears twice. You can fix the start node and the end node, and you can give nodes that the path must visit.
    • Example: A route from point A to point B through a set of 20 possible stops, 3 of which are required.
  • DAG. A DAG variable is a set of one-way links between named nodes, with no loop. This structure is a directed acyclic graph (DAG). You can set these options:
    • A start node, which has no incoming link.
    • An end node, which has no outgoing link.
    • A connected option. With it, every node can be reached from the start node, and every node can reach the end node.
    • Precedences, such as “node B comes after node A”. There is no path from a node to one of its predecessors.
    • Example: Design a supply network from a factory to a distribution center that has the lowest cost, the highest throughput or the most robustness.
  • Tree. A tree variable is a hierarchy that connects every node. One node is the root, and every other node has exactly one parent. This structure is a directed spanning tree. You can fix the root node. You can also give precedences: a node never comes above one of its predecessors in the tree.
    • Example: Design a network backbone that connects regional offices, with headquarters as the root.

Geometric variables
  • Region. A region variable is a point (x, y) inside a polygon on a plane. You give the polygon as a list of its n vertices, in order around the polygon.
    • Example: Place a charging station inside the floor plan of a distribution center.
  • Spherical Region. A spherical region variable is a point inside an area on the surface of the Earth, such as a country or a service area. You give the region as a list of its n vertices. Each vertex is a [latitude, longitude] pair in degrees. List the vertices clockwise, as on a map with north up, so that the region is on your right as you walk from each vertex to the next. The edges of the region are great-circle arcs. A region can enclose a pole, span more than 180 degrees of longitude, or be larger than a hemisphere. The variable reports the latitude and longitude of the point.
    • Example: Locate an offshore wind farm inside a licensed marine energy zone.
  • Angle. An angle variable is an angle in degrees on an arc of the circle. An arc can cross 0 degrees, such as the arc from 320 to 45 degrees.
    • Example: Orient a radar dish that must point between 320 degrees and 45 degrees.
  • Spherical Angle. A spherical angle variable is a pointing direction, given as an elevation and an azimuth in degrees.
    • Example: Point a satellite antenna whose elevation must be from 30 to 80 degrees and whose azimuth must be from 350 to 60 degrees.

Smooth variables

Use a smooth variable when your decision is a long list or a large table of numbers, and neighboring values are expected to be close. Examples are an hourly pumping schedule, a temperature profile along a reactor and a table of set points by month and zone. For each type, you set one small number, such as a number of knots. A smaller number gives a smoother shape.

  • Spline Vector and Matrix. A spline vector is a list of values on a smooth curve through a small number of evenly spaced knots. The curve passes through each knot. A spline matrix is a table on a smooth surface through a grid of knots.
    • Example: Set a pump speed for each of 96 fifteen-minute periods, on a curve through 8 knots.
  • B-Spline Vector and Matrix. A B-spline vector is like a spline vector, but the curve does not pass through its knots. Each value is a weighted average of the nearby knot values, so the curve bends more gently.
    • Example: Smooth the production ramp-up over a month-long schedule.
  • Fourier Vector and Matrix. A Fourier vector is a list of values that is a sum of a few cosine waves across the whole list. The first term is a constant. Each next term adds one more half wave, so more terms add finer detail.
    • Example: Set a demand response target for each hour of the day that rises and falls in a few gradual waves.
  • Low-Rank Matrix. A low-rank matrix is a table whose rows follow a few common patterns. You set the rank, which is the number of patterns.
    • Example: Set a temperature set point for each of 12 months in each of 40 zones, where the zones follow a few seasonal patterns.
  • Time-Series Vector. A time-series vector is a long list of values that repeats on a cycle, such as hourly values over many days. You set three numbers:
    • The length of one cycle, such as 24 hours.
    • The number of cycles, such as 30 days.
    • The rank, which is the number of patterns in a cycle. With rank 1, every day has the same shape, and the size of that shape can change from day to day. Each extra unit of rank adds one more pattern.
    • Example: Set the hourly power use of a plant for each hour of a 30-day month.

Each smooth type also has a correction form. A correction form takes a baseline, such as a known schedule, profile or calibration. OptQuest searches for a smooth change to the baseline, and the values are the baseline plus the change. Use a correction form when you already have a good shape and want to improve it.

The Low-Rank Matrix and Time-Series Vector types also have an incremental correction form. It adds a change of rank 1 to the baseline. Use it to build a correction in steps: run an optimization, use its best value as the baseline of the next run, and repeat. So there are three time-series vector variables: Time-Series Vector, Time-Series Correction Vector and Incremental Time-Series Correction Vector.

These smooth types are decision variables. They are not models that fit or forecast data. To choose one, look at the shape that you expect your decision to have:

The shape of your decision Type
A profile that changes smoothly along its length, where a change at one point affects only the nearby values Spline Vector, or B-Spline Vector for gentler bends
A profile made of gradual waves across its whole length Fourier Vector
A long series that repeats on a cycle, such as hours in a day over many days Time-Series Vector
A table that changes smoothly in both directions Spline Matrix, B-Spline Matrix or Fourier Matrix
A table whose rows follow a few common patterns Low-Rank Matrix
A known profile or table that you want to adjust The correction form of any of the above

Container Variables

With a container variable, you declare an array of similar variables in one call. OptQuest adds one standard decision variable for each element. The search is the same as when you declare each element on its own.

The continuous containers are Vector (1 dimension), Matrix (2 dimensions) and ND (N dimensions). Integer, Discrete and Binary variables have the same three forms. The Output Vector, Output Matrix and Output ND containers declare arrays of outputs that your evaluator returns.

Random Variables

OptQuest 10.1 added percent point functions, with which a model can make a random draw from rand() inside an expression. OptQuest 10.2 adds random variables, which are random draws from standard distributions. Use them to add outside variability to the model that you optimize. For each replication, OptQuest draws a new value from the distribution.

Fourteen distributions are available: Uniform, Normal, Log-Normal, Exponential, Poisson, Gamma, Weibull, Beta, Pareto, Student’s t, Chi-Square, Cauchy, Power and Spherical Elevation.

Agentic Integration

OptQuest 10.2 adds guides and API calls for the case where an AI coding agent writes the model from a plain-language description of your problem. From function signatures alone, an agent cannot tell which variable type fits the problem or in what order the optimization loop runs. The guides contain this information.

Integration Guide for Coding Agents

The documentation set now includes AGENTS.md, a guide written for a coding agent. It covers setup for each language, the mental model, an end-to-end example, turning a problem statement into variables, choosing variable types, variable names, objectives, constraints, the expression language, the evaluator, how to pick a workflow, stochastic simulations, adaptive sampling vs. optimization, model immutability and errors, recipes, pointers into the API reference, mistakes to avoid, and a glossary. The API documentation remains the reference for the function signatures.

Instructions for Agents That Work in Python

The Python distribution includes a second guide, optquest_agent_instructions.md, for agents that work in Python. With it, an agent writes only two files: a model definition in YAML and a simulator function. The provided tools run the optimization loop. A mock engine is included, so the agent can check both files without the OptQuest library.

Algorithm Improvements

Trial Solution Pruning

During an optimization, OptQuest now screens each trial solution before it sends the trial solution for evaluation. OptQuest discards trial solutions that are unlikely to improve on the solutions that it already has. In a black-box problem, most of the time of a run is in the evaluations, so discarding poor trial solutions leaves more of the evaluation budget for better ones.

Scatter Search on Discrete Objectives

In some problems, an objective has only a few distinct values, so many solutions have the same objective value. OptQuest now detects this case and changes its search for it.

New Features

Fix and Float Groups

With AddFixGroup and AddFloatGroup, you can help OptQuest exploit structure that may exist in your problem by directing OptQuest to fix or float a group of variables during the search. Fix and float groups are not used in the initial part of the search, but later in the search some solutions that OptQuest generates will fix or float specified variables based on the current best known solution.

  • A fix group is a set of decision variables. In some generated solutions, the variables of the fix group will be assigned values based on the best solution found so far, while the other variables are given new values. Use a fix group when you want diversity in the search to focus on the other variables.
  • A float group is the inverse of a fix group. In some generated solutions, the float variables will take new values, while and the other variables will be assigned values based on the best solution found so far. Use a float group when you want diversity in the search to focus on these variables.

A fix group of a set of variables gives the same trial solutions as a float group of all the other variables, so declare the smaller set.

Metamodel Prediction in Optimizations

In OptQuest 10.1, Predict() worked only in Adaptive Sampling, where the metamodel is of the sample metrics. In OptQuest 10.2, Predict() also works in an optimization. With no sample metrics, OptQuest builds a metamodel of the objectives and predicts the value of each objective. The uncertainty of each prediction comes from the spread of the results of a solution. It is zero when the model runs without replications, and it is the standard deviation across the replications when the model has replications.

OptQuest builds the metamodel from every solution that the model has at the time of the call. It builds the metamodel again only when that set of solutions has changed, so many predictions against the same set are fast. You can also call Predict() from inside an evaluator while a run is in progress.

Name Discovery

The solution methods GetInputNames() and GetOutputNames() return the names of the variables in a model. The lists include the element names of all standard, permutation, container, and special purpose variables. An evaluator can loop over these names to read every value.

Direct Evaluation

Evaluate() computes the objectives, the constraints and the expression variables from input and output values that you supply, with no search. OptQuest does not count the solution as an evaluation, and the solution has no effect on the search. Use it to score scenarios that you write by hand, to check a model before you run an optimization, and to compare a candidate with the best solution.

REST and MCP Interface (Beta)

A JSON HTTP service for the engine is in beta, with an MCP server in the same process. A model definition is a list of statement objects rather than a command string. A validate call checks a draft model without contacting the engine or creating a model. The MCP server has nine tools for an agent loop: describe the model grammar, validate a draft, create an optimization, ask for a candidate, return a result, reject a candidate, read the best solutions, read the model status and delete a model. The service is available on request.

Changes and Deprecations

The geodist Function Now Uses Degrees and Returns Kilometers

The geodist(lat1, lon1, lat2, lon2) function in expressions now takes latitude and longitude in degrees. It returns the great-circle distance in kilometers, on a spherical Earth with a radius of 6,371 km. It is the same as 6371 * sphdist(dtor(lat1), dtor(lon1), dtor(lat2), dtor(lon2)). The sphdist function has not changed: it takes radians and returns a distance on the unit sphere, also in radians. This is a breaking change for an existing expression that calls geodist.

Case-Insensitive Names

OptQuest now matches names without regard to case, in the API and in expressions. Rate and rate are the same name. If a model uses case to tell two names apart, you must change one of the names.

Use Sequence Variables in Place of Permutation Variables

COptQuestPermutationVariable and AddPermutationVariable still work and have not changed, but they are deprecated. COptQuestSequenceVariable and AddSequenceVariable give the same values, ranks from 1 to n. A sequence variable can also rank only the top k items. Use sequence variables in new models, and use permutation variables only to maintain a model that already has them.

Use Choice Variables in Place of Design Variables

COptQuestDesignVariable and AddDesignVariable still work and have not changed, but they are deprecated. COptQuestChoiceVariable and AddChoiceVariable give the same values, option numbers from 1 to N. Use choice variables in new models, and use design variables only to maintain a model that already has them.

What can OptTek do for you?

Solving the world's most complex challenges through optimization and analytics for over 30 years.