OptTek OptQuest 10.2 Optimization API Help

OptQuest 10.2 Optimization API

The OptQuest 10 API is one declarative interface with bindings for Java, C#, C++, C and Python. The same model definition and the same calls work in all five languages. A COM interface gives Automation clients (VBA, VBScript, VB6 and Excel) the C# calls. In Java, the OptQuest 9 API is still supported, and OptTek has no plan to deprecate it. In C#, C++, C and Python, the OptQuest 10 API is the only interface to the OptQuest Engine.

Overview

What Is Optimization?

Optimization finds the values of decision variables that give the best result for an objective while they satisfy the constraints. The OptQuest® Engine, developed by OptTek Systems, Inc., answers questions such as these:

For most problems, it is not practical to evaluate every combination of values. The OptQuest Engine chooses which combinations to evaluate next based on the results of all of the previously evaluated solutions. ### OptQuest Engine

Search Algorithm and Metaheuristics

The OptQuest Engine is a black-box global optimizer. It makes no assumption about the shape of the objective or the constraints. It needs no formula that gives the outputs from the inputs, and no derivatives, only the values that your evaluation returns. The engine uses metaheuristics: it records how earlier trial solutions performed, and it combines good trial solutions to make new ones. For a simulation that gives a different result each time it runs, the engine can evaluate each trial solution several times and combine the results (see § Concepts › Stochastic Simulation Optimization).

Algorithm Composition

The engine combines several known techniques along with proprietary custom approaches for various problem types:

Concepts

This chapter introduces the parts of an OptQuest model and the loop the engine uses to evaluate solutions. Read it for orientation. The signature of every function mentioned here is in § API Documentation.

Model Components

In the OptQuest Engine, a model is a structured description of an optimization problem. It has one or more decision variables, one or more objectives and, optionally, one or more constraints. With a single objective, OptQuest refines a single best solution that maximizes or minimizes it. With several objectives, OptQuest builds a Pareto frontier: the set of solutions that represent the best trade-offs among the objectives. See § Overview › OptQuest Engine for a summary of the search algorithms.

Names

Every model component (variable, output, expression, objective, constraint, group and sample metric) has a name. These rules apply:

The element names that the engine generates itself can contain commas (m@1,2). You read those back from the name lists. The members of a selection variable, an exchangeable group, a fix group and a float group are names of variables that are already in the model, so a member can be a generated element name with commas, such as m@1,2 or n@1,2,3.

Names in expressions. An expression in an expression variable, an objective, a constraint or a sample metric refers to a variable by a name that GetInputNames or GetOutputNames returns. For a container or special purpose variable, that is an element name, such as v@2, dir@theta or pol@i1, and never the base name (v, dir, pol). The base name has no value of its own. A model with an expression that names a base name, such as pol <= 7, fails when it initializes, and the error gives the reason “The name is the base name of a container or manifold variable. Use its element names, such as name@1.” and the base name. The engine messages call a special purpose variable a manifold variable. The Notes of each type list its element names. Write an element name that contains a comma in brackets, for example [m@1,2].

Decision Variables

Decision variables are the parameters the optimizer is allowed to vary. The API groups them in these families. Each family is documented in § API Documentation › Decision Variables:

Restrictions and groupings that apply to variables after they exist (exclusive ranges, selection gates, exchangeable groups and fix/float groups) are documented in § API Documentation › Variable Modifiers.

Output Variables

Output variables hold results that the simulation (or an external computation) must supply for each trial solution. OptQuest does not assign values to them. Use an output variable whenever an objective or constraint depends on a quantity that cannot be written as a closed-form expression of the input variables. If the evaluator does not call SetValue for an output before it submits the solution, the output stays NaN. For the effect on the objectives and constraints, see § API Documentation › Output Variables. The API supports scalar outputs, output vectors, output matrices and arbitrary-dimensional output ND variables.

Expression Variables

Expression variables are derived values. The optimizer does not choose them and the simulation does not set them. Each expression variable has a string expression, in the same language as objectives and constraints, that the engine recomputes after every solution evaluation. An expression variable can reference input, output and other expression variables. Objectives, constraints, sample metrics and further expression variables can reference it in turn.

Objectives

An objective is an expression over decision variables and output variables that measures a goal. Each objective has a direction:

For example, an objective can be maximize 2*VariableA + 3*VariableB, where VariableA and VariableB are input or output variables. With several objectives, OptQuest finds the set of non-dominated solutions: the frontier of the trade-offs among the objectives.

For stochastic models (with replications), SetObjectiveStatistic selects which statistic of the per-replication objective values (mean, median, percentile, standard deviation, variance, coefficient of variation, min, max or sum) is the value that the optimizer compares, and SetObjectiveConfidence lets the engine stop replicating early once a configured confidence interval is reached. See § API Documentation › Objectives.

Constraints

A constraint is an expression that limits the feasible region. It can reference variables, objectives or both. OptQuest supports:

The engine enforces a constraint at one of two times, depending on what the constraint references:

A constraint over the variable names of a special purpose variable, or over a random variable, is also checked after evaluation. The element names of a container variable, and the names of an item selection or a budgeted selection variable, are ordinary inputs, so a constraint over them is enforced before evaluation. See § API Documentation › Decision Variables › Special Purpose Variables: Common Behavior.

The engine has no strict inequality: it reads < as <= and > as >=. It also accepts a violation of a constant bound up to a small tolerance, 1e-5 for each variable in a linear constraint over inputs. See § API Documentation › Constraints › Add Constraint.

The Optimization Loop

OptQuest is built for black-box simulation optimization, where the objective depends on the outputs of a simulation. The objective can be non-convex, discontinuous or non-differentiable. The engine runs this loop:

  1. Generate: build a trial solution by assigning a value to every input variable within its domain, subject to the constraints.
  2. Evaluate: compute the output values from the trial solution’s inputs, with a simulation, a complex function or an analytical expression.
  3. Learn: assess the evaluated solution to learn about the objective and the solution space.
  4. Refine: use what has been learned to generate the next trial solution.

The four workflows that run this loop (managed, concurrent, asynchronous managed and manual) are documented in § Optimization Workflows.

Model Immutability

An OptQuestModel has two stages: definition and execution. During definition, the client adds decision variables, output variables, expression variables, objectives, constraints and sample metrics, and configures their statistic and confidence parameters. Execution begins the first time the engine builds its internal representation of the model, which is the first call to any of these methods:

You can also start execution explicitly with Initialize(). This is useful to find out whether the model is well formed before any solution is generated.

The first of these calls builds the engine’s internal data structures from the declared components and makes the model immutable. From then on, every configuration method is rejected, including the ones that do not add components. That includes adding decision, output and expression variables, objectives, constraints and sample metrics; the statistic settings (SetObjectiveStatistic, SetOutputStatistic); and the run-control settings SetReplications, SetSerialReplications, SetStopCycles, SetStopImprovement, SetStopTime, StopOnSuccessfulMILP, SuggestedSolutionsOnly, SetParallelHint, SetRandomSeed, SetSampleMethod, SetSampleVariogram and the SetSampleRDS* family. Such a call fails in the language’s standard way (see § Concepts › Error Handling).

These operations stay valid after initialization:

Immutability is a one-way transition. No call returns an initialized model to the definition stage. To change the structure of a model after a run, create a new OptQuestModel, define it again, and use AddAllSolutions to import the old solutions into it if you want them.

Stochastic Simulation Optimization

OptQuest supports stochastic simulations, where identical inputs can produce different outputs. Each trial solution (one combination of decision-variable values) is evaluated N independent times, called N replications, and the engine aggregates the per-replication results into one score that it uses to guide the search. The evaluator and the monitor are both called once per replication. For a trial with twenty replications, both callbacks run twenty times before the engine moves to the next trial. Across those twenty calls the decision-variable values are identical. Only random variables (declared with Add*RandomVariable) and any randomness inside the simulator itself change between replications.

There are two ways to configure the number of replications:

min must be at least 1 and max at least min. A max of 1 runs without replications. A confidence interval needs two observations, so a min of 1 with a larger max runs at least two replications per trial.

See § API Documentation › Optimization Configuration and § API Documentation › Objectives for the signatures.

Error Handling

Each language reports errors in its own way:

For the solution-level operations (Submit, Reject, Predict, Evaluate, Update, AddSuggested, AddEvaluated, AddRequired), read the error from the solution rather than the model: Java throws the same exception type; C#, C++ and Python call GetLastError() / get_last_error() on the OptQuestSolution; C calls OQGetLastSolutionError(sol). See § API Documentation › Utility Functions for the signatures.

GetLastError() / OQGetLastError() is sticky: a successful call does not clear it, so the text can be left over from an earlier, unrelated failure. Use the return code to decide whether a call failed, and read the error text only after a return code that is a failure value.

The description that GetLastError() / OQGetLastError() returns is a pointer into a per-thread buffer. It stays valid until the next GetLastError() call on the same thread. Another thread that records an error (a worker under a parallel Optimize, for instance) cannot invalidate a pointer this thread holds. Copy the string if it must outlive the next call.

No exception and no fault crosses the C boundary. When an OQ* function gets a NULL handle or a NULL array or string argument, or when an exception is raised inside the library, the function returns the call’s own failure value: 0 for the bool-valued calls, -1 for the int-valued counts and reasons, NaN for a value, "" for a borrowed string, and NULL for a handle or an allocated reply. Where a handle is available, the reason is recorded against it. A model is still usable after a call is refused this way. Array arguments must not be NULL unless their count is zero.

Submit and Reject do not follow the return convention above. In Java, C#, C++ and C they return the engine’s running count of completed iterations on success and exactly -1 on failure. The count is 0 for a successful call while no iteration has completed yet (the first replication of a trial under replications, for example), so 0 is a success. Test these two functions with >= 0 (or != -1), never with != 0 or > 0. Predict, Evaluate, Update, AddSuggested, AddEvaluated and AddRequired follow the ordinary convention. Python’s submit() and reject() apply the >= 0 test internally and return False only on failure.

Common Errors

These are the errors and the silent results that new users see most often. The quoted text is what GetLastError() returns in C#, C++, C and Python. In Java, an engine error throws COptQuestException with the same description, and a call that the client refuses returns false with no message. A message from the engine contains the description shown, followed by a call stack.

Message or symptom Cause What to do
ERROR the model has no objective The model has no objective. In Java, Initialize and Optimize return false. Add an objective. The model stays in the definition stage, so you can add the objective and run again.
ERROR duplicate name An Add call used a name that the model already has. Names are compared without regard to case. In Java, the call returns false. Use a different name.
The variable name is a reserved function name. A variable has the name of a function or a constant of the expression language, such as rate or pi. Rename the variable. In C#, C++, C and Python, the engine reports the message when the model initializes, and the model cannot be changed after that. Build a new model.
ERROR already initialized An Add or Set call came after the model was initialized. In Java, the call returns false. Make every Add and Set call before the first run. To change a model after a run, build a new model (see § Model Immutability).
The variable was not found. Error Token = <name> An objective, a constraint or an expression variable uses a name that the model does not declare. The engine reports the message when the model initializes. Check the spelling. A container or special purpose variable has generated names, such as v@1; see § Get Variable Names. Build a new model to correct the error.
ERROR BAD VALUE NAME: <name> SetValue used a name that the model does not declare. The engine reports the message when the solution is sent, for example by Submit. In Java, SetValue returns false. Check the spelling of the output name.
ERROR BAD SOLUTION ID Submit or Reject was called on a solution that the engine did not issue, such as a solution from GetEmptySolution or CopySolution. Java does not refuse this call. Give such a solution to the engine with AddSuggested, AddEvaluated or AddRequired.
ERROR invalid solution A call was made on a solution whose IsValid() is false. In Java, SetValue returns false and Submit returns -1. Test IsValid() after each CreateSolution(). When it is false, read GetTerminationReason().
Constraints are infeasible. No input values satisfy the constraints that use only input variables. The termination reason is Infeasible (12), and CreateSolution returns an invalid solution. Check the constraints and the bounds of the variables that they use.
Bad value for the replication confidence error percent. The epct argument of SetObjectiveConfidence is not greater than 0 and less than 1. The engine reports the message when the model initializes. Pass a fraction: 0.05 for 5 percent.
The run stops after 50 iterations, and the termination reason is 14. There is no message. No license is set. Call SetLicense with your license key.
Optimize returns false, and GetLastError() is empty. The run ended early without an error, for example because the monitor returned false. Read GetTerminationReason() (§ Get Termination Reason).
The best solution is infeasible, and its objective is NaN. There is no message. The evaluator rejected every trial solution. In Python, an evaluator without a return statement returns None, and the engine rejects the trial solution. End a Python evaluator with return True.
An output reads NaN, and an objective or a constraint that uses it is NaN. The evaluator did not call SetValue for that output. Set every output before you submit the solution, or reject the solution.

Your First Optimization

This section gives a complete program and its output. The program finds the values of x and y that give the smallest cost. The engine asks for one set of values of x and y at a time. That set of values is a trial solution. For each trial solution, the engine calls the evaluator, which stands in for your simulation. The evaluator reads the inputs, computes the output and writes the output back. One iteration is one trial solution with all its replications (see § Stochastic Simulation Optimization). This model has no replications, so each iteration is one call of the evaluator.

In Java, GetValue and SetValue declare throws COptQuestException, so the evaluator catches that exception.

import com.opttek.optquest.COptQuestException;
import com.opttek.optquest.IOptQuestEvaluator;
import com.opttek.optquest.OptQuestModel;
import com.opttek.optquest.OptQuestSolution;
import java.util.List;

public class FirstOptimization {
    public static void main(String[] args) throws COptQuestException {
        OptQuestModel model = new OptQuestModel();
        // model.SetLicense("your-license-key");   // without a license, a run stops after 50 iterations
        model.AddContinuousVariable("x", -10, 10);    // decision variables and their bounds
        model.AddContinuousVariable("y", -10, 10);
        model.AddOutputVariable("cost");              // a result that the evaluator writes
        model.AddMinimizeObjective("obj", "cost");    // what "best" means

        IOptQuestEvaluator evaluator = sol -> {
            try {
                double x = sol.GetValue("x");
                double y = sol.GetValue("y");
                double cost = (x - 3.0) * (x - 3.0) + (y + 1.0) * (y + 1.0);   // replace with your simulation
                sol.SetValue("cost", cost);
                return true;                          // true: use this result
            } catch (COptQuestException e) {
                return false;                         // false: reject this trial solution
            }
        };

        model.Optimize(40, evaluator);                // run 40 iterations

        List<OptQuestSolution> best = model.GetBestSolutions();
        if (!best.isEmpty()) {
            OptQuestSolution b = best.get(0);
            System.out.println("x = " + b.GetValue("x") + ", y = " + b.GetValue("y")
                    + ", cost = " + b.GetValue("obj") + ", feasible = " + b.IsFeasible());
        }
        System.out.println("iterations = " + model.GetNumberOfCompletedIterations()
                + ", termination reason = " + model.GetTerminationReason());
    }
}

The same program in Python:

import optquest

def evaluate(sol):
    x = sol.get_value("x")
    y = sol.get_value("y")
    cost = (x - 3.0) ** 2 + (y + 1.0) ** 2      # replace with your simulation
    sol.set_value("cost", cost)
    return True                                 # True: use this result

model = optquest.OptQuestModel()
# model.set_license("your-license-key")         # without a license, a run stops after 50 iterations
model.add_continuous_variable("x", -10, 10)     # decision variables and their bounds
model.add_continuous_variable("y", -10, 10)
model.add_output_variable("cost")               # a result that evaluate() writes
model.add_minimize_objective("obj", "cost")     # what "best" means

model.optimize(40, evaluate)                    # run 40 iterations

best = model.get_best_solutions()
if best:
    b = best[0]
    print(f"x = {b.get_value('x')}, y = {b.get_value('y')}, "
          f"cost = {b.get_value('obj')}, feasible = {b.is_feasible()}")
print(f"iterations = {model.get_number_of_completed_iterations()}, "
      f"termination reason = {model.get_termination_reason()}")

The Java program prints:

x = 2.9083081205692034, y = -0.7155144834659386, cost = 0.08933940987120347, feasible = true
iterations = 40, termination reason = 6

The Python program prints the same values, with True in place of true. The engine uses the same random seed each time, so each run of the program gives the same result (see § Set Random Seed).

The minimum is at x = 3 and y = -1, where the cost is 0. Termination reason 6 is Max Iterations: the run completed the 40 iterations that the program asked for. More iterations give a result closer to the minimum. With a license set, the same program gave these best costs:

Iterations Best cost
20 4.34
40 0.0893
100 4.7e-6
200 4.7e-7
500 1.5e-8

Without a license, the model runs in demo mode, and a run stops after 50 iterations (see § Set License).

To adapt the program to your problem:

  1. Add one decision variable for each quantity that you control. For a comparison of the variable types, see § Choosing a Variable Type.
  2. Add one output variable for each result of your simulation that an objective or a constraint uses.
  3. Add the objective, and add the constraints if you have them.
  4. In the evaluator, call your simulation and write every output variable with SetValue. If the simulation fails, return false to reject the trial solution.
  5. Set the number of iterations, run the optimization, and read the best solution.

The full order of the calls is at the start of § API Documentation. The other ways to run the loop are in § Optimization Workflows.

Optimization Workflows

OptQuest offers four workflows for driving the optimization loop: a managed workflow, in which the engine owns the loop; a concurrent variant, in which the engine spreads evaluation across threads; an asynchronous variant, in which the host application stays responsive during a long run; and a manual workflow, in which the client performs every step itself.

The code examples below are in Java. The OptQuest 10 API is the same in all five languages: C#, C++, C and Python use their own syntax with otherwise identical signatures. The COM interface has the C# calls, with the differences listed in § Reference › Linking OptQuest To Your Project › COM. The signature of every workflow is in § API Documentation › Running Managed Optimization and Sampling and § API Documentation › Manual Optimization.

Managed Optimization

In managed optimization the engine runs the optimization loop.

Simple Optimization

When the objectives and constraints are direct functions of the input variables (no external simulation), OptQuest runs the loop with no evaluation callback. The client specifies only the number of iterations.

OptQuestModel model = new OptQuestModel();

// Define input variables, objectives, and constraints
// ...

// Perform 100 iterations of the optimization loop
model.Optimize(100);

Simulation-Based Optimization

When the outputs come from a simulation, the client supplies a callback that evaluates each solution. OptQuest calls it once for each replication of each trial solution.

OptQuestModel model = new OptQuestModel();

// Define input variables, objectives, and constraints
// ...

// Perform 100 iterations, invoking customEvaluation for each solution
model.Optimize(100, customEvaluation);

Concurrent Optimization

For expensive evaluations, OptQuest evaluates several solutions in parallel. The client specifies the number of threads. OptQuest creates the solutions, dispatches them across the threads and synchronizes the generate and learn steps.

OptQuestModel model = new OptQuestModel();

// Define input variables, objectives, and constraints
// ...

// Perform 100 iterations with 5 concurrent threads, invoking customEvaluation
model.Optimize(5, 100, customEvaluation);

Asynchronous Managed Optimization

For a long run, the client starts the optimization on a background thread and keeps the main thread responsive. The main thread can interrupt the run through a channel.

OptQuestModel model = new OptQuestModel();

// Define input variables, objectives, and constraints
// ...

// Create a channel for 5 concurrent optimizations
OptQuestModelChannel channel = model.CreateAsyncChannel(5);

// Start asynchronous optimization in a background thread
Thread background = new Thread(() -> {
    try {
        // Blocks until 100 solutions are evaluated or interrupted
        model.Optimize(channel, 100, customEvaluation);
    } catch (COptQuestException e) {
        e.printStackTrace();
    }
});
background.start();

// Interrupt optimization in response to a user event
channel.Interrupt();

// Wait for the optimization to terminate gracefully
background.join();

Python has no channel object. Start model.optimize(...) on a background thread, pass npar to it directly, and call model.interrupt() on the model from the main thread. model.continue_opt() clears the interrupt so that a later optimize() can run.

Manual Optimization

For fine-grained control, the client performs each step of the loop itself. Use it for HPC, distributed and other custom concurrent setups, in which the client requests each next solution, then manages evaluation and submission.

OptQuestModel model = new OptQuestModel();
model.AddContinuousVariable("x", 0, 10);
model.AddOutputVariable("y");
model.AddMinimizeObjective("obj", "y");

for (int i = 0; i < 100; i++) {
    // Ask the engine for the next trial solution
    OptQuestSolution solution = model.CreateSolution();
    if (!solution.IsValid()) {
        break;   // the run has ended; read GetTerminationReason() for the reason
    }

    // Read the inputs, compute the outputs and write them back by name
    double x = solution.GetValue("x");
    double y = runSimulation(x);   // your code
    solution.SetValue("y", y);

    // Give the result to the engine: -1 is a failure, 0 or more is a success
    if (solution.Submit() < 0) {
        break;
    }
}

List<OptQuestSolution> best = model.GetBestSolutions();
if (!best.isEmpty()) {
    System.out.println("x = " + best.get(0).GetValue("x") + ", y = " + best.get(0).GetValue("y"));
}

With runSimulation(x) equal to (x - 2) * (x - 2) and no license, the program prints x = 2.000606391779585, y = 3.6771099034838766E-7. In demo mode, the 51st CreateSolution returns an invalid solution with the termination reason Max Demo Iterations (14), so the loop ends after 50 passes.

Without replications, each pass of the loop evaluates one trial solution. With replications, each pass evaluates one replication. In Java, CreateSolution and Submit throw COptQuestException when the engine reports an error. In C#, C++ and Python, call GetLastError() on the solution after Submit reports a failure.

Adaptive Sampling

Adaptive Sampling, introduced in OptQuest 10, is an alternative to optimization for exploring a design space. Optimization seeks one best point, a minimum or a maximum. Adaptive Sampling builds an accurate picture of the response surface across the whole domain with as few evaluations as possible. Use it when the goal is to understand the behavior of the domain: trends, boundaries and regions of interest, rather than a single optimum.

The sampling engine works like the optimization engine. It generates trial solutions, evaluates them and uses the results to guide the next choice. The difference is the goal. Adaptive Sampling monitors a user-defined metric, which has a value and an uncertainty (error). The engine builds an internal model of the metric across the domain, predicts the response in unexplored areas and selects the next solution where it expects to learn the most. The engine refines the model with each evaluated solution.

Sampling Loop

The Adaptive Sampling loop has five steps:

  1. Generate: build a trial solution by assigning a value to every input variable within its domain.
  2. Evaluate: compute the output values from the trial solution’s inputs, with a simulation, a complex function or an analytical expression.
  3. Model: update the internal model of the response surface from all evaluated solutions.
  4. Select: find the most informative region of the domain under the current model.
  5. Refine: generate the next trial solution in that region.

Sampling Strategies

Each strategy defines what “informative” means. Select one by passing its flag to SetSampleMethod (see § API Documentation › Adaptive Sampling Configuration). The constants below are the C names. The constants for the other languages are listed with SetSampleMethod.

The flags above can be combined with the OQSampleMethodStochastic, OQSampleMethodDynamic and OQSampleMethodAsync modifiers. See § Set Sampling Method for the full combination table.

Applications

Adaptive Sampling suits applications that need a picture of the whole domain, such as:

API Documentation

This chapter documents every function of the OptQuest 10 API, with its signature in Java, C#, C++, C and Python. A COM interface for Automation clients (VBA, VBScript, VB6, Excel) is the COM form of the C# interface; see § Reference › Linking OptQuest To Your Project › COM for its naming and marshalling differences. Unless an entry says otherwise, the Java, C# and C++ implementations behave identically. In C the caller frees some resources by hand, and each entry that needs it says so. Any language that can call C functions can use the C interface.

To define a model, call the functions in this order:

  1. Create the model: create an OptQuestModel. It holds every model component.
  2. Add input variables: add one or more decision variables. They define the search space.
  3. Add output variables (optional): add an output variable for each result of the simulation that an objective or constraint needs and that cannot be written as an expression of the inputs.
  4. Define objectives: add one or more objectives, each an expression over input and output variables with a maximize or minimize direction.
  5. Define constraints (optional): add constraints as expressions over the variables to limit the feasible region.
  6. Configure the run: set replications, stopping criteria, the sampling method and the other run settings as needed.
  7. Run: call one of the managed Optimize or Sample methods, or drive the loop by hand, then read the solutions back.

Conventions

The rules below apply to every entry in this chapter. The entries do not repeat them.

Return Values and Errors

A function that has no other result reports success or failure this way:

Submit and Reject return an iteration count instead of a flag; see their entries. The sticky error text, the per-thread error buffer and the rule that no exception crosses the C boundary are described in § Concepts › Error Handling. An entry has its own Returns section only when its function does not follow this rule.

Names

Every name argument follows the rules in § Concepts › Names: unique across the model, not empty, no whitespace, no semicolons, ASCII only, and not starting with a digit for a variable. The element names supplied to a composite variable must not contain commas either. The members of a selection variable and of a group can be generated element names with commas, such as m@1,2. A function that receives a name that breaks these rules fails.

A variable name must also not be the name of a function or a constant of the expression language. In Java, the Add call fails. In the other languages, the Add call succeeds, and the model fails when it initializes.

Numbering

The index and position numbers that OptQuest reports start at 1. These are:

Java, C#, C, C++ and Python number their arrays from 0. To use a reported value k as an index into your own array, read element k - 1. A value of 0 has its own meaning: an Assignment bin of 0 means that the item is in no bin, and a Path position of 0 means that the node is not on the path.

These numbers start at 0: the index i of GetBestSolutionsAt(i), GetAllSolutionsAt(i), GetInputNameAt(i) and GetOutputNameAt(i) in C and C++, and the counter on the --- line of a GETBESTSOLUTIONS or GETALLSOLUTIONS reply in the Standard I/O Interface.

Strings and Arrays in C and C++

Every string argument is a null-terminated const char*. An array of strings is a const char** with its element count passed alongside. The entries state only the layout of arrays that is not obvious from the signature.

Model Lifecycle

Create Model

Language Function Signature
Java new OptQuestModel()
C# new OptQuestModel()
C++ OptQuestModel()
C HOptQuestModel OQCreateModel()
Python OptQuestModel()
Description

Creates a new OptQuestModel. The model holds every component you add to it. Create the model before you add variables, objectives or constraints.

Notes

Delete Model

Language Function Signature
Java Garbage Collected
C# Garbage Collected
C++ Destructed
C void OQDeleteModel(HOptQuestModel model)
Python Garbage Collected
Description

Releases the resources of an OptQuestModel. Java, C# and Python reclaim the object through garbage collection. In C++ the destructor runs when the object goes out of scope. In C, call OQDeleteModel on the handle.

Notes

Set License

Language Function Signature
Java boolean OptQuestModel.SetLicense(String license)
C# bool OptQuestModel.SetLicense(string licenseid)
C++ bool OptQuestModel::SetLicense(const char* licenseid)
C int OQSetLicense(HOptQuestModel model, const char* licenseid)
Python bool OptQuestModel.set_license(str license_id)
Description

Sets the license key that an OptTek representative supplied. If SetLicense is never called, or is called with an empty string, the model runs in demo mode: every optimization stops after 50 iterations regardless of the requested iteration count. CreateSolution then returns an invalid solution, and GetTerminationReason reports Max Demo Iterations (14). A managed Optimize returns false with no error text.

Log Setup

Language Function Signature
Java boolean OptQuestModel.LogSetup(String filespec)
C# bool OptQuestModel.LogSetup(string filespec)
C++ bool OptQuestModel::LogSetup(const char* filespec)
C int OQLogSetup(HOptQuestModel model, const char* filespec)
Python bool OptQuestModel.log_setup(str file_spec)
Description

Writes an XML description of the model’s configuration to the file at filespec. Use it for debugging, or to share a model with OptTek support.

Notes

Log Solutions

Language Function Signature
Java boolean OptQuestModel.LogSolutions(String filespec)
C# bool OptQuestModel.LogSolutions(string filespec)
C++ bool OptQuestModel::LogSolutions(const char* filespec)
C int OQLogSolutions(HOptQuestModel model, const char* filespec)
Python bool OptQuestModel.log_solutions(str file_spec)
Description

Writes every solution evaluated during optimization or sampling to the file at filespec. Use it to share solution data with OptTek support for troubleshooting or analysis.

Notes

Initialize Model

Language Function Signature
Java boolean OptQuestModel.Initialize() throws COptQuestException
C# bool OptQuestModel.Initialize()
C++ bool OptQuestModel::Initialize()
C int OQInitialize(HOptQuestModel model)
Python bool OptQuestModel.initialize()
Description

Builds the engine’s internal representation of the model and moves the model from the definition stage to the execution stage. After this call the model is immutable (see § Concepts › Model Immutability).

The call is optional: every method that needs an initialized model calls it first. Call it explicitly to find out whether the model is well formed before any solution is generated. Without the explicit call, you see the error later as a generic failure of the first CreateSolution() or Optimize(). With it, you can inspect the error at a known point.

Notes

Describe Model

Language Function Signature
Java String OptQuestModel.Describe()
C# string OptQuestModel.Describe()
C++ const char* OptQuestModel::Describe()
C const char* OQDescribe(HOptQuestModel model)
Python str OptQuestModel.describe()
Description

Returns the model as the block of definition commands that the binding sends to the engine. This is the text documented in § Reference › Standard I/O Interface › Model Definition Commands. Use it as a debugging aid: the text is what the binding built from your API calls, including the numeric formatting used on the wire, and you can capture it and replay it through the STDIO interface.

Returns
Notes

Decision Variables

A decision variable is a value the optimizer chooses. Every function in this group adds one variable, or one family of generated variables under a base name, to the model. The families are:

Read the names of the variables in a model, including the generated element names, with GetInputNames (§ Working With Solutions › Get Variable Names).

Choosing a Variable Type

Find your decision in the first column. The full rules of each type are in its entry below.

Your decision Type Example
A number in a range Continuous a flow rate from 0 to 50 L/s
A whole number in a range Integer the number of pumps, from 1 to 4
A number in fixed steps Discrete a pipe size in steps of 0.5 inch
Yes or no Binary whether to add a storage tank
One number from a list of numbers Enumeration a standard resistor value
One option from a list of options that have no order Choice a supplier or a machine type
One row of a table of numbers, where rows with close values give similar results Tuple a catalog pump, given by its flow and its head
One site from a list of map points Geolocation one of 12 candidate depots
Many similar numbers that share their bounds Vector, Matrix or ND container a weight for each of 20 sensors
Proportions that add up to a total Mixture the fractions of a fuel blend
An order of items Sequence the order of jobs on one machine
An order of items in each of several groups Multi-Stage Sequence the order of jobs on each of three machines
An order that must obey rules of the form “A before B” Topological Sequence the steps of a construction project
An order set by attributes of the items, when the weights of the attributes are a useful result Policy Sequence a dispatch priority from urgency and due date
A route through some of a set of places Path a patrol route
Some items from a list, when a count range is the only rule Multi-Choice which 3 to 5 sensors to turn on
Some items from a list, with rules between the items Item Selection which sites to open, when two neighboring sites cannot both open
Items from a pool whose total cost stays within a budget Budgeted Selection which projects to fund
One bin for each item Assignment nurses to wards
Items into a set number of groups that have no labels Partition customers into 4 delivery zones
A set of one-way links with no loop, optionally from a start node to an end node DAG dependencies between tasks
A hierarchy that connects every node, optionally under a fixed root Tree a reporting structure under the head office
A direction in a plane Angle the yaw of a turbine
A direction in three dimensions Spherical Angle the pointing direction of an antenna
A point inside an area on a plane or on the Earth Region or Spherical Region a well site inside a lease boundary
A long list or a large table of numbers in which neighboring values are close a smooth type (see § Special Purpose: Smooth below) an hourly pumping schedule
A random input that the optimizer does not choose a random variable type (see § Random below) the daily demand

These types are close to each other:

Standard

Each function adds one decision variable named name.

Add Continuous Variable
Language Function Signature
Java boolean OptQuestModel.AddContinuousVariable(String name, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddContinuousVariable(string name, double min, double max)
C++ bool OptQuestModel::AddContinuousVariable(const char* name, double min, double max)
C int OQAddContinuousVariable(HOptQuestModel model, const char* name, double min, double max)
Python bool OptQuestModel.add_continuous_variable(str name, float min_val, float max_val)
Description

Adds a continuous variable with the inclusive bounds min and max.

Add Integer Variable
Language Function Signature
Java boolean OptQuestModel.AddIntegerVariable(String name, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddIntegerVariable(string name, double min, double max)
C++ bool OptQuestModel::AddIntegerVariable(const char* name, double min, double max)
C int OQAddIntegerVariable(HOptQuestModel model, const char* name, double min, double max)
Python bool OptQuestModel.add_integer_variable(str name, float min_val, float max_val)
Description

Adds an integer variable whose values are the integers from min to max inclusive.

Add Discrete Variable
Language Function Signature
Java boolean OptQuestModel.AddDiscreteVariable(String name, double min, double max, double step) throws COptQuestException
C# bool OptQuestModel.AddDiscreteVariable(string name, double min, double max, double step)
C++ bool OptQuestModel::AddDiscreteVariable(const char* name, double min, double max, double step)
C int OQAddDiscreteVariable(HOptQuestModel model, const char* name, double min, double max, double step)
Python bool OptQuestModel.add_discrete_variable(str name, float min_val, float max_val, float step)
Description

Adds a discrete variable whose values run from min to max inclusive in steps of step. The range must hold a whole number of steps.

Add Binary Variable
Language Function Signature
Java boolean OptQuestModel.AddBinaryVariable(String name) throws COptQuestException
C# bool OptQuestModel.AddBinaryVariable(string name)
C++ bool OptQuestModel::AddBinaryVariable(const char* name)
C int OQAddBinaryVariable(HOptQuestModel model, const char* name)
Python bool OptQuestModel.add_binary_variable(str name)
Description

Adds a binary variable whose value is 0 or 1.

Add Design Variable

Deprecated. Use the Choice Variable (§ Add Choice Variable) instead. It gives the number of the selected option, from 1 to the number of options.

Language Function Signature
Java boolean OptQuestModel.AddDesignVariable(String name, int num) throws COptQuestException
C# bool OptQuestModel.AddDesignVariable(string name, int num)
C++ bool OptQuestModel::AddDesignVariable(const char* name, int num)
C int OQAddDesignVariable(HOptQuestModel model, const char* name, int num)
Python bool OptQuestModel.add_design_variable(str name, int num)
Description

Adds a design variable with num distinct choices. Its value is an index from 1 to num; for example, the indices 1, 2 and 3 can stand for the options red, blue and green.

Add Enumeration Variable
Language Function Signature
Java boolean OptQuestModel.AddEnumerationVariable(String name, double[] items) throws COptQuestException
C# bool OptQuestModel.AddEnumerationVariable(string name, double[] items)
C++ bool OptQuestModel::AddEnumerationVariable(const char* name, const double* items, int n)
C int OQAddEnumerationVariable(HOptQuestModel model, const char* name, const double* items, int n)
Python bool OptQuestModel.add_enumeration_variable(str name, list[float] values)
Description

Adds an enumeration variable whose value is one of the numbers in items.

Notes
Add Tuple Variable
Language Function Signature
Java boolean OptQuestModel.AddTupleVariable(String name, double[][] tuples) throws COptQuestException
C# bool OptQuestModel.AddTupleVariable(string name, double[][] tuples)
C++ bool OptQuestModel::AddTupleVariable(const char* name, const double** tuples, int nt, int nv)
C int OQAddTupleVariable(HOptQuestModel model, const char* name, const double** tuples, int nt, int nv)
Python bool OptQuestModel.add_tuple_variable(str name, list[list[float]] tuples)
Description

Adds a tuple variable that selects one of the tuples in tuples. The value the solution reports is the 1-based index of the selected tuple. Each tuple is a point in n-dimensional space, and the optimizer uses the Euclidean distance between tuples to judge which choices are close to each other.

Notes
Add Geolocation Variable
Language Function Signature
Java boolean OptQuestModel.AddGeolocationVariable(String name, double[][] locations) throws COptQuestException
C# bool OptQuestModel.AddGeolocationVariable(string name, double[][] locations)
C++ bool OptQuestModel::AddGeolocationVariable(const char* name, const double** locations, int nl)
C int OQAddGeolocationVariable(HOptQuestModel model, const char* name, const double** locations, int nl)
Python bool OptQuestModel.add_geolocation_variable(str name, list[list[float]] locations)
Description

Adds a geolocation variable that selects one of the (latitude, longitude) pairs in locations. The value the solution reports is the 1-based index of the selected pair. The optimizer uses the angular distance between locations on a sphere to judge which choices are close to each other.

Notes

Container

A container function creates one independent standard variable per element and registers each one with the engine as an ordinary input variable. The elements share the bounds (and, for the discrete forms, the step) that you pass. They behave the same as variables added one at a time, and there is no performance cost compared with adding them one at a time. Use a container when many similar variables belong together (weights, coefficients, coordinates, grid parameters) and you want less code and uniform names.

Element names are 1-based and, for two or more dimensions, row-major:

Shape Element names
Vector of n <name>@1 … <name>@n
Matrix m×n <name>@<row>,<col>, from <name>@1,1 to <name>@m,n
ND with dims <name>@i1,i2,…,ir; element [2,1,3] of a [3,4,2] array is <name>@2,1,3

Every dimension must be at least 1, and dims must not be empty. Use the ND form when the decision has more than two dimensions, or when you want the same indexing style for every rank. In an expression, write a name that contains a comma in square brackets, [<name>@1,2], so that the comma is not read as an argument separator. In C and C++, dims is a pointer to an array of ndims ints.

Add Vector Variable
Language Function Signature
Java boolean OptQuestModel.AddVectorVariable(String name, int n, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddVectorVariable(string name, int n, double min, double max)
C++ bool OptQuestModel::AddVectorVariable(const char* name, int n, double min, double max)
C int OQAddVectorVariable(HOptQuestModel model, const char* name, int n, double min, double max)
Python bool OptQuestModel.add_vector_variable(str name, int n, float min_val, float max_val)
Description

Adds a vector variable: n continuous variables. The elements are ordinary input variables.

Each element holds a continuous value from min to max.

Notes
Add Matrix Variable
Language Function Signature
Java boolean OptQuestModel.AddMatrixVariable(String name, int m, int n, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddMatrixVariable(string name, int m, int n, double min, double max)
C++ bool OptQuestModel::AddMatrixVariable(const char* name, int m, int n, double min, double max)
C int OQAddMatrixVariable(HOptQuestModel model, const char* name, int m, int n, double min, double max)
Python bool OptQuestModel.add_matrix_variable(str name, int m, int n, float min_val, float max_val)
Description

Adds a matrix variable: an m by n matrix of continuous variables. The elements are ordinary input variables.

Each element holds a continuous value from min to max.

Notes
Add ND Variable
Language Function Signature
Java boolean OptQuestModel.AddNDVariable(String name, int[] dims, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddNDVariable(string name, int[] dims, double min, double max)
C++ bool OptQuestModel::AddNDVariable(const char* name, const int* dims, int ndims, double min, double max)
C int OQAddNDVariable(HOptQuestModel model, const char* name, const int* dims, int ndims, double min, double max)
Python bool OptQuestModel.add_nd_variable(str name, list[int] dims, float min_val, float max_val)
Description

Adds an N-dimensional variable: an array of continuous variables with the shape dims. The elements are ordinary input variables.

Each element holds a continuous value from min to max.

Notes
Add Integer Vector Variable
Language Function Signature
Java boolean OptQuestModel.AddIntegerVectorVariable(String name, int n, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddIntegerVectorVariable(string name, int n, double min, double max)
C++ bool OptQuestModel::AddIntegerVectorVariable(const char* name, int n, double min, double max)
C int OQAddIntegerVectorVariable(HOptQuestModel model, const char* name, int n, double min, double max)
Python bool OptQuestModel.add_integer_vector_variable(str name, int n, float min_val, float max_val)
Description

Adds an integer vector variable: n integer variables. The elements are ordinary input variables.

Each element takes the values min, min + 1, min + 2, and so on, up to max. Give whole-number bounds to get whole-number values.

Notes
Add Integer Matrix Variable
Language Function Signature
Java boolean OptQuestModel.AddIntegerMatrixVariable(String name, int m, int n, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddIntegerMatrixVariable(string name, int m, int n, double min, double max)
C++ bool OptQuestModel::AddIntegerMatrixVariable(const char* name, int m, int n, double min, double max)
C int OQAddIntegerMatrixVariable(HOptQuestModel model, const char* name, int m, int n, double min, double max)
Python bool OptQuestModel.add_integer_matrix_variable(str name, int m, int n, float min_val, float max_val)
Description

Adds an integer matrix variable: an m by n matrix of integer variables. The elements are ordinary input variables.

Each element takes the values min, min + 1, min + 2, and so on, up to max. Give whole-number bounds to get whole-number values.

Notes
Add Integer ND Variable
Language Function Signature
Java boolean OptQuestModel.AddIntegerNDVariable(String name, int[] dims, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddIntegerNDVariable(string name, int[] dims, double min, double max)
C++ bool OptQuestModel::AddIntegerNDVariable(const char* name, const int* dims, int ndims, double min, double max)
C int OQAddIntegerNDVariable(HOptQuestModel model, const char* name, const int* dims, int ndims, double min, double max)
Python bool OptQuestModel.add_integer_nd_variable(str name, list[int] dims, float min_val, float max_val)
Description

Adds an integer N-dimensional variable: an array of integer variables with the shape dims. The elements are ordinary input variables.

Each element takes the values min, min + 1, min + 2, and so on, up to max. Give whole-number bounds to get whole-number values.

Notes
Add Discrete Vector Variable
Language Function Signature
Java boolean OptQuestModel.AddDiscreteVectorVariable(String name, int n, double min, double max, double step) throws COptQuestException
C# bool OptQuestModel.AddDiscreteVectorVariable(string name, int n, double min, double max, double step)
C++ bool OptQuestModel::AddDiscreteVectorVariable(const char* name, int n, double min, double max, double step)
C int OQAddDiscreteVectorVariable(HOptQuestModel model, const char* name, int n, double min, double max, double step)
Python bool OptQuestModel.add_discrete_vector_variable(str name, int n, float min_val, float max_val, float step)
Description

Adds a discrete vector variable: n discrete variables. The elements are ordinary input variables.

Each element takes the values min, min + step, min + 2 × step, and so on. The largest value is the one nearest to max, so it can differ from max when max - min is not a whole multiple of step.

Notes
Add Discrete Matrix Variable
Language Function Signature
Java boolean OptQuestModel.AddDiscreteMatrixVariable(String name, int m, int n, double min, double max, double step) throws COptQuestException
C# bool OptQuestModel.AddDiscreteMatrixVariable(string name, int m, int n, double min, double max, double step)
C++ bool OptQuestModel::AddDiscreteMatrixVariable(const char* name, int m, int n, double min, double max, double step)
C int OQAddDiscreteMatrixVariable(HOptQuestModel model, const char* name, int m, int n, double min, double max, double step)
Python bool OptQuestModel.add_discrete_matrix_variable(str name, int m, int n, float min_val, float max_val, float step)
Description

Adds a discrete matrix variable: an m by n matrix of discrete variables. The elements are ordinary input variables.

Each element takes the values min, min + step, min + 2 × step, and so on. The largest value is the one nearest to max, so it can differ from max when max - min is not a whole multiple of step.

Notes
Add Discrete ND Variable
Language Function Signature
Java boolean OptQuestModel.AddDiscreteNDVariable(String name, int[] dims, double min, double max, double step) throws COptQuestException
C# bool OptQuestModel.AddDiscreteNDVariable(string name, int[] dims, double min, double max, double step)
C++ bool OptQuestModel::AddDiscreteNDVariable(const char* name, const int* dims, int ndims, double min, double max, double step)
C int OQAddDiscreteNDVariable(HOptQuestModel model, const char* name, const int* dims, int ndims, double min, double max, double step)
Python bool OptQuestModel.add_discrete_nd_variable(str name, list[int] dims, float min_val, float max_val, float step)
Description

Adds a discrete N-dimensional variable: an array of discrete variables with the shape dims. The elements are ordinary input variables.

Each element takes the values min, min + step, min + 2 × step, and so on. The largest value is the one nearest to max, so it can differ from max when max - min is not a whole multiple of step.

Notes
Add Binary Vector Variable
Language Function Signature
Java boolean OptQuestModel.AddBinaryVectorVariable(String name, int k) throws COptQuestException
C# bool OptQuestModel.AddBinaryVectorVariable(string name, int k)
C++ bool OptQuestModel::AddBinaryVectorVariable(const char* name, int k)
C int OQAddBinaryVectorVariable(HOptQuestModel model, const char* name, int k)
Python bool OptQuestModel.add_binary_vector_variable(str name, int k)
Description

Adds a binary vector variable: k binary variables. The elements are ordinary input variables.

Each element holds 0 or 1.

Notes
Add Binary Matrix Variable
Language Function Signature
Java boolean OptQuestModel.AddBinaryMatrixVariable(String name, int m, int n) throws COptQuestException
C# bool OptQuestModel.AddBinaryMatrixVariable(string name, int m, int n)
C++ bool OptQuestModel::AddBinaryMatrixVariable(const char* name, int m, int n)
C int OQAddBinaryMatrixVariable(HOptQuestModel model, const char* name, int m, int n)
Python bool OptQuestModel.add_binary_matrix_variable(str name, int m, int n)
Description

Adds a binary matrix variable: an m by n matrix of binary variables. The elements are ordinary input variables.

Each element holds 0 or 1.

Notes
Add Binary ND Variable
Language Function Signature
Java boolean OptQuestModel.AddBinaryNDVariable(String name, int[] dims) throws COptQuestException
C# bool OptQuestModel.AddBinaryNDVariable(string name, int[] dims)
C++ bool OptQuestModel::AddBinaryNDVariable(const char* name, const int* dims, int ndims)
C int OQAddBinaryNDVariable(HOptQuestModel model, const char* name, const int* dims, int ndims)
Python bool OptQuestModel.add_binary_nd_variable(str name, list[int] dims)
Description

Adds a binary N-dimensional variable: an array of binary variables with the shape dims. The elements are ordinary input variables.

Each element holds 0 or 1.

Notes

Permutation

A permutation variable is an ordinary decision variable. The position variables it creates are the values that the optimizer sets and the simulator reads. It is in its own family and is not one of the special purpose variables. Its element names use the same @ notation as theirs.

Add Permutation Variable

Deprecated. Use the Sequence Variable (§ Add Sequence Variable) instead. It gives the same ranks, from 1 to n, under element names of the same form, and it also has a top-k mode.

Language Function Signature
Java boolean OptQuestModel.AddPermutationVariable(String group, String[] names) throws COptQuestException
C# bool OptQuestModel.AddPermutationVariable(string group, string[] names)
C++ bool OptQuestModel::AddPermutationVariable(const char* group, const char** names, int n)
C int OQAddPermutationVariable(HOptQuestModel model, const char* group, const char** names, int n)
Python bool OptQuestModel.add_permutation_variable(str group, list[str] names)
Description

Adds a permutation variable named group over the elements in names. The engine creates one integer decision variable per element, named <group>@<name>. Its value is the position of that element in the order, from 1 to n. Every trial solution is a complete permutation: each position appears exactly once. The strings in names must be distinct.

Example
model.AddPermutationVariable("group", new String[]{"a","b","c"});

This creates three decision variables: group@a, group@b and group@c. In the generate step, OptQuest writes the position of each element into its variable. If group@a = 1, group@b = 3 and group@c = 2, the evaluator must compute its outputs for the order {a, c, b}.

Notes

Special Purpose Variables: Common Behavior

A special purpose variable is a decision variable whose values must stay inside a structured set, for example an angle on an arc, a ranking of a list of items, or a matrix of limited rank. In every solution that the engine generates, and in every suggested solution, the values of a special purpose variable are inside its set. The simulator needs no code to handle values that are not valid.

In the Java class library, COptQuestManifoldVariable is the base class of the special purpose variable types, and the Javadoc calls them manifold variables. A saved model file uses the XML element ManifoldVariable for them.

The special purpose variable types are:

The Permutation variable is in its own family and is not one of the special purpose variables. Its element names use the same @ notation as theirs. See § API Documentation › Decision Variables › Add Permutation Variable.

Variable Names

A special purpose variable creates its variables under generated names of the form <name>@<suffix>, where <name> is the base name. The Notes of each type list the variable names and the values they hold. Use these names, not the base name, in expressions, objectives and constraints. See § Concepts › Names.

GetInputNames returns the variable names of every special purpose variable, because they are inputs: the engine sets them, and the evaluator reads them. The exceptions are the coefficient, contribution and confidence names of a policy sequence variable, whose values the engine computes. GetOutputNames returns those.

The variable names of the Item Selection and Budgeted Selection variables are ordinary binary inputs: the engine chooses these values directly. The engine adds the rules of these two types and of the Assignment variable to the model as constraints, so a solution that breaks a rule is infeasible.

Evaluated and Required Solutions

The engine uses the values of the special purpose variables in an evaluated solution or a required solution as given, so supply values that are inside the set of each variable. In a suggested solution, the engine can change values that are not inside the set.

Constraint Enforcement Timing

The engine checks a constraint over the variable names of a special purpose variable, other than an Item Selection or a Budgeted Selection variable, after evaluation, the same way it checks a constraint over an output. The simulator always receives values that follow the rules of the variable type. Only the constraint check is deferred. A solution that breaks such a constraint is marked infeasible after its evaluation, so it costs a full evaluation.

When the declaration of the variable can express a restriction, declare it there: an arc on an Angle Variable, per-component bounds and sumTo on a Mixture Variable, a count or capacity range on a selection or assignment type. A restriction declared that way holds for every solution that the engine generates, and it costs no evaluation. Use a constraint over the variable names only when the declaration cannot express the rule.

The Notes of each type below list only what is specific to that type. The behavior in this section applies to every special purpose variable.

Special Purpose: Combinatorial

Add Choice Variable
Language Function Signature
Java boolean OptQuestModel.AddChoiceVariable(String name, int k) throws COptQuestException
C# bool OptQuestModel.AddChoiceVariable(string name, int k)
C++ bool OptQuestModel::AddChoiceVariable(const char* name, int k)
C int OQAddChoiceVariable(HOptQuestModel model, const char* name, int k)
Python bool OptQuestModel.add_choice_variable(str name, int k)
Description

Adds a choice variable. Its value is one option out of k options. Use a choice variable when the decision is one selection from options that have no natural order, such as a machine type, a supplier or an operating mode.

In every solution that the engine generates, exactly one option is selected.

In a suggested solution, the engine rounds the value to the nearest whole number from 1 to k.

Notes
Add Multi-Choice Variable
Language Function Signature
Java boolean OptQuestModel.AddMultiChoiceVariable(String name, String[] choices, int minSelect, int maxSelect) throws COptQuestException
C# bool OptQuestModel.AddMultiChoiceVariable(string name, string[] choices, int minSelect, int maxSelect)
C++ bool OptQuestModel::AddMultiChoiceVariable(const char* name, const char** choices, int numChoices, int minSelect, int maxSelect)
C int OQAddMultiChoiceVariable(HOptQuestModel model, const char* name, const char** choices, int numChoices, int minSelect, int maxSelect)
Python bool OptQuestModel.add_multi_choice_variable(str name, list[str] choices, int min_select, int max_select)
Description

Adds a multi-choice variable. Its value is a subset of the choices that has from minSelect to maxSelect members. Use a multi-choice variable when the decision is an unordered selection of several items and a count range is the only rule, such as which sensors to turn on or which assets to include. If there are rules between the items, use the Item Selection Variable (§ Add Item Selection Variable).

In every solution that the engine generates, each choice is either selected or not, and the number of selected choices is from minSelect to maxSelect.

In a suggested solution, the engine selects each choice whose value is greater than 0.5. If the suggested solution selects more than maxSelect choices, the engine keeps the selected choices that come first in choices. If it selects fewer than minSelect, the engine adds the unselected choices that come first.

Notes
Add Mixture Variable
Language Function Signature
Java boolean OptQuestModel.AddMixtureVariable(String name, String[] components, double[] lowerBounds, double[] upperBounds, double sumTo) throws COptQuestException
C# bool OptQuestModel.AddMixtureVariable(string name, string[] components, double[]? lowerBounds, double[]? upperBounds, double sumTo)
C++ bool OptQuestModel::AddMixtureVariable(const char* name, const char** components, int k, const double* lowerBounds, const double* upperBounds, double sumTo)
C int OQAddMixtureVariable(HOptQuestModel model, const char* name, const char** components, int k, const double* lowerBounds, const double* upperBounds, double sumTo)
Python bool OptQuestModel.add_mixture_variable(str name, list[str] components, list[float] lower_bounds=None, list[float] upper_bounds=None, float sum_to=1.0)
Description

Adds a mixture variable. Its value is a set of continuous weights, one for each component, and the weights sum to sumTo. Use a mixture variable when the decision is a set of proportions, such as portfolio weights, blend fractions or allocation ratios.

In every solution that the engine generates, the weights sum to sumTo within 1e-12, and each weight is within the bounds of its component.

With a negative lower bound, the weights can go below zero, down to that bound.

Notes
Add Sequence Variable
Language Function Signature
Java boolean OptQuestModel.AddSequenceVariable(String name, String[] components, Integer topK) throws COptQuestException
C# bool OptQuestModel.AddSequenceVariable(string name, string[] components, int? topK = null)
C++ bool OptQuestModel::AddSequenceVariable(const char* name, const char** components, int k, const int* topK)
C int OQAddSequenceVariable(HOptQuestModel model, const char* name, const char** components, int k, const int* topK)
Python bool OptQuestModel.add_sequence_variable(str name, list[str] components, int top_k=None)
Description

Adds a sequence variable. Its value is a priority order of the components. Use a sequence variable when the decision is an order of discrete items, such as a job sequence or the priority of sensor tasks.

In every solution that the engine generates, the ranks are valid. In a full ranking, the values are a permutation of 1 to n, where n is the number of components and 1 is the highest priority. In a top-k ranking, the first topK components get the ranks 1 to topK, and every other component gets the rank topK + 1.

When a suggested solution gives two components the same rank, the component that comes first in components gets the better rank.

Notes
Add Multi-Stage Sequence Variable
Language Function Signature
Java boolean OptQuestModel.AddMultiStageSequenceVariable(String name, String[][] stageGroups) throws COptQuestException
C# bool OptQuestModel.AddMultiStageSequenceVariable(string name, string[][] stageGroups)
C++ bool OptQuestModel::AddMultiStageSequenceVariable(const char* name, const char*** stageGroups, int numStages, const int* stageSizes)
C int OQAddMultiStageSequenceVariable(HOptQuestModel model, const char* name, const char*** stageGroups, int numStages, const int* stageSizes)
Python bool OptQuestModel.add_multi_stage_sequence_variable(str name, list[list[str]] stage_groups)
Description

Adds a multi-stage sequence variable. Its value is one priority order for each stage, over the components of that stage. Use a multi-stage sequence variable when the decision is a set of orders, one for each stage, such as the job order on each of several machines.

In every solution that the engine generates, the ranks in each stage are a permutation of 1 to the number of components in that stage, where 1 is the highest priority. The engine ranks each stage separately.

A component name can appear in only one stage. To rank the same item in two stages, give it a different name in each stage.

When a suggested solution gives two components of a stage the same rank, the component that comes first in that stage gets the better rank.

Notes
Add Policy Sequence Variable
Language Function Signature
Java boolean OptQuestModel.AddPolicySequenceVariable(String name, double[][] featureMatrix, String[] itemNames, String[] featureNames) throws COptQuestException
C# bool OptQuestModel.AddPolicySequenceVariable(string name, double[][] featureMatrix, string[] itemNames, string[] featureNames)
C++ bool OptQuestModel::AddPolicySequenceVariable(const char* name, const double** featureMatrix, int n, int k, const char** itemNames, const char** featureNames)
C int OQAddPolicySequenceVariable(HOptQuestModel model, const char* name, const double** featureMatrix, int n, int k, const char** itemNames, const char** featureNames)
Python bool OptQuestModel.add_policy_sequence_variable(str name, list[list[float]] feature_matrix, list[str] item_names, list[str] feature_names)
Description

Adds a policy sequence variable. Its value is a linear scoring rule over the features of a set of items: one weight for each feature, and a priority score for each item. Use a policy sequence variable when a good order depends on a few item attributes, and the weights themselves are a useful result, for example dispatch order by urgency and setup family.

In every solution that the engine generates, the item scores come from one set of feature weights applied to the feature matrix. Sort the items by descending score to get the ranked list: a higher score means a higher priority. This is the opposite of a sequence variable, where 1 is the highest priority.

The engine computes every value of a policy sequence variable. The item scores are inputs. The coefficients, the contributions and the confidences are outputs. The five families of names are in the Notes. Item names and feature names share one set of names, so every item name and feature name must be different from all the others.

Give the feature values in their own units. The engine scales the columns, so you do not need to scale them. In a suggested solution, the engine reads only the item scores, and it can change them. For an evaluated or required solution, the engine computes the coefficient, contribution and confidence outputs from the policy that best fits the supplied item scores. It does not change the scores.

Each item name and feature name must not contain whitespace, a semicolon, a comma or @.

Notes
Add Topological Sequence Variable
Language Function Signature
Java boolean OptQuestModel.AddTopologicalSequenceVariable(String name, String[] tasks, Map<String, List<String>> predecessors) throws COptQuestException
C# bool OptQuestModel.AddTopologicalSequenceVariable(string name, string[] tasks, Dictionary<string, List<string>> predecessors)
C++ bool OptQuestModel::AddTopologicalSequenceVariable(const char* name, const char* tasks[], int numTasks, const char* predecessors[][2], int numPairs)
C int OQAddTopologicalSequenceVariable(HOptQuestModel model, const char* name, const char* tasks[], int numTasks, const char* predecessors[][2], int numPairs)
Python bool OptQuestModel.add_topological_sequence_variable(str name, list[str] tasks, dict[str, list[str]] predecessors)
Description

Adds a topological sequence variable. Its value is an order of the tasks in which every task comes after its predecessors. Use a topological sequence variable when the decision is the order in which to do a set of tasks, and some tasks must always come before others, such as project steps with dependencies or an assembly sequence.

In every solution that the engine generates, the order keeps every precedence: a predecessor always has a smaller rank than the task that depends on it.

In a suggested solution, the engine keeps an order that meets every precedence, and it gives equal ranks different values in the order of tasks. If the order breaks a precedence, the engine changes it: at each step, of the tasks that can go next, the task with the smallest suggested rank goes next.

The engine checks that no task lists itself as a predecessor and that the precedences form no cycle. It ignores names in predecessors that are not in tasks.

predecessors gives the dependencies. In Java, C# and Python it is a map from a dependent task to the list of tasks that must finish before it. In C and C++ it is an array of [dependent, predecessor] pairs; a task with several predecessors appears in several pairs.

Notes
Add Assignment Variable
Language Function Signature
Java boolean OptQuestModel.AddAssignmentVariable(String name, int m, int n) throws COptQuestException
boolean OptQuestModel.AddAssignmentVariable(String name, int m, int n, boolean mustAssign, int binCapacityMin, int binCapacityMax) throws COptQuestException
boolean OptQuestModel.AddAssignmentVariable(String name, int m, int n, boolean[] mustAssign, int[] binCapacitiesMin, int[] binCapacitiesMax) throws COptQuestException
C# bool OptQuestModel.AddAssignmentVariable(string name, int m, int n)
bool OptQuestModel.AddAssignmentVariable(string name, int m, int n, bool mustAssign, int binCapacityMin, int binCapacityMax)
bool OptQuestModel.AddAssignmentVariable(string name, int m, int n, bool[] mustAssign, int[] binCapacitiesMin, int[] binCapacitiesMax)
C++ bool OptQuestModel::AddAssignmentVariable(const char* name, int m, int n)
bool OptQuestModel::AddAssignmentVariable(const char* name, int m, int n, bool mustAssign, int binCapacityMin, int binCapacityMax)
bool OptQuestModel::AddAssignmentVariable(const char* name, int m, int n, const bool* mustAssign, const int* binCapacitiesMin, const int* binCapacitiesMax)
C int OQAddAssignmentVariable(HOptQuestModel model, const char* name, int m, int n)
int OQAddAssignmentVariableHom(HOptQuestModel model, const char* name, int m, int n, int mustAssign, int binCapacityMin, int binCapacityMax)
int OQAddAssignmentVariableHet(HOptQuestModel model, const char* name, int m, int n, const int* mustAssign, const int* binCapacitiesMin, const int* binCapacitiesMax)
Python bool OptQuestModel.add_assignment_variable(str name, int m, int n, must_assign=None, bin_capacity_min=0, bin_capacity_max=None)
Description

Adds an assignment variable. Its value is an assignment of each of m items to one of n bins. Use an assignment variable when the decision assigns items to bins, such as jobs to machines or tasks to workers. Three overloads set the rules:

The engine adds the assignment rules to the model as constraints, so a solution that breaks a rule is infeasible.

In a suggested solution, the engine rounds each value to the nearest bin index, and it puts an item whose value is outside 1 to n in no bin. The engine can then change the assignment so that it meets the rules.

In Python, one method covers the three forms: omit must_assign for the simple form, pass a bool or int for the homogeneous form, or pass a sequence for the heterogeneous form.

In C, the homogeneous function takes mustAssign as an int (0 = false, non-zero = true), and the heterogeneous function takes the flags as const int* with the same convention.

Notes
Add Item Selection Variable
Language Function Signature
Java boolean OptQuestModel.AddItemSelectionVariable(String name, int n, int k) throws COptQuestException
boolean OptQuestModel.AddItemSelectionVariable(String name, int n, int kMin, int kMax) throws COptQuestException
C# bool OptQuestModel.AddItemSelectionVariable(string name, int n, int k)
bool OptQuestModel.AddItemSelectionVariable(string name, int n, int kMin, int kMax)
C++ bool OptQuestModel::AddItemSelectionVariable(const char* name, int n, int k)
bool OptQuestModel::AddItemSelectionVariable(const char* name, int n, int kMin, int kMax)
C int OQAddItemSelectionVariable(HOptQuestModel model, const char* name, int n, int k)
int OQAddItemSelectionVariableRange(HOptQuestModel model, const char* name, int n, int kMin, int kMax)
Python bool OptQuestModel.add_item_selection_variable(str name, int n, int k, int k_max=None)
Description

Adds an item selection variable. Its value is a selection of candidates from a pool of n. Use an item selection variable when the decision is which candidates to include, such as which sites to open. Two overloads set the number of candidates to select:

The engine adds the selection rule to the model as a constraint, so a solution that selects a different number of candidates is infeasible. The variable names are ordinary binary inputs. Expressions can reference them without brackets, and the engine enforces a constraint over them before evaluation, for example sel@2 + sel@5 <= 1.

In Python, one method covers both forms: omit k_max for the exact form, or supply it for the range form with k as the minimum.

In C, the exact form is OQAddItemSelectionVariable and the range form is OQAddItemSelectionVariableRange.

Notes
Add Budgeted Selection Variable
Language Function Signature
Java boolean OptQuestModel.AddBudgetedSelectionVariable(String name, int n, double[] costs, double budgetMax) throws COptQuestException
boolean OptQuestModel.AddBudgetedSelectionVariable(String name, int n, double[] costs, double budgetMin, double budgetMax, int kMin, int kMax) throws COptQuestException
C# bool OptQuestModel.AddBudgetedSelectionVariable(string name, int n, double[] costs, double budgetMax)
bool OptQuestModel.AddBudgetedSelectionVariable(string name, int n, double[] costs, double budgetMin, double budgetMax, int kMin, int kMax)
C++ bool OptQuestModel::AddBudgetedSelectionVariable(const char* name, int n, const double* costs, double budgetMax)
bool OptQuestModel::AddBudgetedSelectionVariable(const char* name, int n, const double* costs, double budgetMin, double budgetMax, int kMin, int kMax)
C int OQAddBudgetedSelectionVariable(HOptQuestModel model, const char* name, int n, const double* costs, double budgetMax)
int OQAddBudgetedSelectionVariableFull(HOptQuestModel model, const char* name, int n, const double* costs, double budgetMin, double budgetMax, int kMin, int kMax)
Python bool OptQuestModel.add_budgeted_selection_variable(str name, int n, list[float] costs, float budget_max, float budget_min=0.0, int k_min=0, int k_max=None)
Description

Adds a budgeted selection variable. Its value is a selection of candidates from a pool of n whose total cost is within a budget. Use a budgeted selection variable when the decision is which candidates to include within a budget, such as which projects to fund. Two overloads set the rules:

The engine adds the budget and count rules to the model as constraints, so a solution that breaks a rule is infeasible. The variable names are ordinary binary inputs, and expressions can reference them without brackets.

In Python, one method covers both forms: supply only budget_max for the simple form, or supply any non-default budget_min, k_min or k_max for the full form.

In C, the simple form is OQAddBudgetedSelectionVariable and the full form is OQAddBudgetedSelectionVariableFull.

Notes
Add Partition Variable
Language Function Signature
Java boolean OptQuestModel.AddPartitionVariable(String name, int m, int k) throws COptQuestException
C# bool OptQuestModel.AddPartitionVariable(string name, int m, int k)
C++ bool OptQuestModel::AddPartitionVariable(const char* name, int m, int k)
C int OQAddPartitionVariable(HOptQuestModel model, const char* name, int m, int k)
Python bool OptQuestModel.add_partition_variable(str name, int m, int k)
Description

Adds a partition variable. Its value is a division of m items into exactly k groups. The groups have no order, and no group is empty. Use a partition variable when the decision divides items into groups, such as crews into shifts or customers into delivery zones.

In every solution that the engine generates, every group has at least one item, and the same division into groups always gets the same group numbers.

In a suggested solution, the engine rounds each value to the nearest group number from 1 to k. It then fills any empty group and numbers the groups again, so the values can change.

Notes
Add DAG Variable
Language Function Signature
Java boolean OptQuestModel.AddDAGVariable(String name, String[] nodeNames) throws COptQuestException
boolean OptQuestModel.AddDAGVariable(String name, String[] nodeNames, String startNode, String endNode, boolean connected, Map<String, List<String>> predecessors) throws COptQuestException
C# bool OptQuestModel.AddDAGVariable(string name, string[] nodeNames)
bool OptQuestModel.AddDAGVariable(string name, string[] nodeNames, string? startNode, string? endNode, bool connected = false, Dictionary<string, List<string>>? predecessors = null)
C++ bool OptQuestModel::AddDAGVariable(const char* name, const char** nodeNames, int n)
bool OptQuestModel::AddDAGVariable(const char* name, const char** nodeNames, int n, const char* startNode, const char* endNode, bool connected, const char* predecessors[][2], int numPairs)
C int OQAddDAGVariable(HOptQuestModel model, const char* name, const char** nodeNames, int n)
int OQAddDAGVariableFull(HOptQuestModel model, const char* name, const char** nodeNames, int n, const char* startNode, const char* endNode, int connected, const char* predecessors[][2], int numPairs)
Python bool OptQuestModel.add_dag_variable(str name, list[str] node_names, str start_node=None, str end_node=None, bool connected=False, dict[str, list[str]] predecessors=None)
Description

Adds a DAG variable. Its value is a directed acyclic graph (DAG) over the given nodes: a set of directed edges with no cycle. Use a DAG variable when the decision is a set of one-way links with no loop, such as dependencies between tasks or a flow network.

In every solution that the engine generates, the edges form no cycle. Without options, any DAG over the nodes can occur, including the graph with no edges. You can restrict the graphs with these options:

In a suggested solution, a value greater than 0.5 is an edge. The engine keeps a suggested DAG that follows the options as it is. If the suggested edges form a cycle or break an option, the engine removes edges until the graph follows the options, and with connected it adds edges until every node is connected.

Notes
Add Tree Variable
Language Function Signature
Java boolean OptQuestModel.AddTreeVariable(String name, String[] nodeNames) throws COptQuestException
boolean OptQuestModel.AddTreeVariable(String name, String[] nodeNames, String rootNode, Map<String, List<String>> predecessors) throws COptQuestException
C# bool OptQuestModel.AddTreeVariable(string name, string[] nodeNames)
bool OptQuestModel.AddTreeVariable(string name, string[] nodeNames, string? rootNode, Dictionary<string, List<string>>? predecessors = null)
C++ bool OptQuestModel::AddTreeVariable(const char* name, const char** nodeNames, int n)
bool OptQuestModel::AddTreeVariable(const char* name, const char** nodeNames, int n, const char* rootNode, const char* predecessors[][2], int numPairs)
C int OQAddTreeVariable(HOptQuestModel model, const char* name, const char** nodeNames, int n)
int OQAddTreeVariableFull(HOptQuestModel model, const char* name, const char** nodeNames, int n, const char* rootNode, const char* predecessors[][2], int numPairs)
Python bool OptQuestModel.add_tree_variable(str name, list[str] node_names, str root_node=None, dict[str, list[str]] predecessors=None)
Description

Adds a tree variable. Its value is a directed spanning tree over the given nodes: one node is the root, every other node has exactly one incoming edge, and every node can be reached from the root. Use a tree variable when the decision is a hierarchy that connects every node, such as a cueing network or a reporting structure.

In every solution that the engine generates, the edges form a spanning tree. The tree has exactly n - 1 edges and no cycle. You can restrict the trees with these options:

In a suggested solution, a value greater than 0.5 is an edge. The engine keeps a suggested tree that follows the options as it is. Otherwise, the engine keeps one incoming edge for each node other than the root, and it uses a suggested edge where it can.

Notes
Add Path Variable
Language Function Signature
Java boolean OptQuestModel.AddPathVariable(String name, String[] nodeNames, String startNode, String endNode, String[] requiredNodes) throws COptQuestException
C# bool OptQuestModel.AddPathVariable(string name, string[] nodeNames, string? startNode = null, string? endNode = null, string[]? requiredNodes = null)
C++ bool OptQuestModel::AddPathVariable(const char* name, const char** nodeNames, int numNodes, const char* startNode, const char* endNode, const char** requiredNodes, int nRequired)
C int OQAddPathVariable(HOptQuestModel model, const char* name, const char** nodeNames, int numNodes, const char* startNode, const char* endNode, const char** requiredNodes, int nRequired)
Python bool OptQuestModel.add_path_variable(str name, list[str] node_names, str start_node=None, str end_node=None, list[str] required_nodes=None)
Description

Adds a path variable. Its value is a simple path through some of the given nodes: an order of nodes in which no node appears twice. Use a path variable when the decision is a route that visits some of the candidate nodes, such as a patrol route or a delivery tour.

In every solution that the engine generates, the path is valid. The positions of the nodes on the path are 1 to L, where L is the length of the path, with no gap and no repeat. The start node, when given, has position 1. The end node, when given and different from the start node, has position L. When the start node and the end node are the same node, it has position 1 only. Every required node is on the path. The path can have only one node.

In a suggested solution, the engine puts a node whose value is 0 or less off the path, and it uses the other values only for the order of the nodes. The engine numbers the positions again, and it adds the start node, the end node and the required nodes when they are missing.

Notes

Special Purpose: Geometric

A geometric variable places a point on a circle, on a sphere or inside a polygon. All angles are in degrees.

Add Angle Variable
Language Function Signature
Java boolean OptQuestModel.AddAngleVariable(String name, double minDeg, double maxDeg) throws COptQuestException
C# bool OptQuestModel.AddAngleVariable(string name, double minDeg, double maxDeg)
C++ bool OptQuestModel::AddAngleVariable(const char* name, double minDeg, double maxDeg)
C int OQAddAngleVariable(HOptQuestModel model, const char* name, double minDeg, double maxDeg)
Python bool OptQuestModel.add_angle_variable(str name, float min_deg, float max_deg)
Description

Adds an angle variable. Its value is an angle in degrees on an arc of the circle. Use an angle variable when the decision is a direction in a plane, such as a panel orientation or a turbine yaw.

In every solution that the engine generates, the angle is on the arc from minDeg to maxDeg. When the difference between maxDeg and minDeg is 360 or more, the arc is the full circle. Otherwise the arc goes from minDeg to maxDeg in the direction of increasing angle, so an arc with minDeg greater than maxDeg, such as 320 to 40, crosses 0.

The engine reports the angle as its equivalent in [0, 360), which can differ from the range that you declare. For example, for an arc declared from -45 to 45, the engine reports 315 for -45. To compare the value with the declared bounds, first subtract 360 while the value is greater than maxDeg.

Notes
Add Spherical Angle Variable
Language Function Signature
Java boolean OptQuestModel.AddSphericalAngleVariable(String name, double minThetaDeg, double maxThetaDeg, double minPhiDeg, double maxPhiDeg) throws COptQuestException
C# bool OptQuestModel.AddSphericalAngleVariable(string name, double minThetaDeg, double maxThetaDeg, double minPhiDeg, double maxPhiDeg)
C++ bool OptQuestModel::AddSphericalAngleVariable(const char* name, double minThetaDeg, double maxThetaDeg, double minPhiDeg, double maxPhiDeg)
C int OQAddSphericalAngleVariable(HOptQuestModel model, const char* name, double minThetaDeg, double maxThetaDeg, double minPhiDeg, double maxPhiDeg)
Python bool OptQuestModel.add_spherical_angle_variable(str name, float min_theta_deg, float max_theta_deg, float min_phi_deg, float max_phi_deg)
Description

Adds a spherical angle variable. Its value is a direction in three dimensions, given as an elevation and an azimuth in degrees. Use a spherical angle variable when the decision is a pointing direction, such as an antenna boresight or a sensor line of sight.

In every solution that the engine generates, the elevation is from minThetaDeg to maxThetaDeg, and the azimuth is on the arc from minPhiDeg to maxPhiDeg. The azimuth arc follows the same rules as the arc of an angle variable: a difference of 360 or more is the full circle, and an arc with minPhiDeg greater than maxPhiDeg crosses 0.

The engine reports the azimuth as its equivalent in [0, 360), which can differ from the range that you declare. For example, for an azimuth declared from -60 to 60, the engine reports 300 for -60. The engine reports the elevation as it is, within the declared range.

Notes
Add Region Variable
Language Function Signature
Java boolean OptQuestModel.AddRegionVariable(String name, double[][] polygon) throws COptQuestException
C# bool OptQuestModel.AddRegionVariable(string name, double[][] polygon)
C++ bool OptQuestModel::AddRegionVariable(const char* name, const double** polygon, int nVertices, int coordsPerVertex)
C int OQAddRegionVariable(HOptQuestModel model, const char* name, const double** polygon, int nVertices, int coordsPerVertex)
Python bool OptQuestModel.add_region_variable(str name, list[list[float]] polygon)
Description

Adds a region variable. Its value is a point (x, y) in a plane polygon. Use a region variable when the decision is a location inside a region, such as a site inside a property boundary.

In every solution that the engine generates, the point is inside the polygon or on its boundary. The polygon can be non-convex. A point is inside by the even-odd rule, so a polygon whose edges cross each other is also accepted.

Give the vertices in either order, clockwise or counterclockwise. You do not need to repeat the first vertex at the end.

Notes
Add Spherical Region Variable
Language Function Signature
Java boolean OptQuestModel.AddSphericalRegionVariable(String name, double[][] polygon) throws COptQuestException
C# bool OptQuestModel.AddSphericalRegionVariable(string name, double[][] polygon)
C++ bool OptQuestModel::AddSphericalRegionVariable(const char* name, const double** polygon, int nVertices, int coordsPerVertex)
C int OQAddSphericalRegionVariable(HOptQuestModel model, const char* name, const double** polygon, int nVertices, int coordsPerVertex)
Python bool OptQuestModel.add_spherical_region_variable(str name, list[list[float]] polygon)
Description

Adds a spherical region variable. Its value is a point (latitude, longitude) in a polygon on the surface of the Earth. Use a spherical region variable when the decision is a location inside a geographic region, such as a sensor site inside a border.

In every solution that the engine generates, the point is inside the region or on its boundary. The edges of the polygon are great-circle arcs, not lines of constant latitude.

List the vertices clockwise, as on a map with north up: the region is on your right as you walk from each vertex to the next. This is the Esri rule for the outer ring of a polygon. The same vertices in counterclockwise order give the rest of the Earth. A region can enclose a pole, span more than 180 degrees of longitude, or be larger than a hemisphere. For a region around the North Pole, list the vertices from east to west. You do not need to repeat the first vertex at the end. The boundary must not cross itself.

Notes

Special Purpose: Smooth

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 smooth type you set one small number: a number of knots, a number of cosine terms or a rank. In every solution that the engine generates, the values have a shape that this number allows, and every element is from min to max.

Your values Type The number that you set
A profile that changes smoothly along its length Spline Vector (the curve passes through its knots) or B-spline Vector (the curve does not pass through its knots) numKnots: fewer knots give a smoother curve
A profile made of gradual waves, such as a daily cycle Fourier Vector numFreq: fewer cosine terms give a smoother vector
A table that changes smoothly in both directions Spline Matrix, B-spline Matrix or Fourier Matrix the number of knots or cosine terms in each direction
A table whose rows follow a few common patterns Low-Rank Matrix rank: the number of row patterns
A long series that repeats, such as hourly values over many days Time-Series Vector rank: the number of repeating patterns
A known profile or table that you want to change the Correction type of any of the above as above
A correction that you build one pattern at a time, over several runs Incremental Low-Rank Correction Matrix or Incremental Time-Series Correction Vector rank: the number of the step, from 1

Each type has a correction variant. It takes a baseline, initial, and adds a smooth correction to it, so the values are initial + correction. Use a correction variant to keep a known profile or table and optimize only a smooth adjustment to it. The engine first moves each entry of initial into [min, max].

Variable names follow the container convention: <name>@1 … <name>@length for a vector, <name>@<row>,<col> for a matrix, and <name>@1 … <name>@(longScale × shortScale) for a time-series vector.

Add Low-Rank Matrix Variable
Language Function Signature
Java boolean OptQuestModel.AddLowRankMatrixVariable(String name, int rows, int cols, int rank, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddLowRankMatrixVariable(string name, int rows, int cols, int rank, double min, double max)
C++ bool OptQuestModel::AddLowRankMatrixVariable(const char* name, int rows, int cols, int rank, double min, double max)
C int OQAddLowRankMatrixVariable(HOptQuestModel model, const char* name, int rows, int cols, int rank, double min, double max)
Python bool OptQuestModel.add_lowrank_matrix_variable(str name, int rows, int cols, int rank, float min_val, float max_val)
Description

Adds a low-rank matrix variable. Its value is a rows by cols matrix that is a constant matrix plus a correction of low rank. Use a low-rank matrix variable when the decision is a large table that you can describe with a few row and column patterns.

In every solution that the engine generates, every entry is from min to max, and the matrix is the constant matrix (min + max) / 2 plus a correction of rank at most rank. So the matrix itself can have rank rank + 1.

The value of rank is the number of row patterns that the engine can combine. With rank 1, each row of the matrix is the middle value (min + max) / 2 plus one row pattern, multiplied by an amount that can differ from row to row. Each extra unit of rank adds one more row pattern. With rank 0, every entry is the middle value.

Notes
Add Low-Rank Correction Matrix Variable
Language Function Signature
Java boolean OptQuestModel.AddLowRankCorrectionMatrixVariable(String name, double[][] initial, int rank, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddLowRankCorrectionMatrixVariable(string name, double[][] initial, int rank, double min, double max)
C++ bool OptQuestModel::AddLowRankCorrectionMatrixVariable(const char* name, const double** initial, int rows, int cols, int rank, double min, double max)
C int OQAddLowRankCorrectionMatrixVariable(HOptQuestModel model, const char* name, const double** initial, int rows, int cols, int rank, double min, double max)
Python bool OptQuestModel.add_lowrank_correction_matrix_variable(str name, list[list[float]] initial, int rank, float min_val, float max_val)
Description

Adds a low-rank correction matrix variable. Its value is a baseline matrix, initial, plus a correction of low rank. Use a low-rank correction matrix variable to keep a known table and change it with a few row and column patterns.

In every solution that the engine generates, every entry is from min to max, and the matrix is initial plus a correction of rank at most rank, except where an entry of initial is on min or max and the correction points past that bound: there the engine keeps the entry on the bound, and the correction can have a higher rank. The engine first moves each entry of initial into [min, max].

Notes
Add Incremental Low-Rank Correction Matrix Variable
Language Function Signature
Java boolean OptQuestModel.AddIncrementalLowRankCorrectionMatrixVariable(String name, double[][] initial, int rank, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddIncrementalLowRankCorrectionMatrixVariable(string name, double[][] initial, int rank, double min, double max)
C++ bool OptQuestModel::AddIncrementalLowRankCorrectionMatrixVariable(const char* name, const double** initial, int rows, int cols, int rank, double min, double max)
C int OQAddIncrementalLowRankCorrectionMatrixVariable(HOptQuestModel model, const char* name, const double** initial, int rows, int cols, int rank, double min, double max)
Python bool OptQuestModel.add_incremental_lowrank_correction_matrix_variable(str name, list[list[float]] initial, int rank, float min_val, float max_val)
Description

Adds an incremental low-rank correction matrix variable. Its value is a baseline matrix, initial, plus a correction of rank 1. Use this variable to build a correction one rank at a time. Run an optimization, pass its best value as initial of the next variable of this type, and repeat. Each variable adds a correction of rank 1 and does not keep the corrections of earlier variables.

In every solution that the engine generates, every entry is from min to max, and the matrix is initial plus a correction of rank at most 1, except where an entry of initial is on min or max and the correction points past that bound: there the engine keeps the entry on the bound, and the correction can have a higher rank. The engine first moves each entry of initial into [min, max].

Notes
Add Time-Series Vector Variable
Language Function Signature
Java boolean OptQuestModel.AddTimeSeriesVectorVariable(String name, int longScale, int shortScale, int rank, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddTimeSeriesVectorVariable(string name, int longScale, int shortScale, int rank, double min, double max)
C++ bool OptQuestModel::AddTimeSeriesVectorVariable(const char* name, int longScale, int shortScale, int rank, double min, double max)
C int OQAddTimeSeriesVectorVariable(HOptQuestModel model, const char* name, int longScale, int shortScale, int rank, double min, double max)
Python bool OptQuestModel.add_timeseries_vector_variable(str name, int long_scale, int short_scale, int rank, float min_val, float max_val)
Description

Adds a time-series vector variable. Its value is a vector of longScale × shortScale values. The engine arranges the values row by row as a longScale by shortScale matrix, and the matrix is a constant plus a correction of low rank. Use a time-series vector variable when the decision is a long vector with a repeating pattern, such as hourly values over many days.

In every solution that the engine generates, every value is from min to max, and the matrix is the constant matrix (min + max) / 2 plus a correction of rank at most rank.

The value of rank is the number of patterns that the engine can combine. With days as rows, hours as columns and rank 1, each day is the middle value (min + max) / 2 plus one pattern over the hours, multiplied by an amount that can differ from day to day. So every day has the same shape, and the size of the change can differ from day to day. Each extra unit of rank adds one more pattern. With rank 0, every value is the middle value.

Notes
Add Time-Series Correction Vector Variable
Language Function Signature
Java boolean OptQuestModel.AddTimeSeriesCorrectionVectorVariable(String name, double[] initial, int longScale, int shortScale, int rank, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddTimeSeriesCorrectionVectorVariable(string name, double[] initial, int longScale, int shortScale, int rank, double min, double max)
C++ bool OptQuestModel::AddTimeSeriesCorrectionVectorVariable(const char* name, const double* initial, int longScale, int shortScale, int rank, double min, double max)
C int OQAddTimeSeriesCorrectionVectorVariable(HOptQuestModel model, const char* name, const double* initial, int longScale, int shortScale, int rank, double min, double max)
Python bool OptQuestModel.add_timeseries_correction_vector_variable(str name, list[float] initial, int long_scale, int short_scale, int rank, float min_val, float max_val)
Description

Adds a time-series correction vector variable. Its value is a baseline vector, initial, plus a correction. The engine arranges the values row by row as a longScale by shortScale matrix, and the correction to that matrix has low rank. Use a time-series correction vector variable to keep a known profile and change it with a few repeating patterns.

In every solution that the engine generates, every value is from min to max, and the matrix is initial plus a correction of rank at most rank, except where an entry of initial is on min or max and the correction points past that bound: there the engine keeps the entry on the bound, and the correction can have a higher rank. The engine first moves each entry of initial into [min, max].

Notes
Add Incremental Time-Series Correction Vector Variable
Language Function Signature
Java boolean OptQuestModel.AddIncrementalTimeSeriesCorrectionVectorVariable(String name, double[] initial, int longScale, int shortScale, int rank, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddIncrementalTimeSeriesCorrectionVectorVariable(string name, double[] initial, int longScale, int shortScale, int rank, double min, double max)
C++ bool OptQuestModel::AddIncrementalTimeSeriesCorrectionVectorVariable(const char* name, const double* initial, int longScale, int shortScale, int rank, double min, double max)
C int OQAddIncrementalTimeSeriesCorrectionVectorVariable(HOptQuestModel model, const char* name, const double* initial, int longScale, int shortScale, int rank, double min, double max)
Python bool OptQuestModel.add_incremental_timeseries_correction_vector_variable(str name, list[float] initial, int long_scale, int short_scale, int rank, float min_val, float max_val)
Description

Adds an incremental time-series correction vector variable. Its value is a baseline vector, initial, plus a correction. The engine arranges the values row by row as a longScale by shortScale matrix, and the correction to that matrix has rank 1. Use this variable to build a correction one rank at a time. Run an optimization, pass its best value as initial of the next variable of this type, and repeat. Each variable adds a correction of rank 1 and does not keep the corrections of earlier variables.

In every solution that the engine generates, every value is from min to max, and the matrix is initial plus a correction of rank at most 1, except where an entry of initial is on min or max and the correction points past that bound: there the engine keeps the entry on the bound, and the correction can have a higher rank. The engine first moves each entry of initial into [min, max].

Notes
Add BSpline Vector Variable
Language Function Signature
Java boolean OptQuestModel.AddBSplineVectorVariable(String name, int length, int numKnots, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddBSplineVectorVariable(string name, int length, int numKnots, double min, double max)
C++ bool OptQuestModel::AddBSplineVectorVariable(const char* name, int length, int numKnots, double min, double max)
C int OQAddBSplineVectorVariable(HOptQuestModel model, const char* name, int length, int numKnots, double min, double max)
Python bool OptQuestModel.add_bspline_vector_variable(str name, int length, int num_knots, float min_val, float max_val)
Description

Adds a B-spline vector variable. Its value is a vector of length values on a smooth curve defined by numKnots knots. Use a B-spline vector variable when the decision is a long profile that changes smoothly, such as a setpoint schedule.

The curve is a uniform cubic B-spline. It is smooth, and it does not pass through its knots: each value is a weighted average of the nearby knot values. The knots are at evenly spaced elements, with the first and last knots at the two ends.

In every solution that the engine generates, every element is from min to max.

Notes
Add Spline Vector Variable
Language Function Signature
Java boolean OptQuestModel.AddSplineVectorVariable(String name, int length, int numKnots, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddSplineVectorVariable(string name, int length, int numKnots, double min, double max)
C++ bool OptQuestModel::AddSplineVectorVariable(const char* name, int length, int numKnots, double min, double max)
C int OQAddSplineVectorVariable(HOptQuestModel model, const char* name, int length, int numKnots, double min, double max)
Python bool OptQuestModel.add_spline_vector_variable(str name, int length, int num_knots, float min_val, float max_val)
Description

Adds a spline vector variable. Its value is a vector of length values on a smooth curve through numKnots knots. Use a spline vector variable when the decision is a long profile that changes smoothly, such as a setpoint schedule.

The curve is a centripetal Catmull-Rom spline. It is smooth, and it passes through its knots. The knots are at evenly spaced elements, with the first and last knots at the two ends.

In every solution that the engine generates, every element is from min to max.

Notes
Add BSpline Correction Vector Variable
Language Function Signature
Java boolean OptQuestModel.AddBSplineCorrectionVectorVariable(String name, double[] initial, int numKnots, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddBSplineCorrectionVectorVariable(string name, double[] initial, int numKnots, double min, double max)
C++ bool OptQuestModel::AddBSplineCorrectionVectorVariable(const char* name, const double* initial, int n, int numKnots, double min, double max)
C int OQAddBSplineCorrectionVectorVariable(HOptQuestModel model, const char* name, const double* initial, int n, int numKnots, double min, double max)
Python bool OptQuestModel.add_bspline_correction_vector_variable(str name, list[float] initial, int num_knots, float min_val, float max_val)
Description

Adds a B-spline correction vector variable. Its value is a baseline vector, initial, plus a correction on a smooth curve defined by numKnots knots. Use a B-spline correction vector variable to keep a known profile and change it smoothly.

The curve is a uniform cubic B-spline. It is smooth, and it does not pass through its knots: each value is a weighted average of the nearby knot values. The knots are at evenly spaced elements, with the first and last knots at the two ends.

In every solution that the engine generates, every element is from min to max. The engine first moves each entry of initial into [min, max].

Notes
Add Spline Correction Vector Variable
Language Function Signature
Java boolean OptQuestModel.AddSplineCorrectionVectorVariable(String name, double[] initial, int numKnots, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddSplineCorrectionVectorVariable(string name, double[] initial, int numKnots, double min, double max)
C++ bool OptQuestModel::AddSplineCorrectionVectorVariable(const char* name, const double* initial, int n, int numKnots, double min, double max)
C int OQAddSplineCorrectionVectorVariable(HOptQuestModel model, const char* name, const double* initial, int n, int numKnots, double min, double max)
Python bool OptQuestModel.add_spline_correction_vector_variable(str name, list[float] initial, int num_knots, float min_val, float max_val)
Description

Adds a spline correction vector variable. Its value is a baseline vector, initial, plus a correction on a smooth curve through numKnots knots. Use a spline correction vector variable to keep a known profile and change it smoothly.

The curve is a centripetal Catmull-Rom spline. It is smooth, and it passes through its knots. The knots are at evenly spaced elements, with the first and last knots at the two ends.

In every solution that the engine generates, every element is from min to max. The engine first moves each entry of initial into [min, max].

Notes
Add BSpline Matrix Variable
Language Function Signature
Java boolean OptQuestModel.AddBSplineMatrixVariable(String name, int rows, int cols, int knotRows, int knotCols, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddBSplineMatrixVariable(string name, int rows, int cols, int knotRows, int knotCols, double min, double max)
C++ bool OptQuestModel::AddBSplineMatrixVariable(const char* name, int rows, int cols, int knotRows, int knotCols, double min, double max)
C int OQAddBSplineMatrixVariable(HOptQuestModel model, const char* name, int rows, int cols, int knotRows, int knotCols, double min, double max)
Python bool OptQuestModel.add_bspline_matrix_variable(str name, int rows, int cols, int knot_rows, int knot_cols, float min_val, float max_val)
Description

Adds a B-spline matrix variable. Its value is a rows by cols matrix on a smooth surface defined by a grid of knots. Use a B-spline matrix variable when the decision is a large table that changes smoothly in both directions.

The surface is a uniform cubic B-spline. It is smooth, and it does not pass through its knots: each value is a weighted average of the nearby knot values. The knots form a knotRows by knotCols grid at evenly spaced rows and columns, with knots at all four edges.

In every solution that the engine generates, every entry is from min to max.

Notes
Add Spline Matrix Variable
Language Function Signature
Java boolean OptQuestModel.AddSplineMatrixVariable(String name, int rows, int cols, int knotRows, int knotCols, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddSplineMatrixVariable(string name, int rows, int cols, int knotRows, int knotCols, double min, double max)
C++ bool OptQuestModel::AddSplineMatrixVariable(const char* name, int rows, int cols, int knotRows, int knotCols, double min, double max)
C int OQAddSplineMatrixVariable(HOptQuestModel model, const char* name, int rows, int cols, int knotRows, int knotCols, double min, double max)
Python bool OptQuestModel.add_spline_matrix_variable(str name, int rows, int cols, int knot_rows, int knot_cols, float min_val, float max_val)
Description

Adds a spline matrix variable. Its value is a rows by cols matrix on a smooth surface through a grid of knots. Use a spline matrix variable when the decision is a large table that changes smoothly in both directions.

The surface is a centripetal Catmull-Rom spline. It is smooth, and it passes through its knots. The knots form a knotRows by knotCols grid at evenly spaced rows and columns, with knots at all four edges.

In every solution that the engine generates, every entry is from min to max.

Notes
Add BSpline Correction Matrix Variable
Language Function Signature
Java boolean OptQuestModel.AddBSplineCorrectionMatrixVariable(String name, double[][] initial, int knotRows, int knotCols, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddBSplineCorrectionMatrixVariable(string name, double[][] initial, int knotRows, int knotCols, double min, double max)
C++ bool OptQuestModel::AddBSplineCorrectionMatrixVariable(const char* name, const double** initial, int rows, int cols, int knotRows, int knotCols, double min, double max)
C int OQAddBSplineCorrectionMatrixVariable(HOptQuestModel model, const char* name, const double** initial, int rows, int cols, int knotRows, int knotCols, double min, double max)
Python bool OptQuestModel.add_bspline_correction_matrix_variable(str name, list[list[float]] initial, int knot_rows, int knot_cols, float min_val, float max_val)
Description

Adds a B-spline correction matrix variable. Its value is a baseline matrix, initial, plus a correction on a smooth surface defined by a grid of knots. Use a B-spline correction matrix variable to keep a known table and change it smoothly.

The surface is a uniform cubic B-spline. It is smooth, and it does not pass through its knots: each value is a weighted average of the nearby knot values. The knots form a knotRows by knotCols grid at evenly spaced rows and columns, with knots at all four edges.

In every solution that the engine generates, every entry is from min to max. The engine first moves each entry of initial into [min, max].

Notes
Add Spline Correction Matrix Variable
Language Function Signature
Java boolean OptQuestModel.AddSplineCorrectionMatrixVariable(String name, double[][] initial, int knotRows, int knotCols, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddSplineCorrectionMatrixVariable(string name, double[][] initial, int knotRows, int knotCols, double min, double max)
C++ bool OptQuestModel::AddSplineCorrectionMatrixVariable(const char* name, const double** initial, int rows, int cols, int knotRows, int knotCols, double min, double max)
C int OQAddSplineCorrectionMatrixVariable(HOptQuestModel model, const char* name, const double** initial, int rows, int cols, int knotRows, int knotCols, double min, double max)
Python bool OptQuestModel.add_spline_correction_matrix_variable(str name, list[list[float]] initial, int knot_rows, int knot_cols, float min_val, float max_val)
Description

Adds a spline correction matrix variable. Its value is a baseline matrix, initial, plus a correction on a smooth surface through a grid of knots. Use a spline correction matrix variable to keep a known table and change it smoothly.

The surface is a centripetal Catmull-Rom spline. It is smooth, and it passes through its knots. The knots form a knotRows by knotCols grid at evenly spaced rows and columns, with knots at all four edges.

In every solution that the engine generates, every entry is from min to max. The engine first moves each entry of initial into [min, max].

Notes
Add Fourier Vector Variable
Language Function Signature
Java boolean OptQuestModel.AddFourierVectorVariable(String name, int length, int numFreq, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddFourierVectorVariable(string name, int length, int numFreq, double min, double max)
C++ bool OptQuestModel::AddFourierVectorVariable(const char* name, int length, int numFreq, double min, double max)
C int OQAddFourierVectorVariable(HOptQuestModel model, const char* name, int length, int numFreq, double min, double max)
Python bool OptQuestModel.add_fourier_vector_variable(str name, int length, int num_freq, float min_val, float max_val)
Description

Adds a Fourier vector variable. Its value is a vector of length values that is a sum of the numFreq lowest-frequency cosine terms. Use a Fourier vector variable when the decision is a long profile that varies smoothly, such as a daily cycle.

The first term is a constant. The second term is half of a cosine wave across the whole vector. Each next term adds one more half wave, so the later terms add finer detail. With one term, every element has the same value. For element i, counted from 1, term k is cos(π k (i - 0.5) / length), where k counts from 0.

In every solution that the engine generates, every element is from min to max.

Notes
Add Fourier Matrix Variable
Language Function Signature
Java boolean OptQuestModel.AddFourierMatrixVariable(String name, int rows, int cols, int freqRows, int freqCols, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddFourierMatrixVariable(string name, int rows, int cols, int freqRows, int freqCols, double min, double max)
C++ bool OptQuestModel::AddFourierMatrixVariable(const char* name, int rows, int cols, int freqRows, int freqCols, double min, double max)
C int OQAddFourierMatrixVariable(HOptQuestModel model, const char* name, int rows, int cols, int freqRows, int freqCols, double min, double max)
Python bool OptQuestModel.add_fourier_matrix_variable(str name, int rows, int cols, int freq_rows, int freq_cols, float min_val, float max_val)
Description

Adds a Fourier matrix variable. Its value is a rows by cols matrix that is a sum of the lowest-frequency cosine terms: freqRows terms down the columns and freqCols terms along the rows. Use a Fourier matrix variable when the decision is a large table that varies smoothly in both directions.

The terms are products of a cosine down the columns and a cosine along the rows, like the terms of the vector type. With one term down the columns, every row is the same. With one term along the rows, every column is the same.

In every solution that the engine generates, every entry is from min to max.

Notes
Add Fourier Correction Vector Variable
Language Function Signature
Java boolean OptQuestModel.AddFourierCorrectionVectorVariable(String name, double[] initial, int numFreq, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddFourierCorrectionVectorVariable(string name, double[] initial, int numFreq, double min, double max)
C++ bool OptQuestModel::AddFourierCorrectionVectorVariable(const char* name, const double* initial, int n, int numFreq, double min, double max)
C int OQAddFourierCorrectionVectorVariable(HOptQuestModel model, const char* name, const double* initial, int n, int numFreq, double min, double max)
Python bool OptQuestModel.add_fourier_correction_vector_variable(str name, list[float] initial, int num_freq, float min_val, float max_val)
Description

Adds a Fourier correction vector variable. Its value is a baseline vector, initial, plus a correction that is a sum of the numFreq lowest-frequency cosine terms. Use a Fourier correction vector variable to keep a known profile and change it smoothly.

The first term is a constant. The second term is half of a cosine wave across the whole vector. Each next term adds one more half wave, so the later terms add finer detail. With one term, the correction has the same value at every element. For element i, counted from 1, term k is cos(π k (i - 0.5) / n), where k counts from 0 and n is the length of initial.

In every solution that the engine generates, every element is from min to max. The engine first moves each entry of initial into [min, max].

Notes
Add Fourier Correction Matrix Variable
Language Function Signature
Java boolean OptQuestModel.AddFourierCorrectionMatrixVariable(String name, double[][] initial, int freqRows, int freqCols, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddFourierCorrectionMatrixVariable(string name, double[][] initial, int freqRows, int freqCols, double min, double max)
C++ bool OptQuestModel::AddFourierCorrectionMatrixVariable(const char* name, const double** initial, int rows, int cols, int freqRows, int freqCols, double min, double max)
C int OQAddFourierCorrectionMatrixVariable(HOptQuestModel model, const char* name, const double** initial, int rows, int cols, int freqRows, int freqCols, double min, double max)
Python bool OptQuestModel.add_fourier_correction_matrix_variable(str name, list[list[float]] initial, int freq_rows, int freq_cols, float min_val, float max_val)
Description

Adds a Fourier correction matrix variable. Its value is a baseline matrix, initial, plus a correction that is a sum of the lowest-frequency cosine terms: freqRows terms down the columns and freqCols terms along the rows. Use a Fourier correction matrix variable to keep a known table and change it smoothly.

The terms are products of a cosine down the columns and a cosine along the rows, like the terms of the vector type. With one term down the columns, every row of the correction is the same. With one term along the rows, every column of the correction is the same.

In every solution that the engine generates, every entry is from min to max. The engine first moves each entry of initial into [min, max].

Notes

Random

Each function in this family adds a variable named name whose value is a random draw. At the start of every replication the engine draws a new value from the named distribution. Within one replication the value is fixed; between replications it changes. Without SetReplications, each trial solution has one replication, so it gets one draw, and its result depends on that one draw. To compare trial solutions by the combined result of several draws, call SetReplications with more than one replication (see § Stochastic Simulation Optimization). The evaluator reads it like any other input, and GetInputNames lists it. The distributions follow the scipy.stats definitions given in § Reference › Probability Distributions.

Add Beta Random Variable
Language Function Signature
Java boolean OptQuestModel.AddBetaRandomVariable(String name, double alpha, double beta) throws COptQuestException
C# bool OptQuestModel.AddBetaRandomVariable(string name, double alpha, double beta)
C++ bool OptQuestModel::AddBetaRandomVariable(const char* name, double alpha, double beta)
C int OQAddBetaRandomVariable(HOptQuestModel model, const char* name, double alpha, double beta)
Python bool OptQuestModel.add_beta_random_variable(str name, float alpha, float beta)
Description

Adds a Beta-distributed variable with the shape parameters alpha and beta, both greater than 0.

Add Cauchy Random Variable
Language Function Signature
Java boolean OptQuestModel.AddCauchyRandomVariable(String name, double location, double scale) throws COptQuestException
C# bool OptQuestModel.AddCauchyRandomVariable(string name, double location, double scale)
C++ bool OptQuestModel::AddCauchyRandomVariable(const char* name, double location, double scale)
C int OQAddCauchyRandomVariable(HOptQuestModel model, const char* name, double location, double scale)
Python bool OptQuestModel.add_cauchy_random_variable(str name, float location, float scale)
Description

Adds a Cauchy-distributed variable with the location parameter location and the scale parameter scale, which must be greater than 0.

Add Chi-Square Random Variable
Language Function Signature
Java boolean OptQuestModel.AddChiSquareRandomVariable(String name, int df) throws COptQuestException
C# bool OptQuestModel.AddChiSquareRandomVariable(string name, int df)
C++ bool OptQuestModel::AddChiSquareRandomVariable(const char* name, int df)
C int OQAddChiSquareRandomVariable(HOptQuestModel model, const char* name, int df)
Python bool OptQuestModel.add_chi_square_random_variable(str name, int df)
Description

Adds a Chi-square-distributed variable with df degrees of freedom, a positive integer.

Add Exponential Random Variable
Language Function Signature
Java boolean OptQuestModel.AddExponentialRandomVariable(String name, double scale) throws COptQuestException
C# bool OptQuestModel.AddExponentialRandomVariable(string name, double scale)
C++ bool OptQuestModel::AddExponentialRandomVariable(const char* name, double scale)
C int OQAddExponentialRandomVariable(HOptQuestModel model, const char* name, double scale)
Python bool OptQuestModel.add_exponential_random_variable(str name, float scale)
Description

Adds an exponentially distributed variable with the scale parameter scale, which must be greater than 0.

Add Gamma Random Variable
Language Function Signature
Java boolean OptQuestModel.AddGammaRandomVariable(String name, double shape, double scale) throws COptQuestException
C# bool OptQuestModel.AddGammaRandomVariable(string name, double shape, double scale)
C++ bool OptQuestModel::AddGammaRandomVariable(const char* name, double shape, double scale)
C int OQAddGammaRandomVariable(HOptQuestModel model, const char* name, double shape, double scale)
Python bool OptQuestModel.add_gamma_random_variable(str name, float shape, float scale)
Description

Adds a Gamma-distributed variable with the shape parameter shape and the scale parameter scale, both greater than 0.

Add Log-Normal Random Variable
Language Function Signature
Java boolean OptQuestModel.AddLogNormalRandomVariable(String name, double shape, double scale) throws COptQuestException
C# bool OptQuestModel.AddLogNormalRandomVariable(string name, double shape, double scale)
C++ bool OptQuestModel::AddLogNormalRandomVariable(const char* name, double shape, double scale)
C int OQAddLogNormalRandomVariable(HOptQuestModel model, const char* name, double shape, double scale)
Python bool OptQuestModel.add_log_normal_random_variable(str name, float shape, float scale)
Description

Adds a log-normally distributed variable with the shape parameter shape and the scale parameter scale, both greater than 0.

Add Normal Random Variable
Language Function Signature
Java boolean OptQuestModel.AddNormalRandomVariable(String name, double mean, double sigma) throws COptQuestException
C# bool OptQuestModel.AddNormalRandomVariable(string name, double mean, double sigma)
C++ bool OptQuestModel::AddNormalRandomVariable(const char* name, double mean, double sigma)
C int OQAddNormalRandomVariable(HOptQuestModel model, const char* name, double mean, double sigma)
Python bool OptQuestModel.add_normal_random_variable(str name, float mean, float sigma)
Description

Adds a normally distributed variable with the mean mean and the standard deviation sigma, which must be greater than 0.

Add Pareto Random Variable
Language Function Signature
Java boolean OptQuestModel.AddParetoRandomVariable(String name, double gamma, double loc, double scale) throws COptQuestException
C# bool OptQuestModel.AddParetoRandomVariable(string name, double gamma, double loc, double scale)
C++ bool OptQuestModel::AddParetoRandomVariable(const char* name, double gamma, double loc, double scale)
C int OQAddParetoRandomVariable(HOptQuestModel model, const char* name, double gamma, double loc, double scale)
Python bool OptQuestModel.add_pareto_random_variable(str name, float gamma, float loc, float scale)
Description

Adds a Pareto-distributed variable with the shape parameter gamma (greater than 0), the location parameter loc and the scale parameter scale (greater than 0). The smallest possible value is loc + scale. SetSampleRDSPareto uses the same three parameters.

Add Poisson Random Variable
Language Function Signature
Java boolean OptQuestModel.AddPoissonRandomVariable(String name, double lambda) throws COptQuestException
C# bool OptQuestModel.AddPoissonRandomVariable(string name, double lambda)
C++ bool OptQuestModel::AddPoissonRandomVariable(const char* name, double lambda)
C int OQAddPoissonRandomVariable(HOptQuestModel model, const char* name, double lambda)
Python bool OptQuestModel.add_poisson_random_variable(str name, float lambda_)
Description

Adds a Poisson-distributed variable with the rate parameter lambda, which must be greater than 0. In Python the parameter is lambda_, because lambda is a keyword.

Add Power Random Variable
Language Function Signature
Java boolean OptQuestModel.AddPowerRandomVariable(String name, double rmin, double rmax, double power) throws COptQuestException
C# bool OptQuestModel.AddPowerRandomVariable(string name, double rmin, double rmax, double power)
C++ bool OptQuestModel::AddPowerRandomVariable(const char* name, double rmin, double rmax, double power)
C int OQAddPowerRandomVariable(HOptQuestModel model, const char* name, double rmin, double rmax, double power)
Python bool OptQuestModel.add_power_random_variable(str name, float rmin, float rmax, float power)
Description

Adds a random variable whose value is from rmin to rmax. Use power to set where most of the values are. With power = 1, every value in the range is equally likely. With power = 2, the values are the distances from the center of points spread evenly over the area of a ring with the radii rmin and rmax. With power = 3, they are the distances from the center of points spread evenly over the volume of a spherical shell. With a larger power, more values are near rmax. With a power between 0 and 1, more values are near rmin.

The probability density is proportional to x^(power - 1):

pdf(x) = power * x^(power - 1) / (rmax^power - rmin^power) for rmin <= x <= rmax.

With power = 1, the density is the constant 1 / (rmax - rmin).

power must be greater than 0, rmin must be at least 0, and rmax must be greater than rmin. A power of 0 or less is rejected; the uniform case is power = 1.

Add Spherical Elevation Random Variable
Language Function Signature
Java boolean OptQuestModel.AddSphericalElevationRandomVariable(String name, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddSphericalElevationRandomVariable(string name, double min, double max)
C++ bool OptQuestModel::AddSphericalElevationRandomVariable(const char* name, double min, double max)
C int OQAddSphericalElevationRandomVariable(HOptQuestModel model, const char* name, double min, double max)
Python bool OptQuestModel.add_spherical_elevation_random_variable(str name, float min_val, float max_val)
Description

Adds a spherical elevation variable, drawn uniformly by surface area from the band of the unit sphere between the elevations min and max in degrees. Uniform by surface area, rather than uniform by angle, means that values near the horizon are more likely than values near the poles. This matches a random pointing direction on a band of the sphere, as used in radar, antenna and surveillance models. The elevation convention is the engineering one: -90° is straight down, 0° is the horizon and +90° is straight up. The bounds must lie within [-90°, +90°].

Add Student T Random Variable
Language Function Signature
Java boolean OptQuestModel.AddStudentTRandomVariable(String name, int df) throws COptQuestException
C# bool OptQuestModel.AddStudentTRandomVariable(string name, int df)
C++ bool OptQuestModel::AddStudentTRandomVariable(const char* name, int df)
C int OQAddStudentTRandomVariable(HOptQuestModel model, const char* name, int df)
Python bool OptQuestModel.add_student_t_random_variable(str name, int df)
Description

Adds a Student’s t-distributed variable with df degrees of freedom, a positive integer.

Add Uniform Random Variable
Language Function Signature
Java boolean OptQuestModel.AddUniformRandomVariable(String name, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddUniformRandomVariable(string name, double min, double max)
C++ bool OptQuestModel::AddUniformRandomVariable(const char* name, double min, double max)
C int OQAddUniformRandomVariable(HOptQuestModel model, const char* name, double min, double max)
Python bool OptQuestModel.add_uniform_random_variable(str name, float min_val, float max_val)
Description

Adds a uniformly distributed variable on [min, max], where max must be greater than min.

Add Weibull Random Variable
Language Function Signature
Java boolean OptQuestModel.AddWeibullRandomVariable(String name, double shape, double scale) throws COptQuestException
C# bool OptQuestModel.AddWeibullRandomVariable(string name, double shape, double scale)
C++ bool OptQuestModel::AddWeibullRandomVariable(const char* name, double shape, double scale)
C int OQAddWeibullRandomVariable(HOptQuestModel model, const char* name, double shape, double scale)
Python bool OptQuestModel.add_weibull_random_variable(str name, float shape, float scale)
Description

Adds a Weibull-distributed variable with the shape parameter shape and the scale parameter scale, both greater than 0.

Output Variables

An output variable holds a value that the simulation writes for each trial solution. The engine never assigns it. The evaluator sets it with SetValue before the solution is submitted. In a solution from CreateSolution, and in the solution that a managed optimization gives to the evaluator, each output is NaN until the evaluator sets it, in each replication. If the evaluator does not set an output, each objective and constraint that uses it is NaN, and the solution is infeasible. The engine reports no error, and an infeasible solution with a NaN objective ranks after the other infeasible solutions. Set every output before you submit a solution, or reject the solution. A solution that you add with AddEvaluated keeps the output values that you give it. The output vector, matrix and ND functions create one output variable per element with the same element names as the container decision variables.

Add Output Variable

Language Function Signature
Java boolean OptQuestModel.AddOutputVariable(String name) throws COptQuestException
C# bool OptQuestModel.AddOutputVariable(string name)
C++ bool OptQuestModel::AddOutputVariable(const char* name)
C int OQAddOutputVariable(HOptQuestModel model, const char* name)
Python bool OptQuestModel.add_output_variable(str name)
Description

Adds an output variable named name.

Set Output Statistic Parameters

Language Function Signature
Java boolean OptQuestModel.SetOutputStatistic(String name, int statistic) throws COptQuestException
boolean OptQuestModel.SetOutputStatistic(String name, int statistic, double statisticValue) throws COptQuestException
C# bool OptQuestModel.SetOutputStatistic(string name, int statistic)
bool OptQuestModel.SetOutputStatistic(string name, int statistic, double statisticValue)
C++ bool OptQuestModel::SetOutputStatistic(const char* name, int statistic, double statisticValue = 0)
C int OQSetOutputStatistic(HOptQuestModel model, const char* name, int statistic, double statisticValue)
Python bool OptQuestModel.set_output_statistic(str name, int statistic, float statistic_value=None)
Description

Sets how the engine aggregates the output variable name across the replications of a trial. The setting is ignored when the model runs without replications. statistic is one of the values in the table below. statisticValue is used only with Percentile, where it selects the percentile as a fraction in [0, 1] (0.95 for the 95th percentile); a value outside that range is refused. The other statistics ignore it.

Statistic Java, C# C++ C, Python
None OptQuestModel.Statistic.None OptQuestModel::Statistic::None OQStatisticNone
Mean OptQuestModel.Statistic.Mean OptQuestModel::Statistic::Mean OQStatisticMean
Median OptQuestModel.Statistic.Median OptQuestModel::Statistic::Median OQStatisticMedian
Percentile OptQuestModel.Statistic.Percentile OptQuestModel::Statistic::Percentile OQStatisticPercentile
Standard Deviation OptQuestModel.Statistic.StdDev OptQuestModel::Statistic::StdDev OQStatisticStdDev
Variance OptQuestModel.Statistic.Variance OptQuestModel::Statistic::Variance OQStatisticVariance
Coefficient of Variation OptQuestModel.Statistic.CoeffOfVar OptQuestModel::Statistic::CoeffOfVar OQStatisticCoeffOfVar
Min OptQuestModel.Statistic.Min OptQuestModel::Statistic::Min OQStatisticMin
Max OptQuestModel.Statistic.Max OptQuestModel::Statistic::Max OQStatisticMax
Sum OptQuestModel.Statistic.Sum OptQuestModel::Statistic::Sum OQStatisticSum
Notes

Add Output Vector Variable

Language Function Signature
Java boolean OptQuestModel.AddOutputVectorVariable(String name, int n) throws COptQuestException
C# bool OptQuestModel.AddOutputVectorVariable(string name, int n)
C++ bool OptQuestModel::AddOutputVectorVariable(const char* name, int n)
C int OQAddOutputVectorVariable(HOptQuestModel model, const char* name, int n)
Python bool OptQuestModel.add_output_vector_variable(str name, int n)
Description

Adds an output vector variable: n output variables. The elements are ordinary output variables, and GetOutputNames returns their names.

The simulator writes a value to each element before it submits the solution.

Notes

Add Output Matrix Variable

Language Function Signature
Java boolean OptQuestModel.AddOutputMatrixVariable(String name, int rows, int cols) throws COptQuestException
C# bool OptQuestModel.AddOutputMatrixVariable(string name, int rows, int cols)
C++ bool OptQuestModel::AddOutputMatrixVariable(const char* name, int rows, int cols)
C int OQAddOutputMatrixVariable(HOptQuestModel model, const char* name, int rows, int cols)
Python bool OptQuestModel.add_output_matrix_variable(str name, int rows, int cols)
Description

Adds an output matrix variable: a rows by cols matrix of output variables. The elements are ordinary output variables, and GetOutputNames returns their names.

The simulator writes a value to each element before it submits the solution.

Notes

Add Output ND Variable

Language Function Signature
Java boolean OptQuestModel.AddOutputNDVariable(String name, int[] dims) throws COptQuestException
C# bool OptQuestModel.AddOutputNDVariable(string name, int[] dims)
C++ bool OptQuestModel::AddOutputNDVariable(const char* name, const int* dims, int ndims)
C int OQAddOutputNDVariable(HOptQuestModel model, const char* name, const int* dims, int ndims)
Python bool OptQuestModel.add_output_nd_variable(str name, list[int] dims)
Description

Adds an output N-dimensional variable: an array of output variables with the shape dims. The elements are ordinary output variables, and GetOutputNames returns their names.

The simulator writes a value to each element before it submits the solution.

Notes

Expression Variables

An expression variable is a derived value. The engine recomputes it from its formula after every evaluation.

Add Expression Variable

Language Function Signature
Java boolean OptQuestModel.AddExpressionVariable(String name, String expression) throws COptQuestException
C# bool OptQuestModel.AddExpressionVariable(string name, string expression)
C++ bool OptQuestModel::AddExpressionVariable(const char* name, const char* expression)
C int OQAddExpressionVariable(HOptQuestModel model, const char* name, const char* expression)
Python bool OptQuestModel.add_expression_variable(str name, str expression)
Description

Adds an expression variable named name with the formula expression. The formula can reference input variables, output variables and expression variables that were added earlier. After every solution evaluation the engine recomputes the value. You can read it with OptQuestSolution.GetValue(name) and reference it in objectives, constraints, sample metrics and later expression variables. SetValue cannot assign it; the engine always derives it from the formula. The functions available in a formula are listed in § Reference › Functions and Constants Available In Expressions.

Notes

Variable Modifiers

Use the functions in this group on variables that already exist in the model. Add the variables first, then apply the modifier. Use an exclusive range to remove part of the domain of a variable. Use a selection variable to switch a group of variables on and off with one binary flag. Use an exchangeable group to declare identical items whose values you can exchange without a change to the result. Use a fix group or a float group to exploit structure in your problem by directing OptQuest to fix or float a group of variables during the search.

Add Exclusive Range to Variable

Language Function Signature
Java boolean OptQuestModel.AddVariableExclusiveRange(String name, double min, double max) throws COptQuestException
C# bool OptQuestModel.AddVariableExclusiveRange(string name, double min, double max)
C++ bool OptQuestModel::AddVariableExclusiveRange(const char* name, double min, double max)
C int OQAddVariableExclusiveRange(HOptQuestModel model, const char* name, double min, double max)
Python bool OptQuestModel.add_variable_exclusive_range(str name, float min_val, float max_val)
Description

Excludes the open interval (min, max) from the domain of the variable name. The values min and max themselves stay feasible; only the values strictly between them are excluded. The variable must already exist. Call the function again to exclude another interval from the same variable.

Example
model.AddContinuousVariable("speed", 0, 100);
// Never run between 40 and 60: those speeds resonate with the structure
model.AddVariableExclusiveRange("speed", 40, 60);

Add Selection Variable

Language Function Signature
Java boolean OptQuestModel.AddSelectionVariable(String name, String[] selVars) throws COptQuestException
C# bool OptQuestModel.AddSelectionVariable(string name, string[] selVars)
C++ bool OptQuestModel::AddSelectionVariable(const char* name, const char** selVars, int n)
C int OQAddSelectionVariable(HOptQuestModel model, const char* name, const char** selVars, int n)
Python bool OptQuestModel.add_selection_variable(str name, list[str] selVars)
Description

Adds a binary input variable named name that gates a group of other variables. When the flag is 1, the variables in selVars take part in the optimization as usual. When the flag is 0, the engine sets each of them to its lower bound for that solution. Every variable in selVars must already exist.

Example
model.AddContinuousVariable("pump_size", 10, 50);
model.AddIntegerVariable("pump_count", 1, 4);
// "use_pump" is a new binary variable. When it is 0, pump_size is 10 and pump_count is 1.
model.AddSelectionVariable("use_pump", new String[]{"pump_size", "pump_count"});
Notes

Add Exchangeable Group

Language Function Signature
Java boolean OptQuestModel.AddExchangeableGroup(String name, String[] variables) throws COptQuestException
boolean OptQuestModel.AddExchangeableGroup(String name, String[][] variables) throws COptQuestException
C# bool OptQuestModel.AddExchangeableGroup(string name, string[] variables)
bool OptQuestModel.AddExchangeableGroup(string name, string[][] group)
C++ bool OptQuestModel::AddExchangeableGroup(const char* name, const char** variables, int n)
bool OptQuestModel::AddExchangeableGroup(const char* name, const char*** group, int ng, int nv)
C int OQAddExchangeableGroupFlat(HOptQuestModel model, const char* name, const char** variables, int n)
int OQAddExchangeableGroup(HOptQuestModel model, const char* name, const char*** group, int ng, int nv)
Python bool OptQuestModel.add_exchangeable_group(str name, list[str] | list[list[str]] group)
Description

Declares a group named name of identical items whose values you can exchange without a change to the result. In each trial solution that the optimizer generates, it puts the items in ascending order of their values, in the order that you list them. Thus the optimizer does not evaluate two solutions that differ only by an exchange of items. This call adds no variable to the model.

There are two forms. The flat form takes a list of variable names, one variable for each item. In each trial solution that the optimizer generates, the first variable in the list has the smallest value. The grouped form takes a list of rows. Each row holds the variables of one item, and every row has the same number of variables in the same order. The optimizer orders the rows by the value of their first variable, then by the second variable when the first values are equal, and so on. In Python one function covers both forms: a flat sequence of strings selects the flat form, and a sequence of sequences selects the grouped form. In C they are separate entry points, OQAddExchangeableGroupFlat and OQAddExchangeableGroup.

A common use is placing several identical items. For example, three identical machines in a factory, each with a location to optimize:

model.AddContinuousVariable("machine1_x", min_x, max_x);
model.AddContinuousVariable("machine1_y", min_y, max_y);
model.AddContinuousVariable("machine2_x", min_x, max_x);
model.AddContinuousVariable("machine2_y", min_y, max_y);
model.AddContinuousVariable("machine3_x", min_x, max_x);
model.AddContinuousVariable("machine3_y", min_y, max_y);
model.AddExchangeableGroup("machines", new String[][]{{"machine1_x","machine1_y"},
                                                      {"machine2_x","machine2_y"},
                                                      {"machine3_x","machine3_y"},
                                                     });

With the group, the optimizer has fewer solutions to search. Three integer variables from 0 to 4 have 125 combinations of values, and 35 of them are different when the order does not matter. Without a group, the optimizer will evaluate all 125 combinations and then stop with the termination reason OptimalFound (5). With an exchangeable group defined, it will evaluate only combinations and then stop with the same reason.

Use an exchangeable group only for items that have the same type, the same bounds and the same role in your evaluation. If the items differ but they are added to an exchangable group, for example machines with different capacities, two solutions with the two items exchanged are different solutions, but the optimizer will evaluate only one of them.

Notes

Add Fix Group

Language Function Signature
Java boolean OptQuestModel.AddFixGroup(String name, String[] variables) throws COptQuestException
C# bool OptQuestModel.AddFixGroup(string name, string[] variables)
C++ bool OptQuestModel::AddFixGroup(const char* name, const char** variables, int n)
C int OQAddFixGroup(HOptQuestModel model, const char* name, const char** variables, int n)
Python bool OptQuestModel.add_fix_group(str name, list[str] variables)
Description

Declares a fix group named name: AddFixGroup can help OptQuest exploit structure in a problem by directing OptQuest to fix a group of variables during the search. In some generated solutions later in the search, 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 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.

Example
// Search the rest of the model with the three pump settings held at
// their values in the best solution found so far.
model.AddFixGroup("pumps", new String[]{"pump1", "pump2", "pump3"});
Notes

Add Float Group

Language Function Signature
Java boolean OptQuestModel.AddFloatGroup(String name, String[] variables) throws COptQuestException
C# bool OptQuestModel.AddFloatGroup(string name, string[] variables)
C++ bool OptQuestModel::AddFloatGroup(const char* name, const char** variables, int n)
C int OQAddFloatGroup(HOptQuestModel model, const char* name, const char** variables, int n)
Python bool OptQuestModel.add_float_group(str name, list[str] variables)
Description

Declares a float group named name: AddFloatGroup can help OptQuest exploit structure in a problem by directing OptQuest to float a group of variables during the search. A float group is the inverse of a fix group. In some generated solutions later in the search, 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.

Example
// Search the two setpoints with every other variable held at its value
// in the best solution found so far.
model.AddFloatGroup("setpoints", new String[]{"t1", "t2"});
Notes

Objectives

Add Objective

Language Function Signature
Java boolean OptQuestModel.AddMinimizeObjective(String name, String expression)
boolean OptQuestModel.AddMaximizeObjective(String name, String expression)
boolean OptQuestModel.AddObjective(String name, String dir, String expression)
C# bool OptQuestModel.AddMinimizeObjective(string name, string expression)
bool OptQuestModel.AddMaximizeObjective(string name, string expression)
bool OptQuestModel.AddObjective(string name, string direction, string expression)
C++ bool OptQuestModel::AddMinimizeObjective(const char* name, const char* expression)
bool OptQuestModel::AddMaximizeObjective(const char* name, const char* expression)
bool OptQuestModel::AddObjective(const char* name, const char* direction, const char* expression)
C int OQAddMinimizeObjective(HOptQuestModel model, const char* name, const char* expression)
int OQAddMaximizeObjective(HOptQuestModel model, const char* name, const char* expression)
int OQAddObjective(HOptQuestModel model, const char* name, const char* direction, const char* expression)
Python bool OptQuestModel.add_minimize_objective(str name, str expression)
bool OptQuestModel.add_maximize_objective(str name, str expression)
bool OptQuestModel.add_objective(str name, str direction, str expression)
Description

Adds an objective named name that minimizes or maximizes expression. AddMinimizeObjective and AddMaximizeObjective are shorthand for AddObjective with the direction MIN or MAX. direction accepts only those two tokens, in any case; the call fails for any other token. expression is a formula over input and output variables. The functions it can use are listed in § Reference › Functions and Constants Available In Expressions. When the model has more than one objective, OptQuest runs a multi-objective optimization and produces a Pareto frontier of trade-off solutions.

Set Multi-Objective Goal

Language Function Signature
Java boolean OptQuestModel.SetObjectiveGoal(String name, double min, double max)
C# bool OptQuestModel.SetObjectiveGoal(string name, double min, double max)
C++ bool OptQuestModel::SetObjectiveGoal(const char* name, double min, double max)
C int OQSetObjectiveGoal(HOptQuestModel model, const char* name, double min, double max)
Python bool OptQuestModel.set_objective_goal(str name, float min_val, float max_val)
Description

Sets a target range for the objective name in a multi-objective optimization. The range is from min to max inclusive. The objective must already exist. OptQuest uses the goal to decide where to search. After its first cycle of search phases, OptQuest uses the rest of the run to fill gaps between neighboring solutions on the Pareto frontier, while the frontier has at least two solutions. It fills first the largest gap next to a frontier solution whose objective values are inside the most goal ranges. When no frontier solution is inside every range, OptQuest uses the solutions that are inside the most ranges.

OptQuest does not use the goal to decide feasibility, and it does not remove the solutions outside the range from the Pareto frontier. The frontier that GetBestSolutions returns can include solutions outside the range. The setting is ignored in a single-objective model.

Set Objective Statistic Parameters

Language Function Signature
Java boolean OptQuestModel.SetObjectiveStatistic(String name, int statistic) throws COptQuestException
boolean OptQuestModel.SetObjectiveStatistic(String name, int statistic, double statisticValue) throws COptQuestException
C# bool OptQuestModel.SetObjectiveStatistic(string name, int statistic)
bool OptQuestModel.SetObjectiveStatistic(string name, int statistic, double statisticValue)
C++ bool OptQuestModel::SetObjectiveStatistic(const char* name, int statistic, double statisticValue = 0)
C int OQSetObjectiveStatistic(HOptQuestModel model, const char* name, int statistic, double statisticValue)
Python bool OptQuestModel.set_objective_statistic(str name, int statistic, float statistic_value=None)
Description

Sets how the engine aggregates the objective name across the replications of a trial. The setting is ignored when the model runs without replications. statistic is one of the values in the table below. statisticValue is used only with Percentile, where it selects the percentile as a fraction in [0, 1] (0.95 for the 95th percentile); a value outside that range is refused. The other statistics ignore it.

Statistic Java, C# C++ C, Python
None OptQuestModel.Statistic.None OptQuestModel::Statistic::None OQStatisticNone
Mean OptQuestModel.Statistic.Mean OptQuestModel::Statistic::Mean OQStatisticMean
Median OptQuestModel.Statistic.Median OptQuestModel::Statistic::Median OQStatisticMedian
Percentile OptQuestModel.Statistic.Percentile OptQuestModel::Statistic::Percentile OQStatisticPercentile
Standard Deviation OptQuestModel.Statistic.StdDev OptQuestModel::Statistic::StdDev OQStatisticStdDev
Variance OptQuestModel.Statistic.Variance OptQuestModel::Statistic::Variance OQStatisticVariance
Coefficient of Variation OptQuestModel.Statistic.CoeffOfVar OptQuestModel::Statistic::CoeffOfVar OQStatisticCoeffOfVar
Min OptQuestModel.Statistic.Min OptQuestModel::Statistic::Min OQStatisticMin
Max OptQuestModel.Statistic.Max OptQuestModel::Statistic::Max OQStatisticMax
Sum OptQuestModel.Statistic.Sum OptQuestModel::Statistic::Sum OQStatisticSum
Notes

Set Objective Confidence Parameters

Language Function Signature
Java boolean OptQuestModel.SetObjectiveConfidence(String name, int ctype, int clevel, double epct)
C# bool OptQuestModel.SetObjectiveConfidence(string name, int ctype, int clevel, double epct)
C++ bool OptQuestModel::SetObjectiveConfidence(const char* name, int ctype, int clevel, double epct)
C int OQSetObjectiveConfidence(HOptQuestModel model, const char* name, int ctype, int clevel, double epct)
Python bool OptQuestModel.set_objective_confidence(str name, int ctype, int clevel, float epct)
Description

Sets the early-stopping confidence parameters for the objective name in a variable-replication optimization. The setting is ignored when the replication count is fixed or the model runs without replications. The parameters are:

With these set, OptQuest stops replicating a trial solution when the half-width of the confidence interval at the level clevel is at most epct times the absolute value of the mean of the replications.

Confidence testing works only with the mean. If the objective, or an output that it uses, has a statistic other than Mean, the model fails when it initializes, with the message “You must use the Mean statistic when using replication confidence.” With no statistic set, the engine uses the mean.

ctype selects one of two rules. Type 1 continues replicating until the confidence level is reached or the maximum number of replications is run. Type 2 also stops early when OptQuest determines that the current solution cannot fall within the confidence interval of the best solution. Type 2 applies to single-objective models.

Confidence Type Java, C# C++ C, Python
Type 1 OptQuestModel.Confidence.Type1 OptQuestModel::Confidence::Type1 OQConfidenceType1
Type 2 OptQuestModel.Confidence.Type2 OptQuestModel::Confidence::Type2 OQConfidenceType2

clevel selects the confidence level of the interval:

Confidence Level Java, C# C++ C, Python
80% OptQuestModel.Confidence.Level80 OptQuestModel::Confidence::Level80 OQConfidenceLevel80
90% OptQuestModel.Confidence.Level90 OptQuestModel::Confidence::Level90 OQConfidenceLevel90
95% OptQuestModel.Confidence.Level95 OptQuestModel::Confidence::Level95 OQConfidenceLevel95
98% OptQuestModel.Confidence.Level98 OptQuestModel::Confidence::Level98 OQConfidenceLevel98
99% OptQuestModel.Confidence.Level99 OptQuestModel::Confidence::Level99 OQConfidenceLevel99
99.9% OptQuestModel.Confidence.Level999 OptQuestModel::Confidence::Level999 OQConfidenceLevel999
Notes

Constraints

Add Constraint

Language Function Signature
Java boolean OptQuestModel.AddConstraint(String name, String expression) throws COptQuestException
C# bool OptQuestModel.AddConstraint(string name, string expression)
C++ bool OptQuestModel::AddConstraint(const char* name, const char* expression)
C int OQAddConstraint(HOptQuestModel model, const char* name, const char* expression)
Python bool OptQuestModel.add_constraint(str name, str expression)
Description

Adds a constraint named name with the formula expression. The formula can reference input variables, output variables, expression variables and objectives, and it can be linear or non-linear. The functions it can use are listed in § Reference › Functions and Constants Available In Expressions.

Notes

Adaptive Sampling Configuration

Add Sampling Metric

Language Function Signature
Java boolean OptQuestModel.AddSampleMetric(String name, String responseExpression, String errorExpression)
C# bool OptQuestModel.AddSampleMetric(string name, string response, string error)
C++ bool OptQuestModel::AddSampleMetric(const char* name, const char* response, const char* error)
C int OQAddSampleMetric(HOptQuestModel model, const char* name, const char* response, const char* error)
Python bool OptQuestModel.add_sample_metric(str name, str response, str error)
Description

Adds a sampling metric named name for Adaptive Sampling. responseExpression is a formula over input and output variables that gives the response the sampler tracks. errorExpression is a formula that gives the uncertainty (error) of that response; pass "0" when the response is exact. The functions the formulas can use are listed in § Reference › Functions and Constants Available In Expressions. The engine creates two values, <name>@response and <name>@error, that you can read from a solution and reference in expressions.

model.AddSampleMetric("metric", response, error);

This creates metric@response and metric@error.

Notes

Set Sampling Method

Language Function Signature
Java boolean OptQuestModel.SetSampleMethod(int method)
C# bool OptQuestModel.SetSampleMethod(int method)
C++ bool OptQuestModel::SetSampleMethod(int method)
C int OQSetSampleMethod(HOptQuestModel model, int method)
Python bool OptQuestModel.set_sample_method(int method)
Description

Sets the sampling method for Adaptive Sampling. method is a bitwise OR of the flags in the table below. The flags determine how the sampling engine builds its internal model and selects the next sample points. See § Adaptive Sampling for the strategies.

Method Java, C# C++ C, Python
Stochastic OptQuestModel.SampleMethod.Stochastic OptQuestModel::SampleMethod::Stochastic OQSampleMethodStochastic
Dynamic OptQuestModel.SampleMethod.Dynamic OptQuestModel::SampleMethod::Dynamic OQSampleMethodDynamic
Async OptQuestModel.SampleMethod.Async OptQuestModel::SampleMethod::Async OQSampleMethodAsync
Uniform OptQuestModel.SampleMethod.Uniform OptQuestModel::SampleMethod::Uniform OQSampleMethodUniform
Variance OptQuestModel.SampleMethod.Variance OptQuestModel::SampleMethod::Variance OQSampleMethodVariance
Zero OptQuestModel.SampleMethod.Zero OptQuestModel::SampleMethod::Zero OQSampleMethodZero
Gradient OptQuestModel.SampleMethod.Gradient OptQuestModel::SampleMethod::Gradient OQSampleMethodGradient
Min OptQuestModel.SampleMethod.Min OptQuestModel::SampleMethod::Min OQSampleMethodMin
Max OptQuestModel.SampleMethod.Max OptQuestModel::SampleMethod::Max OQSampleMethodMax
Response Distribution OptQuestModel.SampleMethod.RDS OptQuestModel::SampleMethod::RDS OQSampleMethodRDS
Stochastic + feedback OptQuestModel.SampleMethod.Stochastic<Method> OptQuestModel::SampleMethod::Stochastic<Method> OQSampleMethodStochastic<Method>

The Stochastic<Method> constants (StochasticVariance, StochasticUniform, StochasticZero, StochasticGradient, StochasticMin, StochasticMax, StochasticRDS) are shorthand for Stochastic | Async | <Method>, the usual combination for a stochastic simulation. Every language has the same names.

Sampling Method Categories

The flags fall into two groups. The model-building flags (Stochastic, Dynamic, Async) control how the engine builds its internal model. The feedback flags (Uniform, Variance, Zero, Gradient, Min, Max, RDS) control how it selects the next sample point.

Model-Building Methods
Feedback Methods

These flags define the criterion for the next sample point, based on the metric’s estimated value and uncertainty. Several feedback flags can be combined with bitwise OR. The engine then produces one sample per enabled flag per request.

Set Sampling Variogram

Language Function Signature
Java boolean OptQuestModel.SetSampleVariogram(String variogram)
C# bool OptQuestModel.SetSampleVariogram(string variogram)
C++ bool OptQuestModel::SetSampleVariogram(const char* variogram)
C int OQSetSampleVariogram(HOptQuestModel model, const char* variogram)
Python bool OptQuestModel.set_sample_variogram(str variogram)
Description

Sets the variogram that the engine uses to build the internal surrogate model during Adaptive Sampling. By default the engine chooses a variogram with a heuristic. Call this function to select one of the variograms in the table below instead. Most users do not need this function: use the default unless OptTek support advises a different variogram.

Method Java, C# C++ C, Python
Spherical OptQuestModel.SampleVariogram.Spherical OptQuestModel::SampleVariogram::Spherical OQSampleVariogramSpherical
Pow OptQuestModel.SampleVariogram.Pow OptQuestModel::SampleVariogram::Pow OQSampleVariogramPow
Exp OptQuestModel.SampleVariogram.Exp OptQuestModel::SampleVariogram::Exp OQSampleVariogramExp
Gaussian OptQuestModel.SampleVariogram.Gaussian OptQuestModel::SampleVariogram::Gaussian OQSampleVariogramGaussian
Tanh OptQuestModel.SampleVariogram.Tanh OptQuestModel::SampleVariogram::Tanh OQSampleVariogramTanh
Sech OptQuestModel.SampleVariogram.Sech OptQuestModel::SampleVariogram::Sech OQSampleVariogramSech
Linear OptQuestModel.SampleVariogram.Linear OptQuestModel::SampleVariogram::Linear OQSampleVariogramLinear
Quadratic OptQuestModel.SampleVariogram.Quadratic OptQuestModel::SampleVariogram::Quadratic OQSampleVariogramQuadratic
Partition OptQuestModel.SampleVariogram.Partition OptQuestModel::SampleVariogram::Partition OQSampleVariogramPartition
Matern OptQuestModel.SampleVariogram.Matern OptQuestModel::SampleVariogram::Matern OQSampleVariogramMatern
Notes

Set Response Distribution

These functions set the wanted probability distribution for a Response Distribution Sampling (RDS) metric. Set exactly one distribution per metric with the matching SetSampleRDS<DistName> function. The setting takes effect only when RDS is part of the sampling method (see § Set Sampling Method); otherwise the engine ignores it.

For a continuous distribution, the engine divides the support into nBins bins of equal probability under that distribution and biases the sampling toward the bins that are under-represented among the evaluated responses. For the discrete distribution, you give the bin edges directly. See § Reference › Probability Distributions for the algorithm.

Function Signatures

name identifies the sample metric declared with AddSampleMetric. nBins is the number of equal-probability bins for a continuous distribution. The remaining parameters depend on the distribution:

Distribution Function Name Distribution-Specific Parameters
Uniform SetSampleRDSUniform double a, double b: lower and upper bounds of the uniform distribution
Normal SetSampleRDSNormal double mu, double sigma: mean and standard deviation
Log Normal SetSampleRDSLogNormal double s, double scale: shape and scale parameters
Beta SetSampleRDSBeta double alpha, double beta: shape parameters
Poisson SetSampleRDSPoisson double lambda: rate parameter
Exponential SetSampleRDSExponential double scale: scale parameter (inverse rate)
Cauchy SetSampleRDSCauchy double location, double scale: location (median) and scale parameters
Gamma SetSampleRDSGamma double a, double scale: shape and scale parameters
Chi-Square SetSampleRDSChiSquare double nu: degrees of freedom
Pareto SetSampleRDSPareto double gamma, double loc, double scale: shape, location, and scale parameters
Student’s t SetSampleRDST double nu: degrees of freedom
Weibull SetSampleRDSWeibull double c, double scale: shape and scale parameters
Discrete SetSampleRDSDiscrete double[] binEdges: n - 1 edges defining n bins; the outermost bins extend to -infinity and +infinity

The Java signature of each continuous form is boolean OptQuestModel.SetSampleRDS<DistName>(String name, int nBins, <distribution parameters>). The discrete form has no nBins and takes a double[] binEdges instead. The other languages follow their usual conventions. In C each function is int OQSetSampleRDS<DistName>(HOptQuestModel model, const char* name, int nBins, ...), for example OQSetSampleRDSNormal(model, name, nBins, mu, sigma), and the discrete form is int OQSetSampleRDSDiscrete(HOptQuestModel model, const char* name, const double* binEdges, int nBinEdges). In Python the names are lower case with underscores, for example set_sample_rds_normal(name, nBins, mu, sigma).

Every one of these functions is a wrapper over one generic entry point:

Language Function Signature
Java boolean OptQuestModel.SetSampleRDSParams(String name, String distribution, double[] params)
C# bool OptQuestModel.SetSampleRDSParams(string name, string distribution, double[] rdsParams)
C++ bool OptQuestModel::SetSampleRDSParams(const char* name, const char* distribution, const double* rdsParams, int nParams)
C int OQSetSampleRDSParams(HOptQuestModel model, const char* name, const char* distribution, const double* rdsParams, int nParams)
Python bool OptQuestModel.set_sample_rds_params(str name, str distribution, Sequence[float] rdsParams)

distribution is one of UNIFORM, NORMAL, LOGNORMAL, BETA, POISSON, EXPONENTIAL, CAUCHY, GAMMA, CHISQUARE, PARETO, T, WEIBULL or DISCRETE (case-insensitive). For every distribution except DISCRETE, params[0] is the bin count and the remaining entries are the distribution parameters in the order of the table above. For DISCRETE the whole array is the bin edges. Prefer the named functions; they place the arguments for you.

Discrete Distribution Example

For a wanted distribution on [0, 1] split into 10 bins of equal width, pass binEdges = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]. The bins are (-infinity, 0.1), [0.1, 0.2), …, [0.8, 0.9), [0.9, +infinity). During sampling the engine biases the points toward the bin with the lowest count, so a narrower bin gets a higher sampling density.

Notes

Optimization Configuration

Set Replications

Language Function Signature
Java boolean OptQuestModel.SetReplications(int reps)
boolean OptQuestModel.SetReplications(int min, int max)
C# bool OptQuestModel.SetReplications(int reps)
bool OptQuestModel.SetReplications(int min, int max)
C++ bool OptQuestModel::SetReplications(int reps)
bool OptQuestModel::SetReplications(int min, int max)
C int OQSetReplications(HOptQuestModel model, int min, int max)
Python bool OptQuestModel.set_replications(int min_reps, int max_reps=None)
Description

Sets how many replications OptQuest runs for each trial solution of a stochastic optimization. There are two modes:

min must be at least 1 and max at least min; other values are rejected. A max of 1 runs without replications. A min of 1 with a larger max runs at least two replications per trial, because a confidence interval needs two observations.

Notes

Set Serial Replications

Language Function Signature
Java boolean OptQuestModel.SetSerialReplications()
C# bool OptQuestModel.SetSerialReplications()
C++ bool OptQuestModel::SetSerialReplications()
C int OQSetSerialReplications(HOptQuestModel model)
Python bool OptQuestModel.set_serial_replications()
Description

Turns on serial replication mode, which changes how the engine schedules replications when several solutions are evaluated in parallel. By default the engine completes every replication of one solution before it generates the next. In serial replication mode the engine generates and evaluates the next solution as soon as the first replication result arrives, so the replications of different solutions interleave across the parallel evaluators. Most users do not need this function. It has an effect only on a model with replications whose solutions are evaluated in parallel.

Notes

Set Parallel Hint

Language Function Signature
Java boolean OptQuestModel.SetParallelHint(int npar)
C# bool OptQuestModel.SetParallelHint(int npar)
C++ bool OptQuestModel::SetParallelHint(int npar)
C int OQSetParallelHint(HOptQuestModel model, int npar)
Python bool OptQuestModel.set_parallel_hint(int npar)
Description

Tells the engine that about npar solutions will be out for evaluation at a time in a manual optimization. Some of the internal metaheuristics depend on that number. The search is most efficient when the number of solutions evaluated in parallel matches the hint, but any number of solutions, up to 5000, can be out at once. Most users do not need this function. It has an effect only in a manual loop with several solutions out at once.

Notes

Set Random Seed

Language Function Signature
Java boolean OptQuestModel.SetRandomSeed(int seed)
C# bool OptQuestModel.SetRandomSeed(int seed)
C++ bool OptQuestModel::SetRandomSeed(int seed)
C int OQSetRandomSeed(HOptQuestModel model, int seed)
Python bool OptQuestModel.set_random_seed(int seed)
Description

Sets the random seed the engine uses during an optimization. Use it to find out how much a result depends on the random choices of the search: run the same model with several seeds and compare the best objective values.

Notes

Stop On Successful MILP

Language Function Signature
Java boolean OptQuestModel.StopOnSuccessfulMILP()
C# bool OptQuestModel.StopOnSuccessfulMILP()
C++ bool OptQuestModel::StopOnSuccessfulMILP()
C int OQStopOnSuccessfulMILP(HOptQuestModel model)
Python bool OptQuestModel.stop_on_successful_milp()
Description

Tells the engine to stop an optimization early when its internal linear-programming solver solves the problem exactly, which happens when the objective and the constraints are linear in the inputs. The engine ignores the setting when the objective or a constraint is non-linear.

Suggested Solutions Only

Language Function Signature
Java boolean OptQuestModel.SuggestedSolutionsOnly()
C# bool OptQuestModel.SuggestedSolutionsOnly()
C++ bool OptQuestModel::SuggestedSolutionsOnly()
C int OQSuggestedSolutionsOnly(HOptQuestModel model)
Python bool OptQuestModel.suggested_solutions_only()
Description

Restricts the model to the solutions the caller supplies. OptQuest evaluates the solutions added with AddSuggested, AddEvaluated and AddRequired and generates none of its own.

The engine still changes the input values of each suggested solution so that they satisfy the input-only constraints and the rules of each variable type, and it still drops duplicates. So you can supply a set of points, and CreateSolution returns the distinct feasible solutions that the engine makes from them. Two points that give the same feasible solution (an integer variable given 1.1 and 1.2, for example) give one solution, and the engine drops the duplicate. When the supplied solutions run out, CreateSolution returns an invalid solution and GetTerminationReason reports FactoriesDone, so the caller reads back all the remaining solutions without knowing the count in advance.

Notes

Set Stop Cycles

Language Function Signature
Java boolean OptQuestModel.SetStopCycles(int cycles)
C# bool OptQuestModel.SetStopCycles(int cycles)
C++ bool OptQuestModel::SetStopCycles(int cycles)
C int OQSetStopCycles(HOptQuestModel model, int cycles)
Python bool OptQuestModel.set_stop_cycles(int cycles)
Description

Stops the optimization after cycles search cycles. The run then ends with the termination reason Auto Stop (4). A search cycle is one pass of the engine’s search methods, and the number of iterations in a cycle depends on the problem. An improvement of the best solution does not reset the count of cycles.

Set Stop Improvement

Language Function Signature
Java boolean OptQuestModel.SetStopImprovement(double improvement, int iterations)
C# bool OptQuestModel.SetStopImprovement(double improvement, int iterations)
C++ bool OptQuestModel::SetStopImprovement(double improvement, int iterations)
C int OQSetStopImprovement(HOptQuestModel model, double improvement, int iterations)
Python bool OptQuestModel.set_stop_improvement(float improvement, int iterations)
Description

Stops the optimization when iterations consecutive iterations pass without a cumulative improvement of more than the fraction improvement. The improvement is relative, measured against the best and worst feasible objective values found so far. Use a value of improvement from 0.0 to 0.2. For example, SetStopImprovement(0.01, 100) stops the run when, over the last 100 iterations, the best objective changed by 1 percent or less of the difference between the best and the worst feasible objective values. The run then ends with the termination reason Auto Stop (4). The rule applies only to a model with one objective. The engine ignores it when the model has two or more objectives.

Set Stop Time

Language Function Signature
Java boolean OptQuestModel.SetStopTime(int seconds)
C# bool OptQuestModel.SetStopTime(int seconds)
C++ bool OptQuestModel::SetStopTime(int seconds)
C int OQSetStopTime(HOptQuestModel model, int seconds)
Python bool OptQuestModel.set_stop_time(int seconds)
Description

Stops the optimization after seconds seconds. The current iteration completes first, so a long evaluation can make the run last longer than seconds.

Running Managed Optimization and Sampling

After the model is defined, the functions in this group run the optimization or Adaptive Sampling loop. The first call to any of them makes the model immutable (see § Concepts › Model Immutability).

In a managed run the engine owns the loop: it creates each solution, calls your evaluator, post-processes the result and reports status. The run can be serial, concurrent or asynchronous. Optimize() and Sample() take two optional callbacks: an evaluator, which is required when the model has output variables that a simulation must compute, and a monitor, which sees each completed solution, for example to update a user interface.

Sample() is the same loop as Optimize(), run by the Adaptive Sampling engine. The engine uses the metrics registered with AddSampleMetric and the method set with SetSampleMethod. Everything below about Optimize() applies to Sample() too.

Managed Optimization

Language Function Signature
Java boolean OptQuestModel.Optimize(int nsol) throws COptQuestException
boolean OptQuestModel.Optimize(int nsol, IOptQuestEvaluator eval) throws COptQuestException
boolean OptQuestModel.Optimize(int nsol, IOptQuestEvaluator eval, IOptQuestMonitor monitor) throws COptQuestException
C# bool OptQuestModel.Optimize(int nsol)
bool OptQuestModel.Optimize(int nsol, IOptQuestEvaluator? eval)
bool OptQuestModel.Optimize(int nsol, IOptQuestEvaluator? eval, IOptQuestMonitor? monitor)
C++ bool OptQuestModel::Optimize(int nsol)
bool OptQuestModel::Optimize(int nsol, const IOptQuestEvaluator& eval)
bool OptQuestModel::Optimize(int nsol, const IOptQuestEvaluator& eval, const IOptQuestMonitor& monitor)
bool OptQuestModel::Optimize(int nsol, const IOptQuestEvaluator* eval, const IOptQuestMonitor* monitor)
C int OQOptimize(HOptQuestModel model, int nsol, OQEvaluator eval, OQMonitor monitor, void* context)
Python bool OptQuestModel.optimize(int num_solutions, func evaluator=None, func monitor=None, int npar=None)
Description

Runs a managed optimization that evaluates nsol solutions generated by the engine. There are three overloads:

In C++, you can pass nullptr for either callback to the overload that takes pointers. In C the callbacks are function pointers and may be NULL, and the context pointer is passed through to them. In Python the callbacks are functions that take one OptQuestSolution and may be None. Python runs the concurrent form when npar is given. A Python evaluator returns True (or any other true value, such as 1) to submit a solution, and a Python monitor returns True (or any other true value) to continue the run. A function without a return statement returns None. When an evaluator returns None, the engine rejects the trial solution, so a run with such an evaluator rejects every trial solution. When a monitor returns None, the engine stops the run after the first solution. No error text appears in either case. If a Python evaluator or monitor raises an exception, the binding stops the run, and optimize() or sample() raises the same exception after the run stops.

Returns

Concurrent Managed Optimization

Language Function Signature
Java boolean OptQuestModel.Optimize(int npar, int nsol) throws COptQuestException
boolean OptQuestModel.Optimize(int npar, int nsol, IOptQuestEvaluator eval) throws COptQuestException
boolean OptQuestModel.Optimize(int npar, int nsol, IOptQuestEvaluator eval, IOptQuestMonitor monitor) throws COptQuestException
C# bool OptQuestModel.Optimize(int npar, int nsol)
bool OptQuestModel.Optimize(int npar, int nsol, IOptQuestEvaluator? eval)
bool OptQuestModel.Optimize(int npar, int nsol, IOptQuestEvaluator? eval, IOptQuestMonitor? monitor)
C++ bool OptQuestModel::Optimize(int npar, int nsol)
bool OptQuestModel::Optimize(int npar, int nsol, const IOptQuestEvaluator& eval)
bool OptQuestModel::Optimize(int npar, int nsol, const IOptQuestEvaluator& eval, const IOptQuestMonitor& monitor)
bool OptQuestModel::Optimize(int npar, int nsol, const IOptQuestEvaluator* eval, const IOptQuestMonitor* monitor)
C int OQParallelOptimize(HOptQuestModel model, int npar, int nsol, OQEvaluator eval, OQMonitor monitor, void* context)
Python bool OptQuestModel.optimize(int num_solutions, func evaluator=None, func monitor=None, int npar=None)
Description

Runs a managed optimization that evaluates nsol solutions on npar threads. It behaves like Managed Optimization, but npar solutions are out for evaluation at once. The engine handles the model and the solutions in a thread-safe way. Your IOptQuestEvaluator and IOptQuestMonitor callbacks run on several threads at once, so they must synchronize any shared state of their own. The call blocks until every solution is evaluated.

In C++, you can pass nullptr for either callback to the overload that takes pointers. In C the callbacks are function pointers and may be NULL, and the context pointer is passed through to them. In Python the callbacks are functions that take one OptQuestSolution and may be None.

Returns

Asynchronous Optimization

Language Function Signature
Java boolean OptQuestModel.Optimize(OptQuestModelChannel ipc, int nsol) throws COptQuestException
boolean OptQuestModel.Optimize(OptQuestModelChannel ipc, int nsol, IOptQuestEvaluator eval) throws COptQuestException
boolean OptQuestModel.Optimize(OptQuestModelChannel ipc, int nsol, IOptQuestEvaluator eval, IOptQuestMonitor monitor) throws COptQuestException
C# bool OptQuestModel.Optimize(OptQuestModelChannel ipc, int nsol)
bool OptQuestModel.Optimize(OptQuestModelChannel ipc, int nsol, IOptQuestEvaluator? eval)
bool OptQuestModel.Optimize(OptQuestModelChannel ipc, int nsol, IOptQuestEvaluator? eval, IOptQuestMonitor? monitor)
C++ bool OptQuestModel::Optimize(OptQuestModelChannel& ipc, int nsol)
bool OptQuestModel::Optimize(OptQuestModelChannel& ipc, int nsol, const IOptQuestEvaluator& eval)
bool OptQuestModel::Optimize(OptQuestModelChannel& ipc, int nsol, const IOptQuestEvaluator& eval, const IOptQuestMonitor& monitor)
bool OptQuestModel::Optimize(OptQuestModelChannel& ipc, int nsol, const IOptQuestEvaluator* eval, const IOptQuestMonitor* monitor)
C int OQAsyncOptimize(HOptQuestModel model, HOptQuestModelChannel ipc, int nsol, OQEvaluator eval, OQMonitor monitor, void* context)
Description

Runs a managed optimization that evaluates nsol solutions on the threads of the channel ipc, and lets another thread interrupt it. The call itself blocks until the run completes or is interrupted, so start it on a background thread. The main thread calls OptQuestModelChannel.Interrupt() to request early termination: the engine then generates no new solutions, and the evaluations in progress complete. The overloads are the same as those of Managed Optimization.

Returns
Example
// Create a channel for 5 concurrent solution evaluations
OptQuestModelChannel oqChannel = oqModel.CreateAsyncChannel(5);

// Start asynchronous optimization in a background thread
Thread background = new Thread(() -> {
    try {
        oqModel.Optimize(oqChannel, nsol);
    } catch (COptQuestException e) {
        e.printStackTrace();
    }
});
background.start();

// Interrupt optimization on user event
oqChannel.Interrupt();

// Wait for graceful shutdown
background.join();

Managed Adaptive Sampling

Language Function Signature
Java boolean OptQuestModel.Sample(int nsol) throws COptQuestException
boolean OptQuestModel.Sample(int nsol, IOptQuestEvaluator eval) throws COptQuestException
boolean OptQuestModel.Sample(int nsol, IOptQuestEvaluator eval, IOptQuestMonitor monitor) throws COptQuestException
C# bool OptQuestModel.Sample(int nsol)
bool OptQuestModel.Sample(int nsol, IOptQuestEvaluator? eval)
bool OptQuestModel.Sample(int nsol, IOptQuestEvaluator? eval, IOptQuestMonitor? monitor)
C++ bool OptQuestModel::Sample(int nsol)
bool OptQuestModel::Sample(int nsol, const IOptQuestEvaluator& eval)
bool OptQuestModel::Sample(int nsol, const IOptQuestEvaluator& eval, const IOptQuestMonitor& monitor)
bool OptQuestModel::Sample(int nsol, const IOptQuestEvaluator* eval, const IOptQuestMonitor* monitor)
C int OQSample(HOptQuestModel model, int nsol, OQEvaluator eval, OQMonitor monitor, void* context)
Python bool OptQuestModel.sample(int num_solutions, func evaluator=None, func monitor=None, int npar=None)
Description

Runs managed Adaptive Sampling that evaluates nsol solutions generated by the sampling engine. The three overloads are the same as those of Managed Optimization: no callback when the metrics depend only on input variables, an evaluator when output variables must be computed, and an optional monitor. The callback conventions for C++, C and Python are the same as for Optimize.

Returns

Concurrent Managed Adaptive Sampling

Language Function Signature
Java boolean OptQuestModel.Sample(int npar, int nsol) throws COptQuestException
boolean OptQuestModel.Sample(int npar, int nsol, IOptQuestEvaluator eval) throws COptQuestException
boolean OptQuestModel.Sample(int npar, int nsol, IOptQuestEvaluator eval, IOptQuestMonitor monitor) throws COptQuestException
C# bool OptQuestModel.Sample(int npar, int nsol)
bool OptQuestModel.Sample(int npar, int nsol, IOptQuestEvaluator? eval)
bool OptQuestModel.Sample(int npar, int nsol, IOptQuestEvaluator? eval, IOptQuestMonitor? monitor)
C++ bool OptQuestModel::Sample(int npar, int nsol)
bool OptQuestModel::Sample(int npar, int nsol, const IOptQuestEvaluator& eval)
bool OptQuestModel::Sample(int npar, int nsol, const IOptQuestEvaluator& eval, const IOptQuestMonitor& monitor)
bool OptQuestModel::Sample(int npar, int nsol, const IOptQuestEvaluator* eval, const IOptQuestMonitor* monitor)
C int OQParallelSample(HOptQuestModel model, int npar, int nsol, OQEvaluator eval, OQMonitor monitor, void* context)
Python bool OptQuestModel.sample(int num_solutions, func evaluator=None, func monitor=None, int npar=None)
Description

Runs managed Adaptive Sampling that evaluates nsol solutions on npar threads. It behaves like Concurrent Managed Optimization, including the synchronization requirement on the callbacks, and blocks until every solution is evaluated.

Returns

Asynchronous Managed Adaptive Sampling

Language Function Signature
Java boolean OptQuestModel.Sample(OptQuestModelChannel ipc, int nsol) throws COptQuestException
boolean OptQuestModel.Sample(OptQuestModelChannel ipc, int nsol, IOptQuestEvaluator eval) throws COptQuestException
boolean OptQuestModel.Sample(OptQuestModelChannel ipc, int nsol, IOptQuestEvaluator eval, IOptQuestMonitor monitor) throws COptQuestException
C# bool OptQuestModel.Sample(OptQuestModelChannel ipc, int nsol)
bool OptQuestModel.Sample(OptQuestModelChannel ipc, int nsol, IOptQuestEvaluator? eval)
bool OptQuestModel.Sample(OptQuestModelChannel ipc, int nsol, IOptQuestEvaluator? eval, IOptQuestMonitor? monitor)
C++ bool OptQuestModel::Sample(OptQuestModelChannel& ipc, int nsol)
bool OptQuestModel::Sample(OptQuestModelChannel& ipc, int nsol, const IOptQuestEvaluator& eval)
bool OptQuestModel::Sample(OptQuestModelChannel& ipc, int nsol, const IOptQuestEvaluator& eval, const IOptQuestMonitor& monitor)
bool OptQuestModel::Sample(OptQuestModelChannel& ipc, int nsol, const IOptQuestEvaluator* eval, const IOptQuestMonitor* monitor)
C int OQAsyncSample(HOptQuestModel model, HOptQuestModelChannel ipc, int nsol, OQEvaluator eval, OQMonitor monitor, void* context)
Description

Runs managed Adaptive Sampling on the threads of the channel ipc, with the same interrupt mechanism and the same blocking behavior as Asynchronous Optimization.

Returns

Create Asynchronous Model Channel

Language Function Signature
Java OptQuestModelChannel OptQuestModel.CreateAsyncChannel(int npar)
C# OptQuestModelChannel OptQuestModel.CreateAsyncChannel(int npar)
C++ OptQuestModelChannel OptQuestModel::CreateAsyncChannel(int npar)
C HOptQuestModelChannel OQCreateAsyncChannel(HOptQuestModel model, int npar)
void OQDeleteAsyncChannel(HOptQuestModelChannel ipc)
Python (no channel object; see the Notes below)
Description

Creates an OptQuestModelChannel that links the application thread to an asynchronous run with npar parallel evaluations. Pass it to the asynchronous overloads of Optimize and Sample. In C, free the HOptQuestModelChannel handle with OQDeleteAsyncChannel when the run is over.

Returns
Notes

Channel Continue, Interrupt and Get Number Of Parallel

Language Function Signature
Java boolean OptQuestModelChannel.Continue()
void OptQuestModelChannel.Interrupt()
int OptQuestModelChannel.GetNumberOfParallel()
C# bool OptQuestModelChannel.Continue()
void OptQuestModelChannel.Interrupt()
int OptQuestModelChannel.GetNumberOfParallel()
C++ bool OptQuestModelChannel::Continue()
void OptQuestModelChannel::Interrupt()
int OptQuestModelChannel::GetNumberOfParallel()
C int OQIsAsyncContinue(HOptQuestModelChannel ipc)
void OQAsyncInterrupt(HOptQuestModelChannel ipc)
int OQGetNumberOfParallel(HOptQuestModelChannel ipc)
Python (no channel object)
Description

The application uses the three members of the channel to control an asynchronous run.

Continue() is a query. It reports whether the interrupt signal has been raised, so an asynchronous loop can poll it and stop cleanly. It does not resume anything. The C API uses the name OQIsAsyncContinue for the same query, to make the distinction clear. To resume an interrupted optimization, call Continue() on the model, not on the channel.

Interrupt() raises the signal on the channel and calls Interrupt() on the model. GetNumberOfParallel() returns the npar the channel was created with.

Returns

Interrupt Optimization

Language Function Signature
Java void OptQuestModel.Interrupt()
C# void OptQuestModel.Interrupt()
C++ void OptQuestModel::Interrupt()
C void OQInterrupt(HOptQuestModel model)
Python OptQuestModel.interrupt() -> None
Description

Tells the model to stop generating new solutions and sets the termination reason to UserStopped. The next CreateSolution() on any thread returns an invalid solution. A managed Optimize() or Sample() that is running on another thread reaches the same invalid solution inside its loop and returns false. In a multi-threaded manual loop, every thread learns of the interrupt through its next CreateSolution() and can exit cleanly.

Returns
Notes

Continue Optimization

Language Function Signature
Java void OptQuestModel.Continue()
C# void OptQuestModel.Continue()
C++ void OptQuestModel::Continue()
C void OQContinue(HOptQuestModel model)
Python OptQuestModel.continue_opt() -> None
Description

Clears an interrupt and sets the termination reason back to Running. After Interrupt(), the model generates no new solutions until Continue() is called. Every Optimize() and Sample() calls it on entry, so a later run starts without an explicit Continue(). The channel’s Continue() is a different operation with the same name: it queries whether the interrupt signal is set. Resuming is always done through the model.

Returns

Manual Optimization

In manual optimization the client runs the loop. Instead of handing the engine an evaluator, the client repeatedly requests a trial solution with CreateSolution(), evaluates the inputs for this trial solution, writes the results back with SetValue, and calls Submit() or Reject() to give the outcome to the engine. The first call to CreateSolution() makes the model immutable.

Create Solution

Language Function Signature
Java OptQuestSolution OptQuestModel.CreateSolution() throws COptQuestException
C# OptQuestSolution OptQuestModel.CreateSolution()
C++ OptQuestSolution OptQuestModel::CreateSolution()
C HOptQuestSolution OQCreateSolution(HOptQuestModel model)
Python OptQuestSolution OptQuestModel.create_solution()
Description

Asks the engine for the next trial solution. The engine fills in a value for every input variable. The caller then computes the output values, writes them with SetValue and submits the solution. In C, free the HOptQuestSolution handle with OQDeleteSolution when you are done with it.

Returns

Submit Solution

Language Function Signature
Java int OptQuestSolution.Submit() throws COptQuestException
C# int OptQuestSolution.Submit()
C++ int OptQuestSolution::Submit()
C int OQSubmit(HOptQuestSolution sol)
Python bool OptQuestSolution.submit()
Description

Gives an evaluated solution back to the engine. Set every required output value with SetValue first. Managed optimization submits solutions itself; call this only in a manual loop.

Returns
Notes

Reject Solution

Language Function Signature
Java int OptQuestSolution.Reject() throws COptQuestException
C# int OptQuestSolution.Reject()
C++ int OptQuestSolution::Reject()
C int OQReject(HOptQuestSolution sol)
Python bool OptQuestSolution.reject()
Description

Tells the engine that the solution could not be evaluated, for example because the simulation failed or an external condition ruled it out. The engine records the rejection and does not use the solution to guide the search. Managed optimization rejects a solution itself when the evaluator returns false; call this only in a manual loop.

Returns
Notes

Predict Solution

Language Function Signature
Java boolean OptQuestSolution.Predict() throws COptQuestException
C# bool OptQuestSolution.Predict()
C++ bool OptQuestSolution::Predict()
C int OQPredict(HOptQuestSolution sol)
Python bool OptQuestSolution.predict()
Description

Predicts the response of a solution whose input values are set, from the engine’s current metamodel, without running the simulation. Use it to query any point in the domain.

What is predicted depends on the model. In Adaptive Sampling the metamodel is of the registered sample metrics, and the predicted values are written to each metric’s @response and @error. In an optimization there are no sample metrics, so the metamodel is of the objectives: the predicted value of each objective is written to that objective, and the uncertainty is the model’s own measurement spread, which is zero when the model runs without replications and the standard deviation across the replications when it does.

Notes

Evaluate Solution

Language Function Signature
Java boolean OptQuestSolution.Evaluate() throws COptQuestException
C# bool OptQuestSolution.Evaluate()
C++ bool OptQuestSolution::Evaluate()
C int OQEvaluate(HOptQuestSolution sol)
Python bool OptQuestSolution.evaluate()
Description

This is the Evaluate method of a solution. For the callback that runs your simulation in a managed run, see § Evaluate (Solution Evaluator).

Runs the model’s expressions over a solution whose input and output values the client has set. It computes every derived quantity (expression variables, constraint feasibility and objective values) and writes the results into the solution.

The solution is not given to the engine. It does not become an iteration, it is not counted among the model’s evaluated solutions, GetBestSolutions and GetAllSolutions do not return it, and it does not influence the search. Evaluate is a pure computation against the declared model: the same arithmetic the engine performs on a submitted solution, performed on demand and then discarded.

Use it in client-side tools that apply the model’s arithmetic without the search, for example a user interface in which an analyst types a scenario and sees the derived quantities update, a what-if screen that shows the scores of hand-written candidates, or a validation pass over external data.

Notes

Update Solution

Language Function Signature
Java boolean OptQuestSolution.Update()
C# bool OptQuestSolution.Update()
C++ bool OptQuestSolution::Update()
C int OQUpdate(HOptQuestSolution sol)
Python bool OptQuestSolution.update()
Description

Refreshes the solution with the engine’s state after Submit or Reject, so that it holds the values the engine computed, such as constraint feasibility and objective values. Managed optimization updates solutions itself; call this only in a manual loop.

Working With Solutions

An OptQuestSolution is the unit of exchange between the client and the engine. It holds a value for every input, output and expression variable of the model. From it you can also read the iteration number, the replication number, whether the solution is feasible, and whether it met its confidence requirement.

Get Empty Solution

Language Function Signature
Java OptQuestSolution OptQuestModel.GetEmptySolution() throws COptQuestException
C# OptQuestSolution OptQuestModel.GetEmptySolution()
C++ OptQuestSolution OptQuestModel::GetEmptySolution()
C HOptQuestSolution OQGetEmptySolution(HOptQuestModel model)
Python OptQuestSolution OptQuestModel.get_empty_solution()
Description

Creates an empty solution tied to the model, for the caller to fill in with SetValue. Use it with AddSuggested() (input values only), AddEvaluated() (input and output values) or AddRequired() to give the engine a solution you already know. In C, free the HOptQuestSolution handle with OQDeleteSolution when you are done with it.

Returns

Copy Solution

Language Function Signature
Java OptQuestSolution OptQuestModel.CopySolution(OptQuestSolution src) throws COptQuestException
C# OptQuestSolution OptQuestModel.CopySolution(OptQuestSolution src)
C++ OptQuestSolution OptQuestModel::CopySolution(const OptQuestSolution& src)
C HOptQuestSolution OQCopySolution(HOptQuestModel model, HOptQuestSolution src)
Python OptQuestSolution OptQuestModel.copy_solution(OptQuestSolution src_solution)
Description

Creates a new solution that belongs to this model and fills it with the values of src. src may belong to a different model. Use it to copy a solution from one model to another when you continue an optimization with changed parameters, for example after adding or tightening a constraint. Values in src whose names match variables of the destination model are copied. Other values in src are ignored, and destination variables that src does not have stay NaN. Give the copy to the engine with AddSuggested, AddEvaluated or AddRequired. In C, free the HOptQuestSolution handle with OQDeleteSolution after that.

A copy includes the values the caller set on src with SetValue and has not yet sent to the engine, as well as the values the engine holds, so a solution can be copied part-way through an evaluation. The copy has the same values as src for every variable, including every name of each special purpose variable.

Returns
Notes

Add All Solutions

Language Function Signature
Java boolean OptQuestModel.AddAllSolutions(OptQuestModel src) throws COptQuestException
C# bool OptQuestModel.AddAllSolutions(OptQuestModel src)
C++ bool OptQuestModel::AddAllSolutions(const OptQuestModel& src)
C int OQAddAllSolutions(HOptQuestModel model, HOptQuestModel src)
Python bool OptQuestModel.add_all_solutions(OptQuestModel src_model)
Description

Copies every evaluated solution of the source model src into this model. Use it to continue an optimization after you change the model, for example its constraints or objectives. Each copy is added in the same way as with AddEvaluated: the engine does not evaluate it again, and it uses its input and output values as given. The engine computes the objectives and constraints of each copy with the definitions of this model, so a copy that breaks a constraint of this model is infeasible. The engine uses the copies at the start of the next run, before it generates new solutions, and each copy counts as one of the nsol iterations of that run.

Notes

Delete Solution

Language Function Signature
Java Garbage Collected
C# Garbage Collected
C++ Destructed
C void OQDeleteSolution(HOptQuestSolution sol)
Python Garbage Collected
Description

Releases the resources of an OptQuestSolution. Solutions are never constructed directly: the model creates them in CreateSolution(), GetEmptySolution(), CopySolution(), GetBestSolutions() and GetAllSolutions(). Java, C# and Python reclaim them through garbage collection. In C++ the destructor runs when the object goes out of scope. In C, call OQDeleteSolution on the handle.

Returns

Is Valid

Language Function Signature
Java boolean OptQuestSolution.IsValid()
C# bool OptQuestSolution.IsValid()
implicit operator bool(OptQuestSolution test)
C++ bool OptQuestSolution::IsValid() const
OptQuestSolution::operator bool() const
C int OQIsValid(HOptQuestSolution sol)
Python bool OptQuestSolution.is_valid()
Description

Reports whether the solution is valid. CreateSolution() returns an invalid solution when the engine cannot generate a new one, for example because the feasible space is exhausted, the domain is too restrictive, or the run was interrupted. In C# and C++, operator bool also converts the solution to a boolean for this test.

In C the invalid solution is a real, non-NULL handle. Test it with OQIsValid, never with handle == NULL, and release it with OQDeleteSolution like any other. A NULL handle is a separate, harder failure. OQGetLastError returns its description.

Returns
Notes

Get Iteration

Language Function Signature
Java int OptQuestSolution.GetIteration()
C# int OptQuestSolution.GetIteration()
C++ int OptQuestSolution::GetIteration() const
C int OQGetIteration(HOptQuestSolution sol)
Python int OptQuestSolution.get_iteration()
Description

Returns the iteration number the engine assigned to the solution when it created it. All replications of one solution share the iteration number. Use it to track the sequence of solutions in a run.

Returns

Get Replication

Language Function Signature
Java int OptQuestSolution.GetReplication()
C# int OptQuestSolution.GetReplication()
C++ int OptQuestSolution::GetReplication() const
C int OQGetReplication(HOptQuestSolution sol)
Python int OptQuestSolution.get_replication()
Description

Returns the replication number of this evaluation of the solution. Each replication of a solution has its own number, which distinguishes the evaluations of one solution in a stochastic simulation.

Returns

Get Number Of Completed Replications

Language Function Signature
Java int OptQuestSolution.GetNumberOfCompletedReplications()
C# int OptQuestSolution.GetNumberOfCompletedReplications()
C++ int OptQuestSolution::GetNumberOfCompletedReplications() const
C int OQGetNumberOfCompletedReplications(HOptQuestSolution sol)
Python int OptQuestSolution.get_number_of_completed_replications()
Description

Returns the number of replications that have been evaluated for the solution. For a solution from CreateSolution that you have not submitted or rejected, the number is the count of replications of the same iteration that are complete: the replication number minus 1. Without replications, it is 0.

Returns

Is Complete

Language Function Signature
Java boolean OptQuestSolution.IsComplete()
C# bool OptQuestSolution.IsComplete()
C++ bool OptQuestSolution::IsComplete() const
C int OQIsComplete(HOptQuestSolution sol)
Python bool OptQuestSolution.is_complete()
Description

Reports whether every required replication of the solution has been evaluated, so that no further evaluation is needed. This matters most in variable-replication mode. For a solution from CreateSolution that you have not submitted or rejected, it reports false.

Returns

Is Feasible

Language Function Signature
Java boolean OptQuestSolution.IsFeasible()
C# bool OptQuestSolution.IsFeasible()
C++ bool OptQuestSolution::IsFeasible() const
C int OQIsFeasible(HOptQuestSolution sol)
Python bool OptQuestSolution.is_feasible()
Description

Reports whether the solution satisfies every constraint of the model.

Returns

Has Met Confidence

Language Function Signature
Java boolean OptQuestSolution.HasMetConfidence()
C# bool OptQuestSolution.HasMetConfidence()
C++ bool OptQuestSolution::HasMetConfidence() const
C int OQHasMetConfidence(HOptQuestSolution sol)
Python bool OptQuestSolution.has_met_confidence()
Description

Reports whether the solution has met the confidence requirement of every objective in variable-replication mode. The result is meaningful only when confidence settings exist (see § Set Objective Confidence Parameters).

Returns

Is Evaluated

Language Function Signature
Java boolean OptQuestSolution.IsEvaluated()
C# bool OptQuestSolution.IsEvaluated()
C++ bool OptQuestSolution::IsEvaluated() const
C int OQIsEvaluated(HOptQuestSolution sol)
Python bool OptQuestSolution.is_evaluated()
Description

Reports whether the solution was supplied to the engine with its output values already computed, that is, whether it was added with AddEvaluated(). A solution the engine generated, or one added with AddSuggested() or AddRequired(), reports false. An evaluated solution is not sent out for evaluation.

Returns

Get Value

Language Function Signature
Java double OptQuestSolution.GetValue(String name) throws COptQuestException
C# double OptQuestSolution.GetValue(string name)
C++ double OptQuestSolution::GetValue(const char* name) const
C double OQGetValue(HOptQuestSolution sol, const char* name)
Python float OptQuestSolution.get_value(str name)
Description

Returns the value of a named input variable, output variable, expression variable, objective or constraint. If the value is not available (the name is unknown, or the value is undefined), the result is NaN. The name can take a suffix that selects a replication, a confidence width or a part of a constraint.

Name Parameter Formats
Example

For a constraint named constraint1 defined as input1 - input2 < 3 OR input2 + input3 > 5 - input2:

Returns

Set Value

Language Function Signature
Java boolean OptQuestSolution.SetValue(String name, double value) throws COptQuestException
C# bool OptQuestSolution.SetValue(string name, double value)
C++ bool OptQuestSolution::SetValue(const char* name, double value)
C int OQSetValue(HOptQuestSolution sol, const char* name, double value)
Python bool OptQuestSolution.set_value(str name, float value)
Description

Sets the value of a named input or output variable. Its main use is to write output values during evaluation. A client can also overwrite an input value. Objectives, constraints and expression variables hold values the engine computes; a write to one of their names is discarded when the solution is sent.

Java checks the name at the call; C, C++, C# and Python check it when the solution is sent. Java returns false for a name the model does not declare. The other four keep the solution’s values in a map of their own, so the call succeeds, GetValue reads the value back, and the engine reports the name when Submit, AddSuggested, AddEvaluated or AddRequired sends the solution: ERROR BAD VALUE NAME: <name>. The engine allows objective and constraint names as an exception, so you can give a solution read back with GetBestSolutions straight back to the engine. The error for a misspelled output name therefore appears at the submit, not at the write.

Get Variable Names

Language Function Signature
Java List<String> OptQuestSolution.GetInputNames() / GetOutputNames()
C# List<string> OptQuestSolution.GetInputNames() / GetOutputNames()
C++ int OptQuestSolution::GetInputNameCount() const / const char* OptQuestSolution::GetInputNameAt(int i) const (and Output pair)
C int OQGetInputNameCount(HOptQuestSolution sol) / const char* OQGetInputNameAt(HOptQuestSolution sol, int i) (and Output pair)
Python list[str] OptQuestSolution.get_input_names() / get_output_names()
Description

Returns the names of the model’s variables in declaration order, so that a caller can loop over the values of a solution without a list of its own. The methods are on the solution rather than the model because an evaluator or monitor callback receives only a solution.

Every returned name resolves through GetValue, so the two can be looped together:

for (String name : sol.GetInputNames())
    System.out.println(name + " = " + sol.GetValue(name));

Most variables appear under the name they were added with. Permutations, containers and special purpose variables expand into their generated element names joined by @. Those generated names, not the base name, are what GetValue resolves:

Declaration Names returned
AddContinuousVariable("x", 0, 10) x
AddPermutationVariable("g", ["a", "b"]) g@a, g@b
AddVectorVariable("v", 3, 0, 1) v@1, v@2, v@3
AddMatrixVariable("m", 2, 2, 0, 1) m@1,1 … m@2,2
AddAngleVariable("dir", 0, 360) dir@theta
AddOutputVectorVariable("ovec", 2) ovec@1, ovec@2 (outputs)
Inputs versus outputs

The split follows what your evaluation does with each name. GetInputNames lists every name that your evaluation reads. For a special purpose variable, that includes every name in its Notes (dir@theta, mix@compA), except the output names of a policy sequence variable.

The two lists never overlap. Together they cover every name that resolves as a variable. Objectives and constraints also resolve through GetValue, but neither list reports them. Read them with the names that you gave to AddObjective and AddConstraint.

Returns
Notes

Submitting Pre-Known Solutions (Add Suggested / Add Evaluated / Add Required)

These three functions give the engine a solution the client already has. Call them before a run to use prior knowledge and speed up convergence. They differ in which values the client must set and in what happens when the solution violates the constraints:

Method Inputs Set By Client Outputs Set By Client Infeasible Handling
AddSuggested Yes No (OptQuest evaluates) The engine changes the input values so that they satisfy the input-only constraints and the rules of each variable type, then evaluates the solution
AddEvaluated Yes Yes Used as given; marked as infeasible
AddRequired Yes No (OptQuest evaluates) Used as given; evaluated and marked as infeasible

In all three cases:

Models Containing Special Purpose Variables

Set the variable names of a special purpose variable on a solution from GetEmptySolution() in the same way as any other input. The engine then handles those values as follows:

CopySolution(src) gives a copy that has the same values as src for every variable, including every name of each special purpose variable. It is the simplest way to move solutions between two models with the same structure, and AddAllSolutions uses it.

Add Suggested

Language Function Signature
Java boolean OptQuestSolution.AddSuggested() throws COptQuestException
C# bool OptQuestSolution.AddSuggested()
C++ bool OptQuestSolution::AddSuggested()
C int OQAddSuggested(HOptQuestSolution sol)
Python bool OptQuestSolution.add_suggested()
Description

Submits a solution with input values only, as a warm start. Before evaluation, the engine can change the input values so that they satisfy the input-only constraints and the rules of each variable type. Use it when the inputs are a hint, not a fixed point.

Add Evaluated

Language Function Signature
Java boolean OptQuestSolution.AddEvaluated() throws COptQuestException
C# bool OptQuestSolution.AddEvaluated()
C++ bool OptQuestSolution::AddEvaluated()
C int OQAddEvaluated(HOptQuestSolution sol)
Python bool OptQuestSolution.add_evaluated()
Description

Submits a solution with input and output values already set. Use it to add the results of earlier simulations without evaluating them again. If the inputs violate a constraint, the engine records the solution as infeasible and does not change its input values. The engine uses the values of a special purpose variable in an evaluated solution as given.

Add Required

Language Function Signature
Java boolean OptQuestSolution.AddRequired() throws COptQuestException
C# bool OptQuestSolution.AddRequired()
C++ bool OptQuestSolution::AddRequired()
C int OQAddRequired(HOptQuestSolution sol)
Python bool OptQuestSolution.add_required()
Description

Submits a solution with input values only, like AddSuggested, but the engine evaluates the inputs as supplied and does not change them. If the inputs violate a constraint, the engine evaluates the solution and marks it infeasible. The engine uses the values of a special purpose variable in a required solution as given, and the simulator receives them as given. Use it when the supplied inputs must be honored exactly.

Retrieving Results

Get Best Solutions

Language Function Signature
Java List<OptQuestSolution> OptQuestModel.GetBestSolutions()
List<OptQuestSolution> OptQuestModel.GetBestSolutions(int limit)
C# List<OptQuestSolution> OptQuestModel.GetBestSolutions(int limit = 1)
C++ int OptQuestModel::GetBestSolutions(int limit = 1)
const OptQuestSolution& OptQuestModel::GetBestSolutionsAt(int i)
C int OQGetBestSolutions(HOptQuestModel model, int limit)
HOptQuestSolution OQGetBestSolutionsAt(HOptQuestModel model, int i)
Python list[OptQuestSolution] OptQuestModel.get_best_solutions(int limit=1)
Description

Returns the best solutions found so far. Java, C# and Python return a list; C++ and C return a count and give access by index. The result is a list even when it holds one solution. The list is empty when the model has no completed iterations, for example before the first run or after a failed initialization, so test its length before you read the first entry. The first entry can be infeasible when the run found no feasible solution, so test IsFeasible() on it.

For a single objective, the order is:

  1. The feasible solutions, by objective value.
  2. The infeasible solutions, by objective value. The order does not depend on the size of a constraint violation, so when no solution is feasible, the first entry is the infeasible solution with the best objective value. An infeasible solution whose objective is NaN, for example because the evaluator did not set an output that the objective uses, comes after the infeasible solutions whose objective is a number, for a minimized and for a maximized objective.
  3. The solutions that the evaluator rejected. Their objective is NaN.

Solutions with equal objective values are in iteration order. For several objectives, the Pareto frontier is in no particular order.

In C and C++, GetBestSolutions returns the number of solutions, and GetBestSolutionsAt(int i) returns each one. The result list is per-model state: a later GetBestSolutions (or GetAllSolutions) on the same model replaces it, so an index that referred to one solution can refer to another afterwards. Fetch the count and read the entries out before you fetch again, and use the model’s result list from one thread at a time. In C, each OQGetBestSolutionsAt call is a fresh allocation that the caller owns and must release with OQDeleteSolution; a handle already fetched keeps its values across a later fetch. In C++, GetBestSolutionsAt returns a reference to an entry of the result list. That reference is not valid after the next fetch. To keep a solution, copy it: OptQuestSolution best(model.GetBestSolutionsAt(0));. In Java and C#, GetBestSolutions returns a new List each call. In Python, the binding makes per-call copies, and each returned OptQuestSolution owns its handle.

An index at or beyond the count, and a negative index, return a real, non-NULL handle whose OQIsValid is 0 and whose OQGetValue is NaN. Check the index against the count, or check OQIsValid; a NULL test does not detect it. That handle is an allocation too, so delete it.

Returns

Get All Solutions

Language Function Signature
Java List<OptQuestSolution> OptQuestModel.GetAllSolutions() throws COptQuestException
C# List<OptQuestSolution> OptQuestModel.GetAllSolutions()
C++ int OptQuestModel::GetAllSolutions()
const OptQuestSolution& OptQuestModel::GetAllSolutionsAt(int i)
C int OQGetAllSolutions(HOptQuestModel model)
HOptQuestSolution OQGetAllSolutionsAt(HOptQuestModel model, int i)
Python list[OptQuestSolution] OptQuestModel.get_all_solutions()
Description

Returns every evaluated solution: feasible, infeasible and rejected. Java, C# and Python return a list; C++ and C return a count and give access by index.

In C and C++, GetAllSolutions returns the number of solutions, and GetAllSolutionsAt(int i) returns each one. The result list is per-model state, and an out-of-range index returns the invalid-solution handle, the same as for GetBestSolutions.

Returns

Get Number Of Completed Iterations

Language Function Signature
Java int OptQuestModel.GetNumberOfCompletedIterations()
C# int OptQuestModel.GetNumberOfCompletedIterations()
C++ int OptQuestModel::GetNumberOfCompletedIterations()
C int OQGetNumberOfCompletedIterations(HOptQuestModel model)
Python int OptQuestModel.get_number_of_completed_iterations()
Description

Returns the number of solutions that have been evaluated: feasible, infeasible and rejected alike. In a concurrent run this is the count across every evaluator thread, so it is a convenient progress indicator for a monitor callback.

Returns

Get Max Replications

Language Function Signature
Java int OptQuestModel.GetMaxReplications()
C# int OptQuestModel.GetMaxReplications()
C++ int OptQuestModel::GetMaxReplications()
C int OQGetMaxReplications(HOptQuestModel model)
Python int OptQuestModel.get_max_replications()
Description

Returns the maximum replication count set with SetReplications. It is the upper bound of the replication numbers that GetReplication() can report, so use it as the loop bound when you read per-replication values from a solution with the "<name>;<replication>" form of GetValue.

Returns

Get Termination Reason

Language Function Signature
Java int OptQuestModel.GetTerminationReason()
C# int OptQuestModel.GetTerminationReason()
C++ int OptQuestModel::GetTerminationReason()
C int OQGetTerminationReason(HOptQuestModel model)
Python int OptQuestModel.get_termination_reason()
Description

Returns why the last run stopped, as one of the constants below.

Returns
Reason Java, C# C++ C, Python Meaning
Not Started = 0 OptQuestModel.TerminationReason.NotStarted OptQuestModel::TerminationReason::NotStarted OQTerminationReasonNotStarted No run has started.
Running = 1 OptQuestModel.TerminationReason.Running OptQuestModel::TerminationReason::Running OQTerminationReasonRunning A run is in progress, or Continue() cleared an interrupt.
LP Solved = 3 OptQuestModel.TerminationReason.LP OptQuestModel::TerminationReason::LP OQTerminationReasonLP The objective and every constraint are linear, and the engine solved the problem exactly.
Auto Stop = 4 OptQuestModel.TerminationReason.AutoStop OptQuestModel::TerminationReason::AutoStop OQTerminationReasonAutoStop The engine stopped the run because of a stop rule set with SetStopCycles or SetStopImprovement.
Optimal Found = 5 OptQuestModel.TerminationReason.OptimalFound OptQuestModel::TerminationReason::OptimalFound OQTerminationReasonOptimalFound The engine has no other candidate to try, for example because it evaluated every combination of values or because the constraints fix the values.
Max Iterations = 6 OptQuestModel.TerminationReason.MaxIterations OptQuestModel::TerminationReason::MaxIterations OQTerminationReasonMaxIterations The run completed the number of iterations that you asked for.
Max Time = 7 OptQuestModel.TerminationReason.MaxTime OptQuestModel::TerminationReason::MaxTime OQTerminationReasonMaxTime The engine stopped the run because it reached the time set with SetStopTime.
User Stopped = 8 OptQuestModel.TerminationReason.UserStopped OptQuestModel::TerminationReason::UserStopped OQTerminationReasonUserStopped The run was stopped, for example by Interrupt() or by a monitor that returned false.
Best Found = 9 OptQuestModel.TerminationReason.BestFound OptQuestModel::TerminationReason::BestFound OQTerminationReasonBestFound Not used. The engine does not set this reason.
Exception = 10 OptQuestModel.TerminationReason.Exception OptQuestModel::TerminationReason::Exception OQTerminationReasonException The run stopped because of an error. Read the error text.
Factories Done = 11 OptQuestModel.TerminationReason.FactoriesDone OptQuestModel::TerminationReason::FactoriesDone OQTerminationReasonFactoriesDone The engine has no more solutions to generate. With SuggestedSolutionsOnly, the supplied solutions are used up.
Infeasible = 12 OptQuestModel.TerminationReason.Infeasible OptQuestModel::TerminationReason::Infeasible OQTerminationReasonInfeasible No input values satisfy the constraints.
Cannot Generate = 13 OptQuestModel.TerminationReason.CannotGenerate OptQuestModel::TerminationReason::CannotGenerate OQTerminationReasonCannotGenerate The engine cannot generate a solution that is different from the solutions it already has.
Max Demo Iterations = 14 OptQuestModel.TerminationReason.MaxDemoIterations OptQuestModel::TerminationReason::MaxDemoIterations OQTerminationReasonMaxDemoIterations No license is set, and the run stopped at 50 iterations. Call SetLicense.

Set Termination Reason

Language Function Signature
Java void OptQuestModel.SetTerminationReason(int reason)
C# void OptQuestModel.SetTerminationReason(int reason)
C++ void OptQuestModel::SetTerminationReason(int reason)
C void OQSetTerminationReason(HOptQuestModel model, int reason)
Python OptQuestModel.set_termination_reason(int reason) -> None
Description

Overrides the model’s termination reason with one of the constants listed under Get Termination Reason. It exists for OptTek’s own use and for the bindings’ Interrupt() and Continue() implementations. Applications call Interrupt() and Continue() instead.

Returns

Managed Optimization Callbacks

With the callbacks, the client runs its own code inside the managed Optimize() and Sample() loops. The evaluator computes the output values of each trial solution. The optional monitor sees each completed solution and can stop the run.

Evaluate (Solution Evaluator)

Language Function Signature
Java boolean IOptQuestEvaluator.Evaluate(OptQuestSolution sol)
C# bool IOptQuestEvaluator.Evaluate(OptQuestSolution sol)
C++ bool IOptQuestEvaluator::operator()(OptQuestSolution& sol) const
C typedef int (*OQEvaluator)(HOptQuestSolution sol, void* context)
Python def evaluate(sol) -> bool
Description

This is the callback that runs your simulation in a managed run. For the Evaluate method of a solution, which computes the expressions, constraints and objectives of values that you supply, see § Evaluate Solution.

The evaluator is an object that implements IOptQuestEvaluator in Java, C# or C++, a function that takes a solution in Python, or a function pointer of type OQEvaluator in C. The engine calls it to evaluate each OptQuestSolution during a managed run. For a stochastic model with replications, the engine calls it once per replication of each trial. Across the replications of one trial the decision-variable values are identical, and the random variables (declared with Add*RandomVariable) are drawn again for each call.

In C, the context argument of Optimize is passed to the callback. In a concurrent or asynchronous run the engine calls the evaluator on several threads at once, so the callback must synchronize any shared state that the engine does not manage.

Example
class MyEvaluator implements IOptQuestEvaluator {
    public boolean Evaluate(OptQuestSolution sol) {
        try {
            double x = sol.GetValue("x");
            double y = runSimulation(x);   // your code
            sol.SetValue("y", y);
            return true;                   // false rejects the solution
        } catch (COptQuestException e) {
            return false;
        }
    }
}

model.Optimize(100, new MyEvaluator());

In Java, GetValue and SetValue declare throws COptQuestException, and Evaluate does not, so the evaluator catches the exception.

Returns

Monitor (Solution Monitor)

Language Function Signature
Java boolean IOptQuestMonitor.Monitor(OptQuestSolution sol)
C# bool IOptQuestMonitor.Monitor(OptQuestSolution sol)
C++ bool IOptQuestMonitor::operator()(OptQuestSolution& sol) const
C typedef int (*OQMonitor)(HOptQuestSolution sol, void* context)
Python def monitor(sol) -> bool
Description

The monitor is an object that implements IOptQuestMonitor in Java, C# or C++, a function that takes a solution in Python, or a function pointer of type OQMonitor in C. The engine calls it after it has post-processed an evaluated solution. The engine calls it as often as the evaluator: for a stochastic model with replications, the monitor runs once per replication of each trial, after the evaluator returns and the engine finishes its bookkeeping for that replication.

In C, the context argument is passed to the callback. In a concurrent run the engine calls the monitor on several threads at once, so the callback must synchronize any shared state that the engine does not manage.

Example
class StopAtTarget implements IOptQuestMonitor {
    public boolean Monitor(OptQuestSolution sol) {
        try {
            double profit = sol.GetValue("profit");
            System.out.println("iteration " + sol.GetIteration() + ": " + profit);
            return profit < 1000;          // false stops the run
        } catch (COptQuestException e) {
            return false;
        }
    }
}

model.Optimize(100, new MyEvaluator(), new StopAtTarget());

With replications, the engine calls the monitor once for each replication. In the monitor, GetValue on an output or an objective gives the combined value of the replications that are complete so far. To stop on the combined value of all the replications of a trial solution, test IsComplete() before you compare the value, for example return !sol.IsComplete() || profit < 1000;.

Returns

Utility Functions

Get Last Error (Model)

Language Function Signature
Java Java reports errors by throwing COptQuestException.
C# string OptQuestModel.GetLastError()
C++ const char* OptQuestModel::GetLastError() const
C const char* OQGetLastError(HOptQuestModel model)
Python str OptQuestModel.get_last_error()
Description

Returns the description of the last error recorded on the model. Read it after a model function returns false (0 in C). Java has no such method; it throws COptQuestException instead. The text is sticky and per-thread; see § Concepts › Error Handling.

Returns

Get Last Error (Solution)

Language Function Signature
Java Java reports errors by throwing COptQuestException.
C# string OptQuestSolution.GetLastError()
C++ const char* OptQuestSolution::GetLastError() const
C const char* OQGetLastSolutionError(HOptQuestSolution sol)
Python str OptQuestSolution.get_last_error()
Description

Returns the description of the last error recorded on the solution. Read it after a solution method returns false (0 in C), or after Submit or Reject returns -1.

Returns

Get Version Info

Language Function Signature
Java static String OptQuest.GetVersionInfo()
C# static string OptQuestNet.GetVersionInfo()
C++ static const char* OptQuest::GetVersionInfo()
C const char* OQGetVersionInfo()
Python str get_version_info()
Description

Returns a string that identifies the version of the engine library that is loaded.

Returns

Reference

This chapter holds the reference material behind the API: the expression language, the probability distributions that Response Distribution Sampling uses, the steps to link OptQuest into a project in each language, and the STDIO interface for environments that cannot link OptQuest directly.

Functions and Constants Available In Expressions

These functions and constants are available in the expressions of objectives, constraints, sample metrics and expression variables. They are grouped by category. Function names are case-insensitive. The arithmetic operators are +, -, *, / and ^ for a power; ** is accepted as a synonym for ^.

Constants

Constant Description
pi Mathematical constant π, approximately equal to 3.14159.
e Mathematical constant e, approximately equal to 2.71828.

Variable Argument Functions and Arrays

A function marked variadic accepts any number of arguments as a comma-separated list, for example min(a, b), min(a, b, c) or sum(x1, x2, x3, x4). The same functions also accept one or more array(...) groups, and arrays can be mixed with standard variables or nested: sum(array(x, y), z) and max(array(1, 2, 3), 0.5) are both valid. array(...) exists only to pass a group of values into a variable argument function. It has no meaning on its own.

Arithmetic, Powers, and Logarithms

Function Description
abs(x) Returns the absolute value of a number.
signum(x) Returns -1 if x < 0, 1 if x > 0, otherwise 0.
sqrt(x) Returns the square root of a number.
cbrt(x) Returns the cube root of a number (defined for negative x).
pow(x,y) Returns x raised to the power y.
exp(x) Returns e raised to the power x.
expm1(x) Returns exp(x) - 1, accurate even when x is close to 0.
log(x) Returns the natural logarithm (base e) of a number.
log10(x) Returns the base-10 logarithm of a number.
log2(x) Returns the base-2 logarithm of a number.
log1p(x) Returns log(1 + x), accurate even when x is close to 0.
logbase(b,x) Returns the logarithm of x in base b, that is, log(x) / log(b).

Rounding and Remainders

Function Description
floor(x) Returns the largest whole number less than or equal to x.
ceil(x) Returns the smallest whole number greater than or equal to x.
round(x) Returns the nearest whole number; ties are rounded away from zero (round(2.5) is 3, round(-2.5) is -3).
trunc(x) Returns the integer part of x, truncated toward zero.
frac(x) Returns the fractional part of x toward zero, that is, x - trunc(x) (frac(-2.7) is -0.7).
mod(x,y) Returns the modulo of x by y, taking the sign of y (mod(-5,3) is 1).
fmod(x,y) Returns the IEEE remainder of x / y (may be negative).

Trigonometry and Angle Conversion

Function Description
sin(x) Returns the sine of x, where x is an angle in radians.
cos(x) Returns the cosine of x, where x is an angle in radians.
tan(x) Returns the tangent of x, where x is an angle in radians.
asin(x) Returns the arcsine of x, in radians.
acos(x) Returns the arccosine of x, in radians.
atan(x) Returns the arctangent of x, in radians.
atan2(y,x) Returns the arctangent of y/x in the range −π to π radians, using the signs of both arguments to place the result in the correct quadrant. The first argument is y, matching C, Java and Python: atan2(1, 2) is 0.4636…, not 1.1071…. If both parameters are 0, returns 0.
dtor(x) Converts degrees to radians.
rtod(x) Converts radians to degrees.

Hyperbolic Functions

Function Description
sinh(x) Returns the hyperbolic sine of x.
cosh(x) Returns the hyperbolic cosine of x.
tanh(x) Returns the hyperbolic tangent of x.
asinh(x) Returns the inverse hyperbolic sine of x (defined for all real x).
acosh(x) Returns the inverse hyperbolic cosine of x; NaN for x < 1.
atanh(x) Returns the inverse hyperbolic tangent of x, defined on (-1, 1); ±Inf at ±1.

Comparison, Logic, and Conditionals

Function Description
eq(x,y) Returns 1 if x == y, otherwise 0.
ne(x,y) Returns 1 if x != y, otherwise 0.
lt(x,y) Returns 1 if x < y, otherwise 0.
le(x,y) Returns 1 if x <= y, otherwise 0.
gt(x,y) Returns 1 if x > y, otherwise 0.
ge(x,y) Returns 1 if x >= y, otherwise 0.
and(...) Variadic. Returns 1 if every argument is nonzero, otherwise 0 (NaN if any argument is non-finite).
or(...) Variadic. Returns 1 if any argument is nonzero, otherwise 0 (NaN if any argument is non-finite).
not(x) Returns 1 if x == 0, otherwise 0.
xor(x,y) Returns 1 if exactly one of x, y is nonzero, otherwise 0.
between(x,lo,hi) Returns 1 if lo <= x <= hi, otherwise 0.
finite(x) Returns 1 if x is a finite IEEE floating-point number (not NaN or Inf), otherwise 0.
ifnan(x,fallback) Returns x if x is finite, otherwise fallback. Useful for keeping an objective finite.
if(x,y,z) Returns y if x != 0, otherwise z.
choose(i,a,b,...) Variadic. Returns the i-th argument, 1-based (choose(2,a,b,c) is b); NaN if i is out of range.
indexof(value,x1,...) Variadic. Returns the 1-based position of the first argument exactly equal to value; NaN if none match.

Clamping, Interpolation, and Smoothing

These functions shape objectives and constraints. The smooth variants (softplus, sigmoid, smoothmax, smoothmin) are differentiable everywhere; the hard forms (clamp, relu) are not.

Function Description
clamp(x,lo,hi) Returns lo if x < lo, hi if x > hi, otherwise x.
lerp(a,b,t) Linear interpolation between a and b: a + t * (b - a).
relu(x) Returns max(0, x).
pos(x) Alias for relu(x); returns max(0, x).
negpart(x) Returns max(0, -x), the magnitude of the negative part of x.
softplus(x) Returns log(1 + exp(x)), a smooth approximation to relu.
sigmoid(x) Returns 1 / (1 + exp(-x)), the logistic function.
logit(x) Returns log(x / (1 - x)), the inverse of sigmoid.
smoothmax(k,x1,x2,...) Variadic. A smooth, differentiable approximation to the maximum that sharpens as k increases (k > 0).
smoothmin(k,x1,x2,...) Variadic. A smooth, differentiable approximation to the minimum (k > 0).

Aggregation Over a List

All of these are variadic. They accept a comma-separated list or one or more array(...) groups (see § Variable Argument Functions and Arrays above).

Function Description
sum(...) Returns the sum of the values.
average(...) Returns the arithmetic mean of the values.
product(...) Returns the product of the values, accumulated in log space to resist overflow and underflow.
geomean(...) Returns the geometric mean of the values; NaN if any value is <= 0.
min(...) Returns the smallest value. Accepts both min(a, b) and min(array(...)).
max(...) Returns the largest value. Accepts both max(a, b) and max(array(...)).
median(...) Returns the median of the values.
range(...) Returns the spread of the values, max - min.
count(...) Returns the number of values.
variance(...) Returns the population variance (divides by n).
stdev(...) Returns the population standard deviation (divides by n).
percentile(p,x1,x2,...) Returns the p-th percentile of the values by linear interpolation, with p in [0, 1] given as the first argument.
norm(...) Returns the Euclidean (L2) norm, sqrt(sum(xi^2)).
norm1(...) Returns the L1 norm, sum(abs(xi)).
norminf(...) Returns the L∞ norm, max(abs(xi)).
logsumexp(...) Returns log(sum(exp(xi))), computed in a numerically stable way.
argmax(...) Returns the 1-based position of the largest value (the first one on ties).
argmin(...) Returns the 1-based position of the smallest value (the first one on ties).
sumproduct(array(...),array(...)) Returns the sum of the elementwise products of two or more equal-length arrays.
array(...) Groups values into a single array argument for the variable argument functions above; not used on its own.

Distance and Geometry

Function Description
hypot(x,y) Returns sqrt(x^2 + y^2) without intermediate overflow.
dist(x1,y1,x2,y2) Returns the Euclidean distance between the points (x1, y1) and (x2, y2).
sphdist(lat1,lon1,lat2,lon2) Returns the great-circle (haversine) distance between two points on a unit sphere (radius 1), in radians. Latitude and longitude are also given in radians; convert from degrees with dtor. Multiply the result by a radius to get a distance in the units you want (for example 6371 for kilometers on Earth, or 3958.8 for miles).
geodist(lat1,lon1,lat2,lon2) Returns the great-circle (haversine) distance between two points on Earth in kilometers, assuming a spherical earth of radius 6371 km. Latitude and longitude are given in degrees. Equivalent to 6371 * sphdist(dtor(lat1), dtor(lon1), dtor(lat2), dtor(lon2)).

Combinatorics and Special Functions

Function Description
factorial(x) Returns x! for whole x >= 0 (x is truncated to an integer).
combin(n,k) Returns the number of combinations of n items taken k at a time (n choose k).
permut(n,k) Returns the number of permutations of n items taken k at a time, n! / (n - k)!.
erf(x) Returns the Gauss error function of x.
erfc(x) Returns the complementary error function, 1 - erf(x).
lgamma(x) Returns the natural logarithm of the absolute value of the gamma function of x.
gammaln(x) Alias for lgamma(x).
sinc(x) Returns the unnormalized sinc function, sin(x) / x, with sinc(0) defined as 1.

Financial

The financial functions follow the spreadsheet sign convention: cash you receive is positive, cash you pay is negative, and payments occur at the end of each period. The argument order differs between the functions: the quantity a function solves for is the one that is missing from its arguments.

Function Description
npv(rate,cf1,cf2,...) Variadic. Returns the net present value of a series of cash flows at the given rate; the first cash flow is discounted one period.
irr(cf0,cf1,...) Variadic. Returns the internal rate of return (the rate at which the net present value is zero); cf0 occurs at time 0.
pmt(rate,nper,pv,fv) Returns the payment per period for a loan or annuity.
fv(rate,nper,pmt,pv) Returns the future value.
pv(rate,nper,pmt,fv) Returns the present value.
nper(rate,pmt,pv,fv) Returns the number of periods.
rate(nper,pmt,pv,fv) Returns the interest rate per period.

Random Sampling and Inverse CDF (PPF)

Function Description
rand() Returns a uniformly distributed random number in [0, 1).
betappf(p,alpha,beta) Returns the percent point function* of the Beta distribution of p with parameters alpha and beta using the same conventions as scipy.stats.beta.
cauchyppf(p,location,scale) Returns the percent point function* of the Cauchy distribution of p with parameters location and scale using the same conventions as scipy.stats.cauchy.
chisqppf(p,df) Returns the percent point function* of the Chi-squared distribution of p with parameter df using the same conventions as scipy.stats.chi2.
expppf(p,scale) Returns the percent point function* of the Exponential distribution of p with parameter scale using the same conventions as scipy.stats.expon.
gammappf(p,a,scale) Returns the percent point function* of the Gamma distribution of p with parameters a and scale using the same conventions as scipy.stats.gamma.
lognormppf(p,shape,scale) Returns the percent point function* of the Log Normal distribution of p with parameters shape and scale using the same conventions as scipy.stats.lognorm.
normppf(p,mean,sigma) Returns the percent point function* of the Normal distribution of p with parameters mean and sigma using the same conventions as scipy.stats.norm.
paretoppf(p,gamma,location,scale) Returns the percent point function* of the Pareto distribution of p with parameters gamma, location, and scale using the same conventions as scipy.stats.pareto.
poissonppf(p,lambda) Returns the percent point function* of the Poisson distribution of p with parameter lambda using the same conventions as scipy.stats.poisson.
tppf(p,df) Returns the percent point function* of the T distribution of p with parameter df using the same conventions as scipy.stats.t.
uniformppf(p,min,max) Returns the percent point function* of the Uniform distribution of p from min to max using the same conventions as scipy.stats.uniform.
weibullppf(p,shape,scale) Returns the percent point function* of the Weibull distribution of p with parameters shape and scale using the same conventions as scipy.stats.weibull_min.

* The percent point function (PPF), also called the inverse cumulative distribution function, returns the value x such that the probability of a draw at or below x is p. For a CDF F(x) = P(X <= x), the PPF is F^(-1)(p) = x, with p in [0, 1]. Its usual use is to draw random numbers from a distribution: betappf(rand(), alpha, beta) turns a uniform random number into a draw from Beta(alpha, beta).

Probability Distributions

Response Distribution Sampling (RDS) is a special case of Adaptive Sampling. The engine tracks two things: the current empirical distribution of the responses from the simulation, that is, what is known now, and the predicted distribution of the responses at the candidate points, estimated from the surrogate model. The next point to evaluate is the one that is predicted to move the empirical distribution closest to the wanted distribution.

The method is a discretized form of inverse transform sampling. The engine uses the wanted distribution to build bins of unequal width for the histogram of the empirical distribution. The bins are placed so that, if the empirical distribution matched the wanted one, every bin would hold the same number of samples. The response values that must be sampled next are therefore the values of a bin with too few samples. There is no need for a histogram of equal bins and a statistical test of which bin moves the empirical distribution most; a count per bin is sufficient.

The engine builds the bins for the common distributions listed below. For any other distribution, supply the bin edges yourself with SetSampleRDSDiscrete. Texts differ on the definitions of some of these distributions. OptQuest uses the definitions of the Python scipy.stats package.

Uniform

A uniform continuous random variable on [a, b]. Every value from a to b is equally likely.

\text{uniform}(a, b)

a: Lower bound

b: Upper bound

\text{PDF}(x) = \begin{cases} \frac{1}{b - a} & a \leq x < b \\ 0 & \text{otherwise} \end{cases}

Normal

A normal continuous random variable with mean \mu and standard deviation \sigma. The values spread symmetrically around \mu. About 95 percent of the values are within 2\sigma of \mu.

\text{norm}(\mu, \sigma)

\mu: Mean

\sigma: Standard deviation

\text{PDF}(x) = \frac{1}{\sigma \sqrt{2\pi}} \exp\left( -\frac{(x - \mu)^2}{2\sigma^2} \right)

Log Normal

A lognormal continuous random variable: a value whose logarithm has a normal distribution. \text{scale} is the median.

\text{lognorm}(s, \text{scale})

s: Shape parameter

\text{scale}: Scale parameter

\text{PDF}(x) = \frac{1}{s x \sqrt{2\pi}} \exp\left( -\frac{(\ln (x / \text{scale}))^2}{2 s^2} \right)

Beta

A beta continuous random variable: a value from 0 to 1, such as a proportion. The two shape parameters set where the values collect. With \alpha = \beta = 1, every value from 0 to 1 is equally likely. The mean is \alpha / (\alpha + \beta).

\mathrm{Beta}(\alpha,\beta)

\alpha: Shape parameter

\beta: Shape parameter

\text{PDF}(x) = \frac{x^{\alpha-1} (1-x)^{\beta-1}}{B(\alpha, \beta)}

Poisson

A Poisson discrete random variable: the number of events in a fixed interval, when the events occur at random at an average rate of \lambda for each interval. The mean is \lambda.

\text{poisson}(\lambda)

\lambda: Rate parameter

\text{PMF}(k) = e^{-\lambda} \frac{\lambda^k}{k!}

Exponential

An exponential continuous random variable: the time between events that occur at random at a constant average rate. \text{scale} is the mean time.

\text{exponential}(\text{scale})

\text{scale}: Scale parameter

\text{PDF}(x) = \frac{1}{\text{scale}} \exp\left( -\frac{x}{\text{scale}} \right)

Cauchy

A Cauchy continuous random variable. The values spread symmetrically around \text{location}, which is the median. Values far from the median are much more likely than with a normal distribution, and the distribution has no mean.

\text{cauchy}(\text{location}, \text{scale})

\text{location}: Location parameter

\text{scale}: Scale parameter

\text{PDF}(x) = \frac{1}{\pi \text{scale} \left[1 + \left( \frac{x - \text{location}}{\text{scale}} \right)^2 \right]}

Gamma

A gamma continuous random variable: a positive value. For a whole number a, it is the total time of a steps that each take an exponential time with the mean \text{scale}. The mean is a \cdot \text{scale}.

\text{gamma}(a, \text{scale})

a: Shape parameter

\text{scale}: Scale parameter

\text{PDF}(x) = \frac{x^{a-1} e^{-x / \text{scale}}}{\text{scale}^a \Gamma(a)}

Chi Square

A chi-squared continuous random variable: the sum of the squares of \nu independent standard normal values. The mean is \nu.

\chi^2(\nu)

\nu: Degrees of freedom

\text{PDF}(x) = \frac{1}{2^{\nu/2} \Gamma(\nu/2)} x^{\nu/2 - 1} e^{-x/2}

Pareto

A Pareto (Type I) continuous random variable, in the form that both AddParetoRandomVariable and SetSampleRDSPareto use. Its values have a long upper tail: most values are near the smallest value, and a few are much larger. A smaller \gamma gives a longer tail.

\text{pareto}(\gamma, \text{loc}, \text{scale})

\gamma: Shape parameter (tail index)

\text{loc}: Location parameter (shift)

\text{scale}: Scale parameter; the minimum possible value is \text{loc} + \text{scale}

\text{PDF}(x) = \frac{\gamma}{\text{scale}} \left( \frac{x - \text{loc}}{\text{scale}} \right)^{-\gamma - 1} for x \geq \text{loc} + \text{scale}

Student’s t

A Student’s t continuous random variable. The values spread symmetrically around 0, and values far from 0 are more likely than with a standard normal distribution. With more degrees of freedom, the distribution is closer to the standard normal distribution.

\text{T}(\nu)

\nu: Degrees of freedom

\text{PDF}(x) = \frac{\Gamma((\nu+1)/2)}{\sqrt{\nu \pi} \Gamma(\nu/2)} \left(1 + \frac{x^2}{\nu}\right)^{-(\nu+1)/2}

Weibull

A Weibull minimum extreme value continuous random variable: a positive value, often used for a time to failure. With c = 1, it is the exponential distribution with the mean \text{scale}.

\text{weibull}_\text{min}(c, \text{scale})

c: Shape parameter

\text{scale}: Scale parameter

\text{PDF}(x) = \frac{c}{\text{scale}} \left( \frac{x}{\text{scale}} \right)^{c-1} \exp\left( -\left( \frac{x}{\text{scale}} \right)^c \right)

Linking OptQuest To Your Project

OptTek ships the OptQuest Engine with bindings for Java, C#, C++, C and Python. This section describes how to add OptQuest to a project in each language.

Java

OptQuest for Java is one file, OptQuest.jar. Add it to your project as a library. It contains both the OptQuest 9 API and the OptQuest 10 API.

C#

OptQuest for C# is two files: OptQuestEngine.dll, the engine, and OptQuestNet.dll, the C# binding. Add a reference to OptQuestNet.dll to your project. At run time both DLLs must be in the same directory. The distribution includes a Visual Studio solution with working examples.

C++

OptQuest for C++ is OptQuestEngine.dll and OptQuestLib.dll, which together hold the engine, plus the header optquest.h and the import library OptQuestLib.lib, which hold the C++ binding. Include the header, link OptQuestLib.lib, and put OptQuestLib.dll and OptQuestEngine.dll in the same directory as your application at run time. The distribution includes a Visual Studio solution with working examples.

C

OptQuest for C uses the same files as C++: OptQuestEngine.dll and OptQuestLib.dll hold the engine, and optquest.h and OptQuestLib.lib hold the C binding. Include the header, link OptQuestLib.lib, and put OptQuestLib.dll and OptQuestEngine.dll in the same directory as your application at run time. The distribution includes a Visual Studio solution with working examples.

Array Arguments From a Host That Cannot Build a Pointer Array

Twelve C entry points take an array of pointers to rows: ten take rows of numbers (const double**) and two take rows of strings (const char***). Seventeen take an array of strings (const char** or const char***). A host such as MATLAB or IDL can pass a contiguous buffer but not an array of pointers, so each of those functions has a second form that takes the data in one piece:

Each variant calls the same implementation as the pointer-array form, so the two validate the same way, fail the same way and produce identical Describe() text. OQAddExchangeableGroupFlat2D is the two-dimensional group. OQAddExchangeableGroupFlat is the one-dimensional form, with one variable for each item.

Python

OptQuest for Python is optquest.py, the binding, plus the engine library for the platform:

By default optquest.py loads the library from its own directory. To load it from elsewhere, set the module-level dll_path before you create the first OptQuestModel:

import optquest
optquest.dll_path = "/path/to/library/directory"
model = optquest.OptQuestModel()

COM (VBA, VBScript, VB6, Excel)

OptQuest also has a COM interface for Automation clients that cannot link the .NET, C++ or C libraries. OptQuestCOM.dll registers it. It has three creatable objects:

ProgID Purpose
OptQuestNet.OptQuestModelCOM The model, the COM form of OptQuestModel
OptQuestNet.OptQuestSolutionCOM A solution, the COM form of OptQuestSolution
OptQuestNet.OptQuestConstantsCOM The constants, as read-only properties (see below)
Dim model As Object
Set model = CreateObject("OptQuestNet.OptQuestModelCOM")
model.AddContinuousVariable "x", 0, 10
model.AddMaximizeObjective "profit", "3*x"

The COM surface is the C# surface with the adjustments that Automation requires:

Dim consts
Set consts = CreateObject("OptQuestNet.OptQuestConstantsCOM")
model.SetObjectiveConfidence "obj", consts.CONFIDENCE_TYPE2, consts.CONFIDENCE_LEVEL95, 0.05

The IID of IOptQuestModelCOM changed in OptQuest 10.1, and the IID of IOptQuestSolutionCOM changed in OptQuest 10.2. A client that binds late (CreateObject and Object variables), as in the example above, needs no change. A client with an early-bound reference to an earlier type library must refresh it.

The distribution includes 90 example programs in the directory examples. OptQuest 10.2 Examples for COM (VBScript) explains each one.

Standard I/O Interface

For expert use only. The engine can also run as a standalone process that reads commands from standard input and writes replies to standard output. Use this interface only when your application cannot link one of the OptQuest libraries (Java, C#, C++, C or Python). It supports the manual optimization loop: the client requests each solution, evaluates it, and submits or rejects it.

Setup

Interface Characteristics

In-Process Variant (OQCore*)

The same commands are also available in-process, with no subprocess and no pipe. OptQuestLib exports one C function per command. Each takes the command’s argument string and returns the reply:

char* OQCoreCreateModel(const char* block);
char* OQCoreCreateSolution(const char* optid);
char* OQCoreSubmitSolution(const char* solution);
char* OQCoreRejectSolution(const char* solution);
char* OQCorePredictSolution(const char* solution);
char* OQCoreEvaluateSolution(const char* solution);
char* OQCoreAddSolution(const char* solution);
char* OQCoreGetSolution(const char* args);
char* OQCoreGetBestSolutions(const char* args);
char* OQCoreGetAllSolutions(const char* optid);
char* OQCoreAddAllSolutions(const char* args);
char* OQCoreCopySolution(const char* args);
char* OQCoreGetTerminationReason(const char* optid);
char* OQCoreSetTerminationReason(const char* args);
char* OQCoreGetNames(const char* optid);
char* OQCoreDeleteModel(const char* optid);
char* OQCoreGetVersionInfo(void);
void  OQCoreFree(char* s);

There are three differences from the subprocess interface:

The command syntax, the model-definition commands and the reply formats are the same as in the STDIO reference below. OQCore<Command> is the in-process spelling of <COMMAND>.

This surface exists for tooling that already builds command strings (YAML or DSL front ends, agent integrations, code generators) and can hand them to the engine directly. For ordinary integration work, use the typed API. The Python binding wraps this layer as its OptQuestCore class.

Command List

The STDIO interface covers the manual optimization loop: model creation, solution request, evaluation and result retrieval. The table lists each command and its equivalent in the typed API.

Command Description API Equivalent
CREATEMODEL Creates a new model object. new OptQuestModel()
CREATESOLUTION Generates a new solution for evaluation, populated with input variable values. model.CreateSolution()
SUBMITSOLUTION Submits an evaluated solution to the optimization engine for processing. solution.Submit()
REJECTSOLUTION Rejects a solution that could not be evaluated. solution.Reject()
PREDICTSOLUTION Uses the internal metamodel to predict the response of a solution. solution.Predict()
EVALUATESOLUTION Computes a solution’s expressions, constraints, and objectives without submitting it. solution.Evaluate()
ADDSOLUTION Adds a suggested (input-only), required (input-only, used as given), or evaluated (input and output) solution to the model. solution.AddSuggested()
solution.AddEvaluated()
solution.AddRequired()
GETSOLUTION Retrieves the values of an evaluated solution after the engine has processed it. solution.Update()
GETBESTSOLUTIONS Retrieves the best solutions, either the n-best or the Pareto frontier. model.GetBestSolutions(limit)
GETALLSOLUTIONS Retrieves all evaluated solutions from the model. model.GetAllSolutions()
ADDALLSOLUTIONS Copies all solutions from a source model to a destination model. model.AddAllSolutions(srcModel)
COPYSOLUTION Copies one solution into a model, with the same values for every variable. model.CopySolution(src)
GETNAMES Retrieves the model’s input and output variable names, in declaration order. solution.GetInputNames()
solution.GetOutputNames()
DELETEMODEL Deletes a model, freeing associated resources. OptQuestModel destructor
VERSIONINFO Returns the version info about the engine. OptQuest.GetVersionInfo()
QUIT Terminates the OptQuest STDIO server, closing the session.

Command Reference

Each command below is documented with its wire format and the format of its reply. The commands are listed in the order of a typical session: model definition, solution generation, evaluation and result retrieval, then model deletion and session end.

Solution Replies

Several commands reply with a solution. There are two shapes.

The short form (CREATESOLUTION, COPYSOLUTION) is:

<modelIdentifier> <solutionIdentifier>
<iteration> <replication> <numberOfReplications> <isComplete> <isFeasible> <hasMetConfidence> <isEvaluated>
<inputName1> <inputValue1>
...
<inputNameN> <inputValueN>

The full form (GETSOLUTION, PREDICTSOLUTION, EVALUATESOLUTION, and each solution in a GETBESTSOLUTIONS or GETALLSOLUTIONS reply) has the same first two lines, followed by one <name> <value> pair per line for:

<modelIdentifier> <solutionIdentifier>
<iteration> <replication> <numberOfReplications> <isComplete> <isFeasible> <hasMetConfidence> <isEvaluated>
<inputName1> <inputValue1>
...
<inputNameN> <inputValueN>
<outputName1> <outputValue1>
<outputName1;1> <outputValue1Replication1>
...
<outputName1;R> <outputValue1ReplicationR>
...
<objectiveName1> <objectiveValue1>
<objectiveName1;cw> <objectiveConfidenceWidth1>
<objectiveName1;1> <objectiveValue1Replication1>
...
<objectiveName1;R> <objectiveValue1ReplicationR>
...
<constraintName1> <constraintFeasibility1>
<constraintName1;LHS;1> <constraintLeftHandSideValue1Clause1>
<constraintName1;RHS;1> <constraintRightHandSideValue1Clause1>
...
<constraintName1;LHS;C> <constraintLeftHandSideValue1ClauseC>
<constraintName1;RHS;C> <constraintRightHandSideValue1ClauseC>
...
Create Model
Command Format

CREATEMODEL spans several lines. It begins with the line CREATEMODEL, continues with one model-definition command per line, and ends with a line that contains only END. Each model-definition command is one line with space-separated parameters.

CREATEMODEL
...model definition commands...
END
Model Definition Commands

Each model-definition command starts with an identifier followed by one or more parameters, separated by spaces unless the table says otherwise. The table lists the commands and their equivalents in the typed API. Identifiers are case-insensitive, so continuous, CONTINUOUS and Continuous are all accepted.

The server skips blank and whitespace-only lines and ignores leading whitespace, so a block can be indented. An identifier that is not in the table is an error: the server does not create the model, so you cannot get a model that silently lacks a variable or a setting because of a misspelling.

Command Parameters Equivalent API Function
LICENSE <license> model.SetLicense(license)
LOGSETUP <filespec> (the rest of the line; may contain spaces) model.LogSetup(filespec)
LOGSOLUTIONS <filespec> (the rest of the line; may contain spaces) model.LogSolutions(filespec)
CONTINUOUS <name> <min> <max> model.AddContinuousVariable(name, min, max)
INTEGER <name> <min> <max> model.AddIntegerVariable(name, min, max)
DISCRETE <name> <min> <max> <step> model.AddDiscreteVariable(name, min, max, step)
BINARY <name> model.AddBinaryVariable(name)
DESIGN <name> <num> model.AddDesignVariable(name, num)
ENUMERATION <name> <items> <items>: Space-delimited list of doubles model.AddEnumerationVariable(name, items)
PERMUTATION <group> <names> <names>: Space-delimited list of strings model.AddPermutationVariable(group, names)
TUPLE <name> <tuples> <tuples>: Comma-separated values, semicolon-separated tuples (for example a,b,c;d,e,f)1 model.AddTupleVariable(name, tuples)
GEOLOCATION <name> <locations> <locations>: Comma-separated lat/lon pairs, semicolon-separated (for example lat1,lon1;lat2,lon2)1 model.AddGeolocationVariable(name, locations)
SELECTION <name> <selVars> <selVars>: Space-delimited list of strings model.AddSelectionVariable(name, selVars)
EXCHANGE <name> <group> <group>: Comma-separated values, semicolon-separated groups (for example x1,y1,z1;x2,y2,z2)1 4 model.AddExchangeableGroup(name, group)
FIXGROUP <name> <variables> <variables>: Space-delimited list of strings model.AddFixGroup(name, variables)
FLOATGROUP <name> <variables> <variables>: Space-delimited list of strings model.AddFloatGroup(name, variables)
EXCLUSIVE <name> <min> <max> model.AddVariableExclusiveRange(name, min, max)
VECTOR <name> <n> <min> <max> model.AddVectorVariable(name, n, min, max)
MATRIX <name> <m> <n> <min> <max> model.AddMatrixVariable(name, m, n, min, max)
ANGLE <name> <minDeg> <maxDeg> model.AddAngleVariable(name, minDeg, maxDeg)
SPHERICALANGLE <name> <minThetaDeg> <maxThetaDeg> <minPhiDeg> <maxPhiDeg> model.AddSphericalAngleVariable(name, minThetaDeg, maxThetaDeg, minPhiDeg, maxPhiDeg)
MIXTURE <name> <k\|c1,c2,...> [<lowerBounds> <upperBounds>] [<sumTo>] model.AddMixtureVariable(name, components, lowerBounds, upperBounds, sumTo)
(components = a component count or comma-separated names; bounds are optional but must appear as a matched pair, each either a comma-separated list of k values or a single value broadcast to every component; sumTo is optional and defaults to 1.0)
SEQUENCE <name> <c1,c2,...> [<topK>] model.AddSequenceVariable(name, components, topK)
(components = comma-separated names; topK is optional)
MULTISTAGESEQUENCE <name> <stage1c1,stage1c2,...;stage2c1,stage2c2,...;...> model.AddMultiStageSequenceVariable(name, stageGroups)
(semicolon between stages, comma within each stage)
POLICYSEQUENCE <name> <item1,item2,...> <feat1,feat2,...> <r1c1,r1c2,...;r2c1,r2c2,...;...> model.AddPolicySequenceVariable(name, featureMatrix, itemNames, featureNames)
(item names, then feature names, then the feature matrix; semicolon between matrix rows, comma within names and within each row)
CHOICE <name> <k> model.AddChoiceVariable(name, k)
MULTICHOICE <name> <choice1,choice2,...> <minSelect> <maxSelect> model.AddMultiChoiceVariable(name, choices, minSelect, maxSelect)
ASSIGNMENT Simple: <name> <m> <n>
Homogeneous: <name> <m> <n> <mustAssign> <binCapMin> <binCapMax>
Heterogeneous: <name> <m> <n> <b1,...,bm> <min1,...,minn> <max1,...,maxn>; mustAssign values are true/false; comma-separated arrays distinguish heterogeneous from homogeneous
model.AddAssignmentVariable(name, m, n)
model.AddAssignmentVariable(name, m, n, mustAssign, binCapMin, binCapMax)
model.AddAssignmentVariable(name, m, n, mustAssign[], binCapMins[], binCapMaxs[])
ITEMSELECTION Exact: <name> <n> <k>
Range: <name> <n> <kMin> <kMax>; four tokens = range form, three = exact form
model.AddItemSelectionVariable(name, n, k)
model.AddItemSelectionVariable(name, n, kMin, kMax)
BUDGETEDSELECTION Simple: <name> <n> <budgetMax> <c1,...,cn>
Full: <name> <n> <budgetMin> <budgetMax> <kMin> <kMax> <c1,...,cn>; six tokens before the cost array = full form, three = simple form
model.AddBudgetedSelectionVariable(name, n, costs, budgetMax)
model.AddBudgetedSelectionVariable(name, n, costs, budgetMin, budgetMax, kMin, kMax)
PARTITION <name> <m> <k> model.AddPartitionVariable(name, m, k)
LOWRANK <name> <rows> <cols> <rank> <min> <max> model.AddLowRankMatrixVariable(name, rows, cols, rank, min, max)
LOWRANKCORRECTION <name> <initial_matrix> <rank> <min> <max> model.AddLowRankCorrectionMatrixVariable(name, initial, rank, min, max)
(initial_matrix = semicolon between rows, comma within rows)
LOWRANKINCREMENTAL <name> <initial_matrix> <rank> <min> <max> model.AddIncrementalLowRankCorrectionMatrixVariable(name, initial, rank, min, max)
(initial_matrix = semicolon between rows, comma within rows)
TIMESERIESVECTOR <name> <longScale> <shortScale> <rank> <min> <max> model.AddTimeSeriesVectorVariable(name, longScale, shortScale, rank, min, max)
TIMESERIESCORRECTIONVECTOR <name> <initial> <longScale> <shortScale> <rank> <min> <max> model.AddTimeSeriesCorrectionVectorVariable(name, initial, longScale, shortScale, rank, min, max)
(initial = comma-separated doubles)
TIMESERIESINCREMENTALVECTOR <name> <initial> <longScale> <shortScale> <rank> <min> <max> model.AddIncrementalTimeSeriesCorrectionVectorVariable(name, initial, longScale, shortScale, rank, min, max)
(initial = comma-separated doubles)
BSPLINEVECTOR <name> <length> <numKnots> <min> <max> model.AddBSplineVectorVariable(name, length, numKnots, min, max)
SPLINEVECTOR <name> <length> <numKnots> <min> <max> model.AddSplineVectorVariable(name, length, numKnots, min, max)
BSPLINECORRECTIONVECTOR <name> <initial> <numKnots> <min> <max> model.AddBSplineCorrectionVectorVariable(name, initial, numKnots, min, max)
(initial = comma-separated doubles)
SPLINECORRECTIONVECTOR <name> <initial> <numKnots> <min> <max> model.AddSplineCorrectionVectorVariable(name, initial, numKnots, min, max)
(initial = comma-separated doubles)
BSPLINEMATRIX <name> <rows> <cols> <knotRows> <knotCols> <min> <max> model.AddBSplineMatrixVariable(name, rows, cols, knotRows, knotCols, min, max)
SPLINEMATRIX <name> <rows> <cols> <knotRows> <knotCols> <min> <max> model.AddSplineMatrixVariable(name, rows, cols, knotRows, knotCols, min, max)
BSPLINECORRECTIONMATRIX <name> <initial_matrix> <knotRows> <knotCols> <min> <max> model.AddBSplineCorrectionMatrixVariable(name, initial_matrix, knotRows, knotCols, min, max)
(initial_matrix = semicolon between rows, comma within rows)
SPLINECORRECTIONMATRIX <name> <initial_matrix> <knotRows> <knotCols> <min> <max> model.AddSplineCorrectionMatrixVariable(name, initial_matrix, knotRows, knotCols, min, max)
(initial_matrix = semicolon between rows, comma within rows)
FOURIERVECTOR <name> <length> <numFreq> <min> <max> model.AddFourierVectorVariable(name, length, numFreq, min, max)
FOURIERMATRIX <name> <rows> <cols> <freqRows> <freqCols> <min> <max> model.AddFourierMatrixVariable(name, rows, cols, freqRows, freqCols, min, max)
FOURIERCORRECTIONVECTOR <name> <initial> <numFreq> <min> <max> model.AddFourierCorrectionVectorVariable(name, initial, numFreq, min, max)
(initial = comma-separated doubles)
FOURIERCORRECTIONMATRIX <name> <initial_matrix> <freqRows> <freqCols> <min> <max> model.AddFourierCorrectionMatrixVariable(name, initial_matrix, freqRows, freqCols, min, max)
(initial_matrix = semicolon between rows, comma within rows)
REGION <name> <vertices> model.AddRegionVariable(name, polygon)
(vertices formatted as x1,y1;x2,y2;...)
SPHERICALREGION <name> <vertices> model.AddSphericalRegionVariable(name, polygon)
(vertices formatted as theta1,phi1;theta2,phi2;...)
DAG <name> node1,...,nodeN [<start>;<end>;<connected>;<dependent1,pred1,pred2;dependent2,pred3,...>] model.AddDAGVariable(name, nodeNames, startNode, endNode, connected, predecessors)
(the options token is optional; an empty field leaves that option unset, and connected is 0 or 1. Example: DAG g S,A,B,T S;T;1;B,A has start S, end T, connected, and B after A.)
TREE <name> node1,...,nodeN [<root>;<dependent1,pred1,pred2;dependent2,pred3,...>] model.AddTreeVariable(name, nodeNames, rootNode, predecessors)
(the options token is optional; an empty root leaves the root free. Example: TREE t hq,east,west,north hq has the root hq.)
PATH <name> <node1,node2,...> <startNode>;<endNode>;<required1,required2,...> model.AddPathVariable(name, nodeNames, startNode, endNode, requiredNodes)
TOPOLOGICALSEQUENCE <name> <task1,task2,...> <dependent1,pred1,pred2;dependent2,pred3,...> model.AddTopologicalSequenceVariable(name, tasks, predecessors)
(predecessor rows separated by ;; within each row, the first name is the dependent task and the rest are its predecessors. Example: tasks A,B,C,D with predecessor list B,A;C,A;D,B,C means B requires A; C requires A; D requires B and C.)
BETARANDOM <name> <alpha> <beta> model.AddBetaRandomVariable(name, alpha, beta)
CAUCHYRANDOM <name> <location> <scale> model.AddCauchyRandomVariable(name, location, scale)
CHISQRANDOM <name> <df> model.AddChiSquareRandomVariable(name, df)
EXPONENTIALRANDOM <name> <scale> model.AddExponentialRandomVariable(name, scale)
GAMMARANDOM <name> <shape> <scale> model.AddGammaRandomVariable(name, shape, scale)
LOGNORMALRANDOM <name> <shape> <scale> model.AddLogNormalRandomVariable(name, shape, scale)
NORMALRANDOM <name> <mean> <sigma> model.AddNormalRandomVariable(name, mean, sigma)
PARETORANDOM <name> <gamma> <loc> <scale> model.AddParetoRandomVariable(name, gamma, loc, scale)
POISSONRANDOM <name> <lambda> model.AddPoissonRandomVariable(name, lambda)
POWERRANDOM <name> <rmin> <rmax> <power> model.AddPowerRandomVariable(name, rmin, rmax, power)
SPHERICALRANDOM <name> <min> <max> model.AddSphericalElevationRandomVariable(name, min, max)
STUDENTTRANDOM <name> <df> model.AddStudentTRandomVariable(name, df)
UNIFORMRANDOM <name> <min> <max> model.AddUniformRandomVariable(name, min, max)
WEIBULLRANDOM <name> <shape> <scale> model.AddWeibullRandomVariable(name, shape, scale)
OUTPUT <name> model.AddOutputVariable(name)
OUTPUTSTATISTIC <name> <statistic> <statisticValue> model.SetOutputStatistic(name, statistic, statisticValue)
OUTPUTVECTOR <name> <n> model.AddOutputVectorVariable(name, n)
OUTPUTMATRIX <name> <rows> <cols> model.AddOutputMatrixVariable(name, rows, cols)
BINARYVECTOR <name> <n> model.AddBinaryVectorVariable(name, n)
BINARYMATRIX <name> <m> <n> model.AddBinaryMatrixVariable(name, m, n)
INTEGERVECTOR <name> <n> <min> <max> model.AddIntegerVectorVariable(name, n, min, max)
INTEGERMATRIX <name> <m> <n> <min> <max> model.AddIntegerMatrixVariable(name, m, n, min, max)
DISCRETEVECTOR <name> <n> <min> <max> <step> model.AddDiscreteVectorVariable(name, n, min, max, step)
DISCRETEMATRIX <name> <m> <n> <min> <max> <step> model.AddDiscreteMatrixVariable(name, m, n, min, max, step)
NDVARIABLE <name> <d1,d2,...> <min> <max> model.AddNDVariable(name, dims, min, max)
(dims = comma-separated integers, for example 3,4,2)
INTEGERNVARIABLE <name> <d1,d2,...> <min> <max> model.AddIntegerNDVariable(name, dims, min, max)
(dims = comma-separated integers)
DISCRETENDVARIABLE <name> <d1,d2,...> <min> <max> <step> model.AddDiscreteNDVariable(name, dims, min, max, step)
(dims = comma-separated integers)
BINARYNDVARIABLE <name> <d1,d2,...> model.AddBinaryNDVariable(name, dims)
(dims = comma-separated integers)
OUTPUTNDVARIABLE <name> <d1,d2,...> model.AddOutputNDVariable(name, dims)
(dims = comma-separated integers)
OBJECTIVE <name> <direction> <expression> <direction>: MIN or MAX model.AddMinimizeObjective(name, expression) (if MIN)
model.AddMaximizeObjective(name, expression) (if MAX)
OBJECTIVEGOAL <name> <min> <max> model.SetObjectiveGoal(name, min, max)
OBJECTIVECONFIDENCE <name> <ctype> <clevel> <epct> (epct is a fraction greater than 0 and less than 1, such as 0.05) model.SetObjectiveConfidence(name, ctype, clevel, epct)
OBJECTIVESTATISTIC <name> <statistic> <statisticValue> model.SetObjectiveStatistic(name, statistic, statisticValue)
CONSTRAINT <name> <expression> model.AddConstraint(name, expression)
EXPRESSION <name> <expression> model.AddExpressionVariable(name, expression)
REPLICATIONS <min> <max> (min ≥ 1, max ≥ min; max of 1 runs without replications) model.SetReplications(min, max)
SERIALREPLICATIONS None model.SetSerialReplications()
PARALLELHINT <npar> model.SetParallelHint(npar)
RANDOMSEED <seed> model.SetRandomSeed(seed)
STOPMILP None model.StopOnSuccessfulMILP()
NOGENERATE None model.SuggestedSolutionsOnly()
STOPCYCLES <cycles> model.SetStopCycles(cycles)
STOPIMPROVEMENT <improvement> <iterations> model.SetStopImprovement(improvement, iterations)
STOPTIME <seconds> model.SetStopTime(seconds)
METRIC <name> <response>;<error>2 model.AddSampleMetric(name, response, error)
SAMPLE <method> model.SetSampleMethod(method)
VARIOGRAM <variogram> model.SetSampleVariogram(variogram)
RDSBINS <name> <distribution> <params>3 model.SetSampleRDSUniform(...)
model.SetSampleRDSNormal(...)
model.SetSampleRDSLogNormal(...)
model.SetSampleRDSBeta(...)
model.SetSampleRDSPoisson(...)
model.SetSampleRDSExponential(...)
model.SetSampleRDSCauchy(...)
model.SetSampleRDSGamma(...)
model.SetSampleRDSChiSquare(...)
model.SetSampleRDSPareto(...)
model.SetSampleRDST(...)
model.SetSampleRDSWeibull(...)
model.SetSampleRDSDiscrete(...)

1 Tuple and geolocation format: tuples and geolocations are one string, with commas between the values of a tuple or coordinate pair and semicolons between tuples or pairs. For example, the four tuples (a,b,c), (d,e,f), (g,h,i) and (j,k,l) are written a,b,c;d,e,f;g,h,i;j,k,l, and geolocations are written lat1,lon1;lat2,lon2.

2 Metric expressions: a semicolon (;) separates responseExpression and errorExpression in the METRIC command, so that the expressions can contain spaces. The semicolon is a separator inside the METRIC command only. Variable, constraint and objective names still must not contain semicolons.

3 Response distribution parameters: distribution is the name of the distribution, and params is a space-separated list of values. For a continuous distribution (UNIFORM, NORMAL, BETA and so on), params begins with nBins, the number of histogram bins, followed by the parameters of the distribution, for example nBins mu sigma for NORMAL. For DISCRETE, params has no nBins; it is the list of bin edges, for example 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 for ten equal bins on [0,1]. The number of bins is one more than the number of edges.

4 Exchangeable group members: a member can be a generated element name with commas, such as m@1,2. The engine splits each group on the commas and then joins a part that starts with a digit to the member before it, because a variable name cannot start with a digit. Thus m@1,1,m@1,2;m@2,1,m@2,2 holds the two groups (m@1,1, m@1,2) and (m@2,1, m@2,2). A comma in a member name must be followed by a digit.

Return

A single integer, the identifier of the new model.

On error, the reply begins with ERROR followed by a description. A statement the parser does not recognize, or one the model rejects, gets ERROR CREATING OPTIMIZATION: type=<identifier> name=<name>.

<modelIdentifier>
Create Solution
Command Format

One line with one parameter, the integer identifier of the model.

CREATESOLUTION <modelIdentifier>
Return

The short form of the solution reply (see § Solution Replies).

When the engine has no solution to offer (the search space is exhausted, a stop criterion was met, or the run was interrupted), the reply is ERROR CANNOT CREATE; REASON = <n>, where <n> is the termination reason code. This is the normal end of a manual loop, not a fault. Any other reply that begins with ERROR is a failure, followed by a description.

Submit Solution
Command Format

Several lines, to submit an evaluated solution:

SUBMITSOLUTION
<modelIdentifier> <solutionIdentifier>
<variableName1> <variableValue1>
...
<variableNameN> <variableValueN>
END
Return

A single integer: the number of iterations the model has completed, including this one. 0 is a valid reply while no iteration is complete.

On error (for example, an invalid solution ID), the reply begins with ERROR followed by a description. Two errors concern the value lines:

<numberCompleted>
Reject Solution
Command Format

One line with two integer parameters, <modelIdentifier> and <solutionIdentifier>, to reject a solution that could not be evaluated.

REJECTSOLUTION <modelIdentifier> <solutionIdentifier>
Return

A single integer: the number of iterations the model has completed, including this one. 0 is a valid reply while no iteration is complete.

On error (for example, an invalid solution ID), the reply begins with ERROR followed by a description.

<numberCompleted>
Predict Solution
Command Format

Several lines, to predict the response of a candidate solution from the internal metamodel without evaluating it:

PREDICTSOLUTION
<modelIdentifier> <solutionIdentifier>
<variableName1> <variableValue1>
...
<variableNameN> <variableValueN>
END
Return

The full form of the solution reply (see § Solution Replies). The first line echoes <modelIdentifier> and <solutionIdentifier> as sent, with -1 for a new empty solution.

On error (for example, an invalid solution ID), the reply begins with ERROR followed by a description.

Evaluate Solution
Command Format

Several lines, to compute the expressions, constraints and objectives of a solution from client-supplied input and output values, without submitting the solution to the engine:

EVALUATESOLUTION
<modelIdentifier> <solutionIdentifier>
<variableName1> <variableValue1>
...
<variableNameN> <variableValueN>
END
Return

The full form of the solution reply (see § Solution Replies). The first line echoes <modelIdentifier> and <solutionIdentifier> as sent, with -1 for a new empty solution.

On error (for example, an invalid solution ID), the reply begins with ERROR followed by a description.

Add Solution
Command Format

Several lines, to add a suggested, required or evaluated solution to a model:

ADDSOLUTION
<modelIdentifier> <solutionIdentifier> <isEvaluated> <ignoreMapping>
<variableName1> <variableValue1>
...
<variableNameN> <variableValueN>
END
Return

One line with the number of solutions evaluated so far, as GetNumberOfCompletedIterations() reports it.

On error (for example, an invalid model ID or a missing required value), the reply begins with ERROR followed by a description.

42
Get Solution
Command Format

One line with two integer parameters, <modelIdentifier> and <solutionIdentifier>, to read everything about one solution.

GETSOLUTION <modelIdentifier> <solutionIdentifier>
Return

The full form of the solution reply (see § Solution Replies).

On error (for example, an invalid solution ID), the reply begins with ERROR followed by a description.

Get Best Solutions
Command Format

One line with two integer parameters: <modelIdentifier> and <limit>, the number of best solutions to return. <limit> is ignored for a multi-objective model, which returns the whole Pareto frontier.

GETBESTSOLUTIONS <modelIdentifier> <limit>
Return

The best solutions, one after the other, each in the full form of the solution reply (see § Solution Replies). A line with three dashes and a 0-based counter precedes each solution, including the first.

On error (for example, an invalid model ID), the reply begins with ERROR followed by a description.

--- 0
<solution 1 output>
--- 1
<solution 2 output>
...
--- <n-1>
<solution N output>
Get All Solutions
Command Format

One line with one parameter, <modelIdentifier>.

GETALLSOLUTIONS <modelIdentifier>
Return

Every evaluated solution, one after the other, each in the full form of the solution reply (see § Solution Replies). A line with three dashes and a 0-based counter precedes each solution, including the first.

On error (for example, an invalid model ID), the reply begins with ERROR followed by a description.

--- 0
<solution 1 output>
--- 1
<solution 2 output>
...
--- <n-1>
<solution N output>
Add All Solutions
Command Format

One line with two integer parameters, <destinationModelIdentifier> and <sourceModelIdentifier>.

ADDALLSOLUTIONS <destinationModelIdentifier> <sourceModelIdentifier>
Return

One line with OK on success.

On error (for example, an invalid model ID), the reply begins with ERROR followed by a description.

OK
Copy Solution
Command Format

One line that copies one solution into a model, the engine-side form of CopySolution. It takes four integer parameters: <destinationModelIdentifier>, <sourceModelIdentifier>, <sourceSolutionIdentifier> (the ID of a solution the source model owns, or -1) and <sourceIteration>, which is used when the solution ID is -1: the iteration number of an evaluated solution of the source model, as GETBESTSOLUTIONS and GETALLSOLUTIONS report it. The destination model owns the copy, and the copy has the same values as the source solution for every variable.

COPYSOLUTION <destinationModelIdentifier> <sourceModelIdentifier> <sourceSolutionIdentifier> <sourceIteration>
Return

The short form of the solution reply (see § Solution Replies) for the new copy. Use the returned solution ID with ADDSOLUTION, PREDICTSOLUTION or EVALUATESOLUTION.

On error (for example, an unknown model or solution), the reply begins with ERROR followed by a description.

Get Names
Command Format

One line with one parameter, <modelIdentifier>.

GETNAMES <modelIdentifier>
Return

A count line, <numberOfInputs> <numberOfOutputs>, followed by one name per line: every input name first, then every output name. A variable name cannot contain whitespace, ; or a newline, so one name per line is unambiguous.

The names are the ones the typed API reports. Most variables appear under the name they were added with. Permutations, containers and special purpose variables expand into their generated element names joined by @. The two lists never overlap: the coordinates that the optimizer sets are inputs, and the values the simulation must write are outputs.

On error (for example, an invalid model ID), the reply begins with ERROR followed by a description.

2 1
x1
x2
result
Delete Model
Command Format

One line with one parameter, <modelIdentifier>.

DELETEMODEL <modelIdentifier>
Return

One line with OK. Deleting an identifier the engine no longer holds is not an error, so a client may delete a model twice. An identifier that is not an integer gets ERROR.

OK
Quit
Command Format

One line with no parameters. The server stops and sends no reply.

QUIT

Worked Example

This example defines a model, requests three solutions, evaluates them and reads the best one back. Lines that begin with > are the client’s input on STDIN, and lines that begin with < are the server’s replies on STDOUT.

> CREATEMODEL
> CONTINUOUS X -10 10
> CONTINUOUS Y -15 15
> OUTPUT Z
> CONSTRAINT C1 X<Y
> CONSTRAINT C2 X+Y>1
> CONSTRAINT C3 X+Y<10
> OBJECTIVE O1 MAX X+Y-Z
> END
< 0
> CREATESOLUTION 0
< 0 0
< 1 1 0 0 1 1 0
< X -2.5
< Y 7.75
> SUBMITSOLUTION
> 0 0
> Z 66
> END
< 1
> CREATESOLUTION 0
< 0 1
< 2 1 0 0 1 1 0
< X 0.5
< Y 0.5
> SUBMITSOLUTION
> 0 1
> Z .5
> END
< 2
> CREATESOLUTION 0
< 0 2
< 3 1 0 0 1 1 0
< X -5.0
< Y 15.0
> SUBMITSOLUTION
> 0 2
> Z 250
> END
< 3
> GETBESTSOLUTIONS 0 1
< --- 0
< 2 1 1 1 1 1 0
< X 0.5
< Y 0.5
< Z 0.5
< O1 0.5
< C1 1.0
< C1;LHS;1 0.5
< C1;RHS;1 0.5
< C2 1.0
< C2;LHS;1 1.0
< C2;RHS;1 1.0
< C3 1.0
< C3;LHS;1 1.0
< C3;RHS;1 10.0
> GETALLSOLUTIONS 0
< --- 0
< 2 1 1 1 1 1 0
< X 0.5
< Y 0.5
< Z 0.5
< O1 0.5
< C1 1.0
< C1;LHS;1 0.5
< C1;RHS;1 0.5
< C2 1.0
< C2;LHS;1 1.0
< C2;RHS;1 1.0
< C3 1.0
< C3;LHS;1 1.0
< C3;RHS;1 10.0
< --- 1
< 1 1 1 1 1 1 0
< X -2.5
< Y 7.75
< Z 66.0
< O1 -60.75
< C1 1.0
< C1;LHS;1 -2.5
< C1;RHS;1 7.75
< C2 1.0
< C2;LHS;1 5.25
< C2;RHS;1 1.0
< C3 1.0
< C3;LHS;1 5.25
< C3;RHS;1 10.0
< --- 2
< 3 1 1 1 1 1 0
< X -5.0
< Y 15.0
< Z 250.0
< O1 -240.0
< C1 1.0
< C1;LHS;1 -5.0
< C1;RHS;1 15.0
< C2 1.0
< C2;LHS;1 10.0
< C2;RHS;1 1.0
< C3 1.0
< C3;LHS;1 10.0
< C3;RHS;1 10.0
> DELETEMODEL 0
< OK
> QUIT

QUIT stops the server and sends no reply, so the example ends there.

Migrating from OptQuest 9

This appendix is for users of OptQuest 9. New users can skip it. The examples are in Java, the language in which the OptQuest 9 API was most used, but the OptQuest 10 mappings apply in all five languages (Java, C#, C++, C and Python).

The OptQuest 10 API has built-in parallel execution, so the client manages no threads or queues, and it follows one pattern in every supported language.

Every OptQuest 9 feature maps to an OptQuest 10 call. In OptQuest 9 the central object was COptQuestOptimization. The client subclassed it, overrode virtual methods to define the model, and evaluated solutions through a dependency-injection pattern. In OptQuest 10 the model is an opaque, immutable OptQuestModel, and callbacks evaluate the solutions.

In OptQuest 9 the client created the objects for decision variables, objectives and constraints, managed their lifetimes, and added them to its COptQuestOptimization subclass. In OptQuest 10 the OptQuestModel creates and owns those objects, and the client refers to them by name.

In OptQuest 9 an objective could receive its value directly from the simulation. In OptQuest 10 an objective is always an expression over input and output variables. To reproduce an OptQuest 9 objective that took a simulation result, add an output variable for the result and make the objective’s expression reference it. This replaces a COptQuestUserControlledObjective tied to a simulation output:

//to be collected from the simulation
myModel.AddOutputVariable("simOutput");

//the expression for the objective is just the output value
myModel.AddMinimizeObjective("objective","simOutput");

The examples below map the OptQuest 9 API to the OptQuest 10 API.

New Optimization

OptQuest 9

class MyOptimization extends COptQuestOptimization {
 //remember to pass into this object a reference
 //to all the variables and objectives
 public void Evaluate(COptQuestSolution sol)
   throws COptQuestException {
    double myVarValue = sol.GetVariableValue(myVar);
    double myOutputValue = //run my simulation;
    sol.SetVariableValue(myOutput, myOutputValue);
 }
}

MyOptimization myOpt = new MyOptimization();

OptQuest 10

OptQuestModel myModel = new OptQuestModel();

Add Decision Variable

OptQuest 9

COptQuestVariable myVar = new COptQuestContinuousVariable(min, max);
myOpt.AddVariable(myVar);

OptQuest 10

myModel.AddContinuousVariable("myVar", min, max);

Add Output Variable

OptQuest 9

COptQuestVariable myOutput = new COptQuestUserControlledVariable();
myOpt.AddVariable(myOutput);

OptQuest 10

myModel.AddOutputVariable("myOutput");

Add Single Objective

OptQuest 9

class MyObjective extends
 COptQuestUserControlledObjective {
 //remember to pass into this object a reference to all the variables and objectives
 protected void calculateObjective(Solution sol)
  throws COptQuestException {
   double myVarValue = sol.GetVariableValue(myVar);
   double myOutputValue = sol.GetVariableValue(myOutput);
   double myObjValue = myVarValue+myOutputValue;
   sol.SetObjectiveValue(myObj, myObjValue);
 }
}
COptQuestSingleObjective myObj = new MyObjective();
myObj.SetMinimize();
myOpt.AddObjective(myObj);

OptQuest 10

myModel.AddMinimizeObjective("myObj", "myVar + myOutput");

Add Multi Objective

OptQuest 9

class MyObjective1 extends COptQuestUserControlledObjective {
 //remember to pass into this object a reference to all the variables and objectives
 protected void calculateObjective(Solution sol)
  throws COptQuestException {
   double myVarValue = sol.GetVariableValue(myVar);
   double myOutputValue = sol.GetVariableValue(myOutput);
   double myObjValue = myVarValue - myOutputValue;
   sol.SetObjectiveValue(myObj1, myObjValue);
 }
}

class MyObjective2 extends
 COptQuestUserControlledObjective {
 //remember to pass into this object a reference to all the variables and objectives
 protected void calculateObjective(Solution sol)
  throws COptQuestException {
   double myVarValue = sol.GetVariableValue(myVar);
   double myOutputValue = sol.GetVariableValue(myOutput);
   double myObjValue = myVarValue / myOutputValue;
   sol.SetObjectiveValue(myObj2, myObjValue);
 }
}

COptQuestSingleObjective myObj1 = new MyObjective1();
myObj1.SetMinimize();
COptQuestSingleObjective myObj2 = new MyObjective2();
myObj2.SetMaximize();
COptQuestFrontierMultiObjective myMultiObj = new COptQuestFrontierMultiObjective();
myMultiObj.AddObjective(myObj1);
myMultiObj.AddObjective(myObj2);
myOpt.AddObjective(myMultiObj);

OptQuest 10

myModel.AddMinimizeObjective("myObj1", "myVar - myOutput");
myModel.AddMaximizeObjective("myObj2", "myVar / myOutput");

Add Constraint

OptQuest 9

COptQuestConstraint myConstraint = new COptQuestLEConstraint(5);
myConstraint.AddVariable(myVar, 1);
myConstraint.AddVariable(myOutput, -3);
myOpt.AddConstraint(myConstraint);

OptQuest 10

myModel.AddConstraint("myConstraint", "myVar - 3 * myOutput <= 5");

Evaluate Solution

OptQuest 9

The evaluation is the Evaluate override of the COptQuestOptimization subclass shown under New Optimization.

OptQuest 10

class MyEvaluator implements IOptQuestEvaluator {
 public boolean Evaluate(OptQuestSolution sol) {
  double myVarValue=sol.GetValue("myVar");
  double myOutputValue = //run simulation here;
  sol.SetValue("myOutput",myOutputValue);
  return true;  //submit this trial; return false to reject it
 }
}

Run Optimization

OptQuest 9

myOpt.SetMaximumIteration(50);
myOpt.Optimize();

OptQuest 10

myModel.Optimize(50, new MyEvaluator());

Get Best Solution

OptQuest 9

COptQuestSolution best = myOpt.GetBestSolution();
double myBestVal = best.GetVariableValue(myVar);
double myBestObj = best.GetObjectiveValue(myObj);

OptQuest 10

OptQuestSolution best = myModel.GetBestSolutions().get(0);
double myBestVal = best.GetValue("myVar");
double myBestObj = best.GetValue("myObj");

Get Pareto Frontier of Solutions

OptQuest 9

for (COptQuestSolution frontier : myOpt.GetParetoFrontier()){
 double myBestObj1 = frontier.GetObjectiveValue(myObj1);
 double myBestObj2 = frontier.GetObjectiveValue(myObj2);
}

OptQuest 10

for (OptQuestSolution frontier : myModel.GetBestSolutions()){
 double myBestObj1 = frontier.GetValue("myObj1");
 double myBestObj2 = frontier.GetValue("myObj2");
}