Package google.research.optimization.v1.mathopt

Índice

BasisProto

Uma caracterização combinatória para uma solução de um programa linear.

O método simplex para resolver programas lineares sempre retorna uma “solução básica viável” que pode ser descrita de forma combinatória por uma base. Uma base atribui um BasisStatusProto para cada variável e restrição linear.

Por exemplo, considere uma forma padrão LP: min c * x s.t. A * x = b x >= 0 que tenha mais variáveis do que restrições e com classificação de linha completa A.

Permita que n seja o número de variáveis e m o número de restrições lineares. Uma base válida para esse problema pode ser construída da seguinte maneira: * Todas as restrições terão o status de base FIXED. * Escolha m variáveis de modo que as colunas de A sejam linearmente independentes e atribuam o status BASIC. * Atribua o status AT_LOWER para as variáveis n - m restantes.

A solução básica para essa base é a solução exclusiva de A * x = b que tem todas as variáveis com status AT_LOWER fixo em seus limites inferiores (todas zero). A solução resultante é chamada de solução básica viável se também atende a x >= 0.

Campos
constraint_status

SparseBasisStatusVector

Status da base de restrição.

Requisitos: * restrict_status.ids é igual a LinearConstraints.ids.

variable_status

SparseBasisStatusVector

Status de base variável.

Requisitos: * restrict_status.ids é igual a VariablesProto.ids.

basic_dual_feasibility

SolutionStatusProto

Esse é um recurso avançado usado pelo MathOpt para caracterizar a viabilidade de soluções de LP abaixo do ideal (as soluções ideais sempre terão o status SOLUTION_STATUS_FEASIBLE).

Para páginas de destino unilateral, deve ser igual ao status de viabilidade da solução dupla associada. Para LPs bilateral, pode ser diferente em alguns casos extremos (por exemplo, soluções incompletas com simplex primária).

Se você estiver fornecendo uma base inicial por ModelSolveParametersProto.initial_basis, esse valor será ignorado. Ele é relevante apenas para a base retornada por SolutionProto.basis.

BasisStatusProto

Status de uma variável/restrição na página de destino.

Enums
BASIS_STATUS_UNSPECIFIED Valor de guarda que não representa status.
BASIS_STATUS_FREE A variável/restrição é sem custo financeiro (não tem limites finitos).
BASIS_STATUS_AT_LOWER_BOUND A variável/restrição está no limite inferior (que precisa ser finito).
BASIS_STATUS_AT_UPPER_BOUND A variável/restrição está no limite superior (que precisa ser finito).
BASIS_STATUS_FIXED_VALUE A variável/restrição tem limites inferiores e superiores finitos idênticos.
BASIS_STATUS_BASIC A variável/restrição é básica.

DualRayProto

Uma direção de melhoria ilimitada para o duplo de uma otimização, problema; equivalente, um certificado de inviabilidade primordial.

Por exemplo, considere o par de programa linear de par duplo primário: (Primal) (Dual) min c * x max b * y s.t. A * x >= b s.t. y * A + r = c x >= 0 y, r >= 0. O raio duplo é o par (y, r) que satisfaz: b * y > 0 y * A + r = 0 y, r >= 0. A adição de um múltiplo positivo de (y, r) a uma solução viável dupla mantém a viabilidade dupla e melhora o objetivo (provando que o duplo é ilimitado). O raio duplo também prova que o problema primário é inviável.

Na mensagem DualRay abaixo, y é dual_values e r éreduce_costs.

Campos
dual_values

SparseDoubleVectorProto

Requisitos: * dual_values.ids são elementos de LinearConstraints.ids. * dual_values.values deve ser finito.

reduced_costs

SparseDoubleVectorProto

Requisitos: * lower_costs.ids são elementos de VariablesProto.ids. * lower_costs.values precisam ser finitos.

DualSolutionProto

Uma solução para o duplo problema de otimização.

Por exemplo, considere o par de programa linear de par duplo primário: (Primal) (Dual) min c * x max b * y s.t. A * x >= b s.t. y * A + r = c x >= 0 y, r >= 0. A solução dupla é o par (y, r). É viável se ele satisfaz as restrições de (Dual) acima.

Na mensagem abaixo, y é dual_values, r éreduce_costs e b * y é um valor objetivo.

Campos
dual_values

SparseDoubleVectorProto

Requisitos: * dual_values.ids são elementos de LinearConstraints.ids. * dual_values.values deve ser finito.

reduced_costs

SparseDoubleVectorProto

Requisitos: * lower_costs.ids são elementos de VariablesProto.ids. * lower_costs.values precisam ser finitos.

feasibility_status

SolutionStatusProto

Status de viabilidade da solução de acordo com o solucionador.

objective_value

double

EmphasisProto

Nível de esforço aplicado a uma tarefa opcional durante a resolução (consulte SolveParametersProto para uso).

A ênfase é usada para configurar um recurso do solucionador da seguinte forma: * Se um solucionador não oferecer suporte ao recurso, somente UNSPECIFIED será sempre válido, qualquer outra configuração normalmente será um erro de argumento inválido (alguns solucionadores também podem aceitar OFF). * Se o solucionador oferecer suporte ao recurso: - Quando definido como UNSPECIFIED, o padrão subjacente será usado. - Quando o recurso não puder ser desativado, OFF retornará um erro. - Se o recurso estiver ativado por padrão, o padrão do solucionador será mapeado para MEDIUM. - Se o recurso for suportado, BAIXO, MÉDIO, ALTO e MUITO ALTO nunca darão um erro e serão mapeadas na melhor correspondência.

Enums
EMPHASIS_UNSPECIFIED
EMPHASIS_OFF
EMPHASIS_LOW
EMPHASIS_MEDIUM
EMPHASIS_HIGH
EMPHASIS_VERY_HIGH

FeasibilityStatusProto

Status de viabilidade do problema conforme reivindicado pelo solucionador (o solucionador não precisa retornar um certificado para a reivindicação).

Enums
FEASIBILITY_STATUS_UNSPECIFIED Valor de guarda que não representa status.
FEASIBILITY_STATUS_UNDETERMINED O solucionador não reivindica um status.
FEASIBILITY_STATUS_FEASIBLE O solucionador afirma que o problema é viável.
FEASIBILITY_STATUS_INFEASIBLE O solucionador afirma que o problema é inviável.

IndicatorConstraintProto

Dados para representar uma restrição de indicador único no formato: variável(indicator_id) = (activate_on_zero ? 0 : 1) ⇒ limite_inferior <= expressão <= limite_superior.

Se uma variável envolvida nessa restrição (o indicador ou que aparece em expression) for excluída, ela será tratada como se estivesse definida como zero. Mais especificamente, a exclusão da variável de indicador significa que a restrição do indicador será vazia se activate_on_zero for falsa, e que será equivalente a uma restrição linear se activate_on_zero for verdadeiro.

Campos
activate_on_zero

bool

Se verdadeira, se a variável do indicador receber o valor 0, a restrição implícita deverá ser mantida. Caso contrário, se a variável do indicador receber o valor 1, a restrição implícita deverá ser mantida.

expression

SparseDoubleVectorProto

Precisa ser uma expressão linear válida em relação ao modelo que o contém: * Todas as condições declaradas em SparseDoubleVectorProto, * Todos os elementos de expression.values precisam ser finitos, * expression.ids são um subconjunto de VariablesProto.ids.

lower_bound

double

Precisa ter um valor em [-inf, inf); não pode ser NaN.

upper_bound

double

Precisa ter um valor em (-inf, inf]; não pode ser NaN.

name

string

As mensagens principais podem ter requisitos de exclusividade neste campo. Por exemplo, consulte ModelProto.indicator_constraints e IndicatorConstraintUpdatesProto.new_constraints.

indicator_id

int64

Um ID correspondente a uma variável binária ou não definido. Se não for definida, a restrição do indicador será ignorada. Se definido, será necessário que: * VariablesProto.integers[indicator_id] = true, * VariablesProto.lower_bounds[indicator_id] >= 0, * VariablesProto.upper_bounds[indicator_id] <= 1. Essas condições não são validadas pelo MathOpt, mas, se não forem satisfeitas, o solucionador retornará um erro ao resolver.

LPAlgorithmProto

Seleciona um algoritmo para resolver programas lineares.

Enums
LP_ALGORITHM_UNSPECIFIED
LP_ALGORITHM_PRIMAL_SIMPLEX O método simplex (primal). Normalmente, pode fornecer soluções primárias e duplas, raios primais/duais em problemas ilimitados primais/duais e uma base.
LP_ALGORITHM_DUAL_SIMPLEX O método simplex duplo. Normalmente, pode fornecer soluções primárias e duplas, raios primais/duais em problemas ilimitados primais/duais e uma base.
LP_ALGORITHM_BARRIER O método de barreira, também comumente chamado de método de ponto interno (IPM, na sigla em inglês). Normalmente, podem oferecer soluções primárias e duplas. Algumas implementações também podem produzir raios em problemas ilimitados/inviáveis. Uma base não é fornecida, a menos que o solucionador subjacente faça "crossover" e termine com simplex.
LP_ALGORITHM_FIRST_ORDER Um algoritmo baseado em um método de primeira ordem. Eles normalmente produzirão soluções primárias e duplas e, potencialmente, também certificados de inviabilidade primária e/ou dupla. Os métodos de primeira ordem normalmente fornecem soluções com menor acurácia, portanto, os usuários devem tomar cuidado ao definir os parâmetros de qualidade da solução (por exemplo, tolerâncias) e validar as soluções.

LimitProto

Quando um Solve() é interrompido antes com juntosReasonProto FEASIBLE ou NO_SOLUTION_FOUND, o limite específico que foi atingido.

Enums
LIMIT_UNSPECIFIED Usado como um valor nulo quando encerramos sem um limite (por exemplo, TERMINATION_REASON_OPTIMAL).
LIMIT_UNDETERMINED O solucionador não expõe qual limite foi atingido.
LIMIT_ITERATION Um algoritmo iterativo parou depois de realizar o número máximo de iterações (por exemplo, iterações simplex ou barreira).
LIMIT_TIME O algoritmo foi interrompido após um tempo de computação especificado pelo usuário.
LIMIT_NODE Um algoritmo de ramificação e vinculação foi interrompido porque analisou um número máximo de nós na árvore correspondente.
LIMIT_SOLUTION O algoritmo parou porque encontrou o número necessário de soluções. Isso é frequentemente usado em MIPs para fazer com que o solucionador retorne a primeira solução viável que encontrar.
LIMIT_MEMORY O algoritmo parou porque ficou sem memória.
LIMIT_CUTOFF O solucionador foi executado com um corte (por exemplo, SolveParameters.cutoff_limit foi definido) no objetivo, indicando que o usuário não queria uma solução pior do que o ponto de corte, e o solucionador concluiu que não havia soluções tão boas quanto o corte. Normalmente, nenhuma outra informação sobre a solução é fornecida.
LIMIT_OBJECTIVE O algoritmo foi interrompido porque encontrou uma solução ou um limite melhor do que o limite definido pelo usuário (consulte SolveParameters.objective_limit e SolveParameters.best_bound_limit).
LIMIT_NORM O algoritmo parou porque a norma de uma iteração ficou muito grande.
LIMIT_INTERRUPTED O algoritmo parou devido a um sinal de interrupção ou a uma solicitação de interrupção do usuário.
LIMIT_SLOW_PROGRESS O algoritmo parou porque não foi possível continuar progredindo em direção à solução.
LIMIT_OTHER

O algoritmo foi interrompido devido a um limite não coberto por nenhuma das opções acima. LIMIT_UNDETERMINED é usado quando o motivo não pode ser determinado, e LIMIT_OTHER é usado quando o motivo é conhecido, mas não se encaixa em nenhuma das alternativas acima.

RescisãoProto.detail pode conter informações adicionais sobre o limite.

LinearConstraintsProto

Conforme usado abaixo, definimos "#linear constraints" = size(LinearConstraintsProto.ids).

Campos
ids[]

int64

Precisa ser não negativo e estritamente crescente. Não é possível usar o valor max(int64).

lower_bounds[]

double

Deve ter comprimento igual a #linear restrições, valores em [-inf, inf).

upper_bounds[]

double

Deve ter comprimento igual a #linear restrições, valores em (-inf, inf].

names[]

string

Se não for definido, serão consideradas todas as strings vazias. Caso contrário, deve ter comprimento igual a #linear restrições.

Todos os nomes não vazios precisam ser distintos.

LinearExpressionProto

Uma representação esparsa de uma expressão linear (uma soma ponderada de variáveis, mais um deslocamento constante).

Campos
ids[]

int64

IDs de variáveis. Precisam ser classificados (em ordem crescente) com todos os elementos distintos.

coefficients[]

double

Precisa ter o mesmo comprimento que os IDs. Os valores precisam ser finitos e podem não ser NaN.

offset

double

Precisa ser finito e pode não ser NaN.

ModelProto

Um problema de otimização. MathOpt suporta: - Variáveis de decisão contínuas e inteiras com limites finitos opcionais. - Objetivos lineares e quadráticos (objetivos únicos ou múltiplos), minimizados ou maximizados. - Vários tipos de restrições, incluindo: * Restrições lineares * Restrições quadráticas * Restrições de cone de segunda ordem * Restrições lógicas > Restrições de SOS1 e SOS2 > Restrições do indicador

Por padrão, as restrições são representadas em mapas "id-to-data". No entanto, representamos as restrições lineares em um formato de “struct-of-arrays” mais eficiente.

Campos
name

string

variables

VariablesProto

objective

ObjectiveProto

O objetivo principal do modelo.

auxiliary_objectives

map<int64, ObjectiveProto>

Objetivos auxiliares para uso em modelos multiobjetivos.

Os IDs de chave do mapa precisam estar no intervalo [0, max(int64)). Cada prioridade e cada nome não vazio precisam ser únicos e também diferentes do objective principal.

linear_constraints

LinearConstraintsProto

linear_constraint_matrix

SparseDoubleMatrixProto

Os coeficientes variáveis das restrições lineares.

Se uma variável envolvida nessa restrição for excluída, ela será tratada como se estivesse definida como zero.

Requisitos: * linear_constraint_matrix.row_ids são elementos de linear_constraints.ids. * matriz_de_restrição_linear.ids_da_coluna são elementos de variables.ids. * As entradas de matriz não especificadas são zero. * matriz_restrição_de_linear.valores devem ser finitos.

quadratic_constraints

map<int64, QuadraticConstraintProto>

Restrições quadráticas no modelo.

second_order_cone_constraints

map<int64, SecondOrderConeConstraintProto>

Restrições de cone de segunda ordem no modelo.

sos1_constraints

map<int64, SosConstraintProto>

As restrições SOS1 no modelo restringem o máximo de um expression ser diferente de zero. As entradas weights opcionais são um detalhe de implementação usado pelo solucionador para convergir mais rapidamente. Em mais detalhes, os solucionadores podem (ou não) usar esses pesos para selecionar decisões de ramificação que produzem nós filhos "equilibrados".

sos2_constraints

map<int64, SosConstraintProto>

Restrições SOS2 no modelo, que restringem que no máximo duas entradas de expression podem ser diferentes de zero, e elas precisam ser adjacentes na ordem. Se nenhum weights for fornecido, essa ordem será a ordem linear na lista de expressions. Se weights forem apresentados, a ordem será considerada em relação a esses valores em ordem crescente.

indicator_constraints

map<int64, IndicatorConstraintProto>

Restrições de indicador no modelo, que impõem que, se uma "variável indicadora" binária for definida como um, então uma "restrição implícita" precisa ser mantida.

ModelSolveParametersProto

Campos
variable_values_filter

SparseVectorFilterProto

Filtro aplicado a todos os contêineres esparsos retornados codificados por variáveis em PrimalSolutionProto e PrimalRayProto (PrimalSolutionProto.variable_values, PrimalRayProto.variable_values).

Requisitos: * filter_ids são elementos de VariablesProto.ids.

dual_values_filter

SparseVectorFilterProto

Filtro aplicado a todos os contêineres esparsos retornados codificados por restrições lineares em DualSolutionProto e DualRay (DualSolutionProto.dual_values, DualRay.dual_values).

Requisitos: * filter_ids são elementos de LinearConstraints.ids.

reduced_costs_filter

SparseVectorFilterProto

Filtro aplicado a todos os contêineres esparsos retornados codificados por variáveis em DualSolutionProto e DualRay (DualSolutionProto.reduced_costs, DualRay.reduced_costs).

Requisitos: * filter_ids são elementos de VariablesProto.ids.

initial_basis

BasisProto

Base inicial opcional para solucionadores de LP simplex de inicialização a quente. Se definido, espera-se que ele seja válido de acordo com ValidateBasis em validators/solution_validator.h para o ModelSummary atual.

solution_hints[]

SolutionHintProto

Dicas de solução opcionais. Se o solucionador aceitar apenas uma dica, a primeira será usada.

branching_priorities

SparseInt32VectorProto

Prioridades de ramificação opcionais. As variáveis com valores mais altos serão ramificadas primeiro. As variáveis com prioridades não definidas recebem a prioridade padrão do solucionador (geralmente zero).

Requisitos: * branching_priorities.values deve ser finito. * branching_priorities.ids precisa ser elementos de VariablesProto.ids.

ObjectiveBoundsProto

Limites para o valor do objetivo ideal.

Campos
primal_bound

double

O solucionador afirma que o valor ideal é igual ou melhor (menor para minimização e maior para maximização) do que o limite_primal até a tolerância de viabilidade primária do solucionador (veja o aviso abaixo): * primal_bound é trivial (+inf para minimização e -inf maximização) quando o solucionador não alega ter esse limite. * primal_bound pode estar mais próximo do valor ideal do que o objetivo da melhor solução primária viável. Em particular, primal_bound pode não ser trivial mesmo quando nenhuma solução primária viável é retornada. Aviso: a afirmação precisa é que existe uma solução primária que: * é numericamente viável (ou seja, viável até a tolerância do solucionador) e * tem um valor objetivo primal_bound. Essa solução numericamente viável pode ser ligeiramente inviável, caso em que primal_bound pode ser estritamente melhor do que o valor ideal. Converter uma tolerância de viabilidade primal para uma tolerância em primal_bound não é trivial, especialmente quando a tolerância de viabilidade é relativamente grande (por exemplo, ao resolver com PDLP).

dual_bound

double

O solucionador afirma que o valor ideal é igual ou pior (maior para minimização e menor para maximização) do que o limite_dupla até a tolerância de viabilidade dupla dos solucionadores (veja o aviso abaixo): * limite_dupla é trivial (-inf para minimização e +inf maximização) quando o solucionador afirma não ter esse limite. Da mesma forma que em primal_bound, isso pode acontecer com alguns solucionadores mesmo quando retornar ideal. Os solucionadores de MIP normalmente informam um limite, mesmo que ele seja impreciso. * para problemas contínuos, double_bound pode estar mais próximo do valor ideal do que o objetivo da melhor solução dupla viável. Para o MIP, um dos primeiros valores não triviais para dual_bound é frequentemente o valor ideal do relaxamento do LP do MIP. * O limite_bativo precisa ser melhor (menor para minimização e maior para maximização) do que o limite_primal até as tolerâncias do solucionador (consulte o aviso abaixo). Aviso: * para problemas contínuos, a afirmação precisa é de que existe uma solução dupla que: * é numericamente viável (ou seja, viável até a tolerância de solucionadores) e * tem um valor objetivo dual_bound. Essa solução numericamente viável pode ser ligeiramente inviável, caso em que "double_bound" pode ser estritamente pior do que o valor ideal e primal_bound. Semelhante ao caso primário, converter uma tolerância de viabilidade dupla em uma tolerância em dual_bound não é trivial, especialmente quando a tolerância de viabilidade é relativamente grande. No entanto, alguns solucionadores fornecem uma versão corrigida de dual_bound, que pode ser numericamente mais segura. Essa versão corrigida pode ser acessada pela saída específica do solucionador (por exemplo, para PDLP, pdlp_output.convergence_information. previstoed_dual_objective). * Para solucionadores de MIP, dual_bound pode ser associado a uma solução dupla para algum relaxamento contínuo (por exemplo, relaxamento de LP), mas geralmente é uma consequência complexa da execução de solucionadores e, em geral, é mais impreciso do que os limites relatados por solucionadores de LP.

ObjectiveProto

Campos
maximize

bool

falso é minimizar, verdadeiro é maximizar

offset

double

Precisa ser finito e não NaN.

linear_coefficients

SparseDoubleVectorProto

Termos de ObjectiveProto que são lineares nas variáveis de decisão.

Requisitos: * linear_coeficientes.ids são elementos de VariablesProto.ids. * VariablesProto não especificado corresponde a zero. * coeficientes_linear.valores devem ser todos finitos. * linear_coeficientes.values pode ser zero, mas isso só desperdiça espaço.

quadratic_coefficients

SparseDoubleMatrixProto

Termos objetivos que são quadráticos nas variáveis de decisão.

Requisitos além daqueles nas mensagens SparseDoubleMatrixProto: * Cada elemento de quadratic_coefficients.row_ids e cada elemento de quadratic_coefficients.column_ids precisa ser um elemento de VariablesProto.ids. * A matriz precisa ser triangular superior: para cada i, coeficientes_quadráticos.ids_da_linha[i] <= coeficientes_quadráticos.ids_coluna[i].

Observações: * Termos que não são armazenados explicitamente têm coeficiente zero. * Os elementos de quadratic_coeficientes.coeficientes podem ser zero, mas isso só desperdiça espaço.

name

string

As mensagens principais podem ter requisitos de exclusividade neste campo. Por exemplo, consulte ModelProto.objectives e AuxiliaryObjectivesUpdatesProto.new_objectives.

priority

int64

Para problemas com vários objetivos, a prioridade desse objetivo em relação aos outros (menor é mais importante). Esse valor não pode ser negativo. Além disso, cada prioridade objetiva do modelo precisa ser distinta no momento da resolução. Essa condição não é validada no nível proto, então os modelos podem ter objetivos temporariamente com a mesma prioridade.

PrimalRayProto

Uma direção de melhoria ilimitada para um problema de otimização; equivalente, um certificado de inviabilidade para o duplo do problema de otimização.

Por exemplo, considere um programa linear simples: min c * x s.t. A * x >= b x >= 0 Um raio primal é um x que satisfaz: c * x < 0 A * x >= 0 x >= 0. Considerando uma solução viável, qualquer objetivo múltiplo positivo do raio primário ainda é um valor melhor e essa solução. Um raio primário também prova que o problema de otimização dupla é inviável.

Na mensagem PrimalRay abaixo, "variable_values" é x.

Campos
variable_values

SparseDoubleVectorProto

Requisitos: * variable_values.ids são elementos de VariablesProto.ids. * variáveis_values.values precisam ser finitos.

PrimalSolutionProto

Uma solução para um problema de otimização.

Por exemplo, considere um programa linear simples: min c * x s.t. A * x >= b x >= 0. Uma solução primaria é atribuir valores a x. É viável se satisfizer A * x >= b e x >= 0 a partir de cima. Na mensagem PrimalSolutionProto abaixo, "variable_values" é x e "object_value" é c * x.

Campos
variable_values

SparseDoubleVectorProto

Requisitos: * variable_values.ids são elementos de VariablesProto.ids. * variáveis_values.values precisam ser finitos.

objective_value

double

Valor do objetivo calculado pelo solucionador. Não pode ser infinito ou NaN.

auxiliary_objective_values

map<int64, double>

Valores de objetivos auxiliares calculados pelo solucionador. As chaves precisam ser IDs de objetivos auxiliares válidos. Os valores não podem ser infinitos ou NaN.

feasibility_status

SolutionStatusProto

Status de viabilidade da solução de acordo com o solucionador.

ProblemStatusProto

Status de viabilidade do problema primal e seu duplo (ou duplo de um relaxamento contínuo), conforme reivindicado pelo solucionador. O solucionador não precisa retornar um certificado para a declaração. Por exemplo, o solucionador pode reivindicar viabilidade primária sem retornar uma solução primeira viável. Esse status combinado fornece uma descrição abrangente das afirmações de um solucionador sobre a viabilidade e a infinidade de limites do problema resolvido. Por exemplo:

  • um status viável para problemas primários e duplos indica que a primária é viável e limitada e provavelmente tem uma solução ideal (garantida para problemas sem restrições não lineares).
  • um status primeiramente viável e um status inviável duplo indicam que o problema primário é ilimitado (ou seja, tem soluções arbitrariamente boas).

Um status duplo inviável por si só (ou seja, acompanhado por um status primal indeterminado) não implica que o problema primário é ilimitado, já que os dois problemas podem ser inviáveis. Além disso, embora um status inicial e duplo viável possa implicar a existência de uma solução ideal, isso não garante que o solucionador realmente encontrou essa solução ideal.

Campos
primal_status

FeasibilityStatusProto

Status do problema primário.

dual_status

FeasibilityStatusProto

Status para o problema duplo (ou para o duplo relaxamento contínuo).

primal_or_dual_infeasible

bool

Se verdadeiro, o solucionador afirma que o problema primário ou duplo é inviável, mas não sabe qual (ou se ambos são inviáveis). Pode ser verdadeiro apenas quando primal_problem_status = dual_problem_status = kUndeterminado. Essa informação extra muitas vezes é necessária quando o pré-processamento determina que não há uma solução ideal para o problema, mas não é possível determinar se a causa é inviabilidade, delimitação ou ambos.

QuadraticConstraintProto

Uma única restrição quadrática da forma: lb <= sum{linear_terms} + sum{quadratic_terms} <= ub.

Se uma variável envolvida nessa restrição for excluída, ela será tratada como se estivesse definida como zero.

Campos
linear_terms

SparseDoubleVectorProto

Termos que são lineares nas variáveis de decisão.

Além dos requisitos para mensagens de SparseDoubleVectorProto, exigimos que: * linear_terms.ids são elementos de VariablesProto.ids. * linear_terms.values deve ser todos finitos e não-NaN.

Observações: * Os IDs de variáveis omitidos têm um coeficiente correspondente de zero. * linear_terms.values pode ser zero, mas isso apenas desperdiça espaço.

quadratic_terms

SparseDoubleMatrixProto

Termos quadráticos nas variáveis de decisão.

Além dos requisitos nas mensagens de SparseDoubleMatrixProto, exigimos que: * Cada elemento de quadratic_terms.row_ids e cada elemento de quadratic_terms.column_ids deve ser um elemento de VariablesProto.ids. * A matriz precisa ser triangular superior: para cada i, quadratic_terms.row_ids[i] <= quadratic_terms.column_ids[i].

Observações: * Termos que não são armazenados explicitamente têm coeficiente zero. * Os elementos de quadratic_terms.coeficientes podem ser zero, mas isso só desperdiça espaço.

lower_bound

double

Precisa ter um valor em [-inf, inf) e ser menor ou igual a upper_bound.

upper_bound

double

Precisa ter um valor em (-inf, inf] e ser maior ou igual a lower_bound.

name

string

As mensagens principais podem ter requisitos de exclusividade neste campo. Por exemplo, consulte ModelProto.quadratic_constraints e QuadraticConstraintUpdatesProto.new_constraints.

SecondOrderConeConstraintProto

Uma única restrição de cone de segunda ordem do formulário:

||arguments_to_norm||_2 <= upper_bound,

em que upper_bound e cada elemento de arguments_to_norm são expressões lineares.

Se uma variável envolvida nessa restrição for excluída, ela será tratada como se estivesse definida como zero.

Campos
upper_bound

LinearExpressionProto

arguments_to_norm[]

LinearExpressionProto

name

string

As mensagens principais podem ter requisitos de exclusividade neste campo. Por exemplo, consulte ModelProto.second_order_cone_constraints e SecondOrderConeConstraintUpdatesProto.new_constraints.

SolutionHintProto

Uma sugestão de solução inicial para o solucionador.

Os solucionadores de MIP geralmente querem apenas informações primárias (variable_values), enquanto os solucionadores de LP querem informações primárias e duplas (dual_values).

Muitos solucionadores de MIP podem trabalhar com: (1) soluções parciais que não especificam todas as variáveis ou (2) soluções inviáveis. Nesses casos, os solucionadores normalmente resolvem um sub-MIP para concluir/corrigir a dica.

A forma como a dica é usada pelo solucionador depende muito do solucionador, do tipo de problema e do algoritmo usado. A maneira mais confiável de garantir que sua dica tenha efeito é ler os registros dos solucionadores subjacentes com e sem a dica.

Os solucionadores de LP baseados em simplex normalmente preferem uma base inicial a uma dica de solução. Caso contrário, eles precisam fazer um crossover para converter a dica em uma solução básica viável.

Campos
variable_values

SparseDoubleVectorProto

Uma atribuição possivelmente parcial de valores para as variáveis primitivas do problema. Os requisitos independentes do solucionador para esta submensagem são: * variables_values.ids são elementos de VariablesProto.ids. * variáveis_values.values precisam ser finitos.

dual_values

SparseDoubleVectorProto

Uma atribuição (possivelmente parcial) de valores às restrições lineares do problema.

Requisitos: * dual_values.ids são elementos de LinearConstraintsProto.ids. * dual_values.values deve ser finito.

SolutionProto

O que está incluído em uma solução depende do tipo de problema e do solucionador. O padrão comum atual é 1. Os solucionadores de MIP retornam apenas uma solução primária. 2. Os solucionadores de LP Simplex geralmente retornam uma base e as soluções primária e dupla associadas a ela. 3. Outros solucionadores contínuos geralmente retornam uma solução primária e uma solução dupla que estão conectadas em uma forma dependente do solucionador.

Requisitos: * pelo menos um campo precisa ser definido. Uma solução não pode ficar vazia.

Campos
primal_solution

PrimalSolutionProto

dual_solution

DualSolutionProto

basis

BasisProto

SolutionStatusProto

Viabilidade de uma solução primal ou dupla, conforme declarado pelo solucionador.

Enums
SOLUTION_STATUS_UNSPECIFIED Valor de guarda que não representa status.
SOLUTION_STATUS_UNDETERMINED O solucionador não declara um status de viabilidade.
SOLUTION_STATUS_FEASIBLE O solucionador afirma que a solução é viável.
SOLUTION_STATUS_INFEASIBLE O solucionador afirma que a solução é inviável.

SolveParametersProto

Parâmetros para controlar uma única solução.

Contém os parâmetros comuns a todos os solucionadores (por exemplo, time_limit) e parâmetros para um solucionador específico (por exemplo, gscip). Se um valor for definido no campo comum e específico do solucionador, a configuração específica do solucionador será usada.

Os parâmetros comuns que são opcionais e não definidos ou um tipo enumerado com valor não especificado indicam que o padrão do solucionador é usado.

Os parâmetros específicos do solucionador para solucionadores diferentes do que está em uso são ignorados.

Os parâmetros que dependem do modelo (por exemplo, a prioridade de ramificação é definida para cada variável) são transmitidos em ModelSolveParametersProto.

Campos
time_limit

Duration

O tempo máximo que um solucionador deve gastar no problema (ou infinito, se não for definido).

Este valor não é um limite fixo. O tempo de solução pode exceder um pouco esse valor. Esse parâmetro sempre é transmitido para o solucionador. O padrão do solucionador não é usado.

enable_output

bool

Ativa a impressão dos rastros de implementação do solucionador. A localização desses traces depende do solucionador. Para SCIP e Gurobi, esses serão os fluxos de saída padrão. Para Glop e CP-SAT, LOG(INFO).

Se o solucionador oferecer suporte ao callback de mensagem e o usuário registrar um callback para ela, esse valor de parâmetro será ignorado e nenhum rastro será exibido.

lp_algorithm

LPAlgorithmProto

O algoritmo para resolver um programa linear. Se LP_ALGORITHM_UNSPECIFIED, use o algoritmo padrão do solucionador.

Para problemas que não são programas lineares, mas em que a programação linear é uma sub-rotina, os solucionadores podem usar esse valor. Por exemplo, os solucionadores de MIP normalmente o usam apenas para a solução de LP raiz (senão, o simplex duplo será usado).

presolve

EmphasisProto

Esforça-se para simplificar o problema antes de iniciar o algoritmo principal ou o nível de esforço padrão do solucionador, se FALSE_UNSPECIFIED.

cuts

EmphasisProto

Esforço para obter um relaxamento de LP mais forte (somente MIP) ou o nível de esforço padrão do solucionador se FALSE_UNSPECIFIED.

OBSERVAÇÃO: desativar cortes pode impedir que os callbacks tenham a chance de adicionar cortes em MIP_NODE. Esse comportamento é específico do solucionador.

heuristics

EmphasisProto

Esforço para encontrar soluções viáveis além das encontradas no procedimento de pesquisa completo (somente MIP) ou no nível de esforço padrão do solucionador se FALSE_UNSPECIFIED.

scaling

EmphasisProto

Esforço para redimensionar o problema a fim de melhorar a estabilidade numérica ou o nível de esforço padrão do solucionador se FALSE_UNSPECIFIED.

iteration_limit

int64

Limite nas iterações do algoritmo subjacente (por exemplo, tabelas dinâmicas simples). O comportamento específico depende do solucionador e do algoritmo usado, mas muitas vezes pode fornecer um limite de solução determinístico (pode ser necessária uma configuração adicional, por exemplo, uma linha de execução).

Geralmente suportado por solucionadores de LP, QP e MIP, mas para solucionadores MIP veja também node_limit.

node_limit

int64

Limite no número de subproblemas resolvidos na pesquisa enumerada (por exemplo, ramificação e limite). Para muitos solucionadores, isso pode ser usado para limitar de maneira determinista a computação (pode ser necessária uma configuração adicional, por exemplo, uma linha de execução).

Normalmente, para solucionadores de MIP, consulte também iteration_limit.

cutoff_limit

double

O solucionador interrompe antecipadamente se consegue provar que não há soluções primárias pelo menos tão boas quanto o corte.

Em uma parada antecipada, o solucionador retorna o motivo da rescisão NO_SOLUTION_FOUND e tem o limite de CUTOFF e não precisa fornecer informações adicionais sobre a solução. Não tem efeito sobre o valor de retorno se não houver parada antecipada.

Recomenda-se usar uma tolerância se você quiser que soluções com objetivo exatamente igual ao limite sejam retornadas.

Para obter mais detalhes e uma comparação com best_bound_limit, consulte o guia do usuário.

objective_limit

double

O solucionador interrompe o processo assim que encontra uma solução pelo menos tão boa, com motivo de encerramento FÁCIL e limite OBJETIVO.

best_bound_limit

double

O solucionador interrompe o processo assim que consegue comprovar que o melhor limite é pelo menos tão bom, com o motivo da rescisão FEASIBLE ou NO_SOLUTION_FOUND e limite OBJETIVO.

Consulte o guia do usuário para obter mais detalhes e uma comparação com cutoff_limit.

solution_limit

int32

O solucionador interrompe logo após encontrar essas muitas soluções viáveis, com o motivo da rescisão FÁCIL e limitar a SOLUÇÃO. Precisa ser maior do que zero se definido. Em geral, esse método é usado para que o solucionador pare na primeira solução viável encontrada. Não há garantia sobre o valor objetivo de nenhuma das soluções retornadas.

Os solucionadores não costumam retornar mais soluções do que o limite da solução, mas isso não é aplicado pelo MathOpt. Consulte também b/214041169.

No momento, compatível com Gurobi e SCIP e apenas para CP-SAT com valor 1.

threads

int32

Se definido, precisa ser >= 1.

random_seed

int32

Semente para o gerador de números pseudoaleatórios no solucionador. Todos os solucionadores usam números pseudoaleatórios para selecionar itens como perturbação no algoritmo LP, regras de tie-break e correções heurísticas. Fazer isso pode ter um impacto perceptível no comportamento do solucionador.

Embora todos os solucionadores tenham um conceito de sementes, os valores válidos dependem do solucionador real. - Gurobi: [0:GRB_MAXINT] (na versão Gurobi 9.0 é 2x10^9). – GSCIP: [0:2147483647] (que é MAX_INT, kint32max ou 2^31-1). - GLOP: [0:2147483647] (o mesmo que acima). Em todos os casos, o solucionador receberá um valor igual a: MAX(0, MIN(MAX_VALID_VALUE_FOR_SOLVER, random_seed)).

absolute_gap_tolerance

double

Uma tolerância de otimização absoluta (principalmente) para solucionadores de MIP.

O GAP absoluto é o valor absoluto da diferença entre: * o valor objetivo da melhor solução viável encontrada, * o limite duplo produzido pela pesquisa. O solucionador pode parar assim que o GAP absoluto atingir o valor máximo deAbsolute_gap_tolerant (quando definido) e retornar TERMINATION_REASON_OPTIMAL.

Precisa ser >= 0, se definido.

Consulte também relative_gap_Tolerância.

relative_gap_tolerance

double

Uma tolerância de otimização relativa (principalmente) para solucionadores de MIP.

O GAP relativo é uma versão normalizada do GAP absoluto (definido em equals_gap_tolerante), em que a normalização é dependente do solucionador, por exemplo, o GAP absoluto dividido pelo valor objetivo da melhor solução viável encontrada.

O solucionador poderá parar assim que o GAP relativo estiver no máximo relative_gap_tolerant (quando definido) e retornar TERMINATION_REASON_OPTIMAL.

Precisa ser >= 0, se definido.

Consulte tambémAbsolute_gap_ Equipe.

solution_pool_size

int32

Mantenha até solution_pool_size soluções durante a pesquisa. O pool de soluções geralmente tem duas funções: (1) para solucionadores que podem retornar mais de uma solução, isso limita quantas soluções serão retornadas. (2) Alguns solucionadores podem executar heurísticas usando soluções do conjunto. Por isso, alterar esse valor pode afetar o caminho do algoritmo. Forçar o solucionador a preencher o conjunto de soluções, por exemplo, com as "n melhores soluções", exige mais configuração específica do solucionador.

SolveResultProto

O contrato de quando soluções/raios primitivos/duais/raios são complexos. consulte terminais_reasons.md para uma descrição completa.

Até que um contrato exato seja finalizado, é mais seguro simplesmente verificar se uma solução/raio está presente em vez de confiar no motivo da rescisão.

Campos
termination

TerminationProto

O motivo pelo qual o solucionador parou.

solutions[]

SolutionProto

O contrato geral para a ordem das soluções que futuros solucionadores de problemas implementarão é ordenar por: 1. As soluções com uma solução primária viável, ordenadas pelo melhor objetivo primário primeiro. 2. As soluções com uma solução duplamente viável, ordenada pelo melhor objetivo duplo (objetivo duplo desconhecido é pior) 3. Todas as soluções restantes podem ser retornadas em qualquer ordem.

primal_rays[]

PrimalRayProto

Rotas de melhoria primária ilimitada ou, equivalente, certificados de inviabilidade dupla. Normalmente fornecido para RescisãoReasonProtos UNBOUNDED e DUAL_INFEASIBLE

dual_rays[]

DualRayProto

Rotas de certificados de melhoria dupla ilimitada, ou, equivalente, de certificados de inviabilidade primárias. Normalmente fornecido para RescisãoReasonProto INFEASIBLE.

solve_stats

SolveStatsProto

Estatísticas do processo de solução, por exemplo, tempo de execução, iterações.

SolveStatsProto

Campos
solve_time

Duration

O tempo decorrido decorrido, conforme medido por math_opt, é aproximadamente o tempo dentro de Solver::Solve(). Observação: isso não inclui o trabalho feito na criação do modelo.

problem_status

ProblemStatusProto

Status de viabilidade para problemas primários e duplos.

simplex_iterations

int64

barrier_iterations

int64

first_order_iterations

int64

node_count

int64

SolverTypeProto

Os solucionadores com suporte de MathOpt.

Enums
SOLVER_TYPE_UNSPECIFIED
SOLVER_TYPE_GSCIP

Resolver o solucionador de programas de números inteiros de restrição (SCIP, na sigla em inglês) (terceiros).

Oferece suporte a problemas quadráticos de números inteiros não convexos com LP, MIP e números inteiros não convexos. No entanto, nenhum dado duplo para LPs é retornado. Prefira GLOP para LPs.

SOLVER_TYPE_GUROBI

Solucionador Gurobi (terceiros).

Oferece suporte a problemas quadráticos de números inteiros não convexos com LP, MIP e números inteiros não convexos. Geralmente a opção mais rápida, mas com licenciamento especial.

SOLVER_TYPE_GLOP

o solucionador Glop do Google.

Dá suporte ao LP com métodos primários e duplos simplex.

SOLVER_TYPE_CP_SAT

o solucionador CP-SAT do Google.

Compatível com problemas em que todas as variáveis são inteiras e limitadas (ou implícitas após a resolução). Suporte experimental para redimensionar e discretizar problemas com variáveis contínuas.

SOLVER_TYPE_PDLP

Solucionador de PDLP do Google.

Compatível com objetivos quadráticos diagonais de LP e convexos. Usa métodos de primeira ordem em vez de simplex. Pode resolver problemas muito grandes.

SOLVER_TYPE_GLPK

GNU Linear Programming Kit (GLPK) (terceiros).

Dá suporte a MIP e LP.

Segurança de encadeamento: o GLPK usa armazenamento local de encadeamento para alocações de memória. Como consequência, as instâncias do solucionador devem ser destruídas no mesmo thread em que são criadas, ou o GLPK falhará. Não há problema em chamar Solver::Solve() de outra linha de execução diferente daquela usada para criar o Solver, mas isso não é documentado pelo GLPK e deve ser evitado.

Ao resolver um LP com o presolver, uma solução (e os raios não vinculados) só são retornadas se uma solução ideal tiver sido encontrada. Caso contrário, nada será retornado. Consulte a página glpk-5.0/doc/glpk.pdf 40 disponível em glpk-5.0.tar.gz para obter detalhes.

SOLVER_TYPE_OSQP

O solucionador de operadores de divisão do programa quadrático (OSQP, na sigla em inglês) (terceiros).

Suporta problemas contínuos com restrições lineares e objetivos quadráticos lineares ou convexos. Usa um método de primeira ordem.

SOLVER_TYPE_ECOS

O solucionador cônico incorporado (ECOS, na sigla em inglês).

Suporta problemas de LP e SOCP. Usa métodos de ponto interno (barreira).

SOLVER_TYPE_SCS

O Solucionador de Cônicas de Divisão (SCS) (terceiros).

Suporta problemas de LP e SOCP. Usa um método de primeira ordem.

SOLVER_TYPE_HIGHS

O Solucionador de HiGHS (terceiros).

Suporta problemas de LP e MIP (os QPs convexos não são implementados).

SOLVER_TYPE_SANTORINI

Implementação de referência de MathOpt de um solucionador MIP.

Lento/não recomendado para produção. Não é um solucionador LP (nenhuma informação dupla é retornada).

SosConstraintProto

Dados para representar uma única restrição de SOS1 ou SOS2.

Se uma variável envolvida nessa restrição for excluída, ela será tratada como se estivesse definida como zero.

Campos
expressions[]

LinearExpressionProto

As expressões sobre as quais aplicar a restrição SOS: * SOS1: no máximo, um elemento assume um valor diferente de zero. * SOS2: no máximo, dois elementos recebem valores diferentes de zero e precisam ser adjacentes na ordem repetida.

weights[]

double

Vazio ou de igual comprimento às expressões. Se estiver vazio, as ponderações padrão serão 1, 2, ... Se estiver presente, as entradas devem ser exclusivas.

name

string

As mensagens mãe podem ter requisitos de exclusividade neste campo. Por exemplo, consulte ModelProto.sos1_constraints e SosConstraintUpdatesProto.new_constraints.

SparseBasisStatusVector

Uma representação esparsa de um vetor de status básicos.

Campos
ids[]

int64

Precisam ser classificados (em ordem crescente) com todos os elementos distintos.

values[]

BasisStatusProto

Precisa ter o mesmo comprimento que os IDs.

SparseDoubleMatrixProto

Uma representação esparsa de uma matriz de duplos.

A matriz é armazenada como triplos de ID de linha, ID de coluna e coeficiente. Esses três vetores devem ter o mesmo comprimento. Para todos i, a tupla (row_ids[i], column_ids[i]) deve ser distinta. As entradas precisam estar na ordem maior na linha.

Campos
row_ids[]

int64

column_ids[]

int64

coefficients[]

double

Pode não conter NaN.

SparseDoubleVectorProto

Uma representação esparsa de um vetor de duplos.

Campos
ids[]

int64

Precisam ser classificados (em ordem crescente) com todos os elementos distintos.

values[]

double

Precisa ter o mesmo comprimento que os IDs. Pode não conter NaN.

SparseInt32VectorProto

Uma representação esparsa de um vetor de ints.

Campos
ids[]

int64

Precisa ser classificado (em ordem crescente) com todos os elementos distintos.

values[]

int32

Precisa ter o mesmo comprimento que os IDs.

SparseVectorFilterProto

Essa mensagem permite consultar/definir partes específicas de um SparseXxxxVector. O comportamento padrão é não filtrar nada. Um uso comum é consultar apenas partes de soluções (apenas valores diferentes de zero e/ou apenas um conjunto de valores de variáveis escolhidos manualmente).

Campos
skip_zero_values

bool

Para SparseBoolVectorProto, "zero" é false.

filter_by_ids

bool

Quando verdadeiro, retorna somente os valores correspondentes aos IDs listados em filter_ids.

filtered_ids[]

int64

A lista de IDs a serem usados quando filter_by_ids for verdadeiro. Precisa estar em branco quando filter_by_ids for falso. OBSERVAÇÃO: se estiver vazio e filter_by_ids for verdadeiro, você estará dizendo que não deseja receber nenhuma informação no resultado.

TerminationProto

Todas as informações sobre o motivo pelo qual uma chamada para Solve() foi encerrada.

Campos
reason

TerminationReasonProto

Para mais informações no limit quando o valor for TERMINATION_REASON_FEASIBLE ou TERMINATION_REASON_NO_SOLUTION_FOUND, consulte limit para mais detalhes.

limit

LimitProto

É LIMIT_UNSPECIFIED, a menos que o motivo seja TERMINATION_REASON_FEASIBLE ou TERMINATION_REASON_NO_SOLUTION_FOUND. Nem todos os solucionadores podem determinar sempre o limite que causou o encerramento. LIMIT_UNDETERMINED é usado quando a causa não pode ser determinada.

detail

string

Outras informações, normalmente específicas do solucionador, sobre a rescisão.

problem_status

ProblemStatusProto

Status de viabilidade para problemas primários e duplos. Desde 18 de julho de 2023, essa mensagem pode não estar disponível. Se não definido, problem_status pode ser encontrado em SolveResultProto.solve_stats.

objective_bounds

ObjectiveBoundsProto

Limites para o valor do objetivo ideal. Desde 18 de julho de 2023, essa mensagem pode não estar disponível. Se ausente, "object_bounds.primal_bound" pode ser encontrado em SolveResultProto.solve.stats.best_primal_bound e goal_bounds.dual_bound pode ser encontrado em SolveResultProto.solve.stats.best_dual_bound

TerminationReasonProto

O motivo pelo qual uma chamada para Solve() é encerrada.

Enums
TERMINATION_REASON_UNSPECIFIED
TERMINATION_REASON_OPTIMAL Foi encontrada uma solução comprovadamente ideal (até tolerâncias numéricas).
TERMINATION_REASON_INFEASIBLE O problema primário não tem soluções viáveis.
TERMINATION_REASON_UNBOUNDED O problema primário é viável e arbitrariamente boas soluções podem ser encontradas ao longo de um raio primário.
TERMINATION_REASON_INFEASIBLE_OR_UNBOUNDED O problema primário é inviável ou ilimitado. Mais detalhes sobre o status do problema podem estar disponíveis em resolve_stats.problem_status. O status ilimitado de Gurobi pode ser mapeado aqui.
TERMINATION_REASON_IMPRECISE

O problema foi resolvido para um dos critérios acima (ideal, inviável, ilimitado ou inviável ou ilimitado), mas uma ou mais tolerâncias não foram atendidas. Alguns raios/soluções primitivas/duais estão presentes, mas serão ligeiramente inviáveis ou (se o problema for quase ideal), podem ser uma lacuna entre o melhor objetivo da solução e o melhor limite do objetivo.

Os usuários ainda podem consultar soluções/raios primários/duais e estatísticas de solução, mas são responsáveis por lidar com a imprecisão numérica.

TERMINATION_REASON_FEASIBLE O otimizador atingiu algum tipo de limite e uma solução primeira viável é retornada. Consulte SolveResultProto.limit_detail para obter uma descrição detalhada do tipo de limite que foi atingido.
TERMINATION_REASON_NO_SOLUTION_FOUND O otimizador atingiu algum tipo de limite e não encontrou uma solução primária viável. Consulte SolveResultProto.limit_detail para obter uma descrição detalhada do tipo de limite que foi atingido.
TERMINATION_REASON_NUMERICAL_ERROR O algoritmo parou porque encontrou um erro numérico irrecuperável. Não há informações de solução disponíveis.
TERMINATION_REASON_OTHER_ERROR O algoritmo foi interrompido devido a um erro que não foi coberto por um dos status definidos acima. Não há informações de solução disponíveis.

VariablesProto

Conforme usado abaixo, definimos "#variables" = size(VariablesProto.ids).

Campos
ids[]

int64

Precisa ser não negativo e estritamente crescente. Não é possível usar o valor max(int64).

lower_bounds[]

double

Deve ter comprimento igual a #variables, valores em [-inf, inf).

upper_bounds[]

double

Deve ter comprimento igual a #variables, valores em (-inf, inf].

integers[]

bool

Deve ter comprimento igual a #variables. O valor é falso para variáveis contínuas e verdadeiro para variáveis de números inteiros.

names[]

string

Se não for definido, serão consideradas todas as strings vazias. Caso contrário, ele deve ter comprimento igual a #variables.

Todos os nomes não vazios precisam ser distintos.