MicroCity NotesMicroCity Notes
Notes
  • MicroCity Web
  • MicroCity Desktop

    • 1. MicroCity Introduction
    • 2. Getting Started with MicroCity
    • 3. User Interface
    • 4. Script Writing
  • GitHub

    • MicroCity Desktop Repository
    • MicroCity Web Repository
    • MicroCity Web Online Environment
  • 简体中文
  • English
Notes
  • MicroCity Web
  • MicroCity Desktop

    • 1. MicroCity Introduction
    • 2. Getting Started with MicroCity
    • 3. User Interface
    • 4. Script Writing
  • GitHub

    • MicroCity Desktop Repository
    • MicroCity Web Repository
    • MicroCity Web Online Environment
  • 简体中文
  • English
  • Table of Contents
  • General Knowledge

    • Quick Start with Lua Language
    • Version Information of MicroCity
    • Advancement of Simulation Time
    • Object-Oriented Programming
    • Tools
  • MicroCity

    • Visualization of Results
    • Operating Networks
    • Model Solving
  • MicroCityWeb

    • User Interface Overview
    • 3D Scene
    • 3D Objects
    • Discrete Event Simulation and Program Control
    • Mixed integer programming
    • Debugging
  • Concepts

    • Ideas for Warehouse Automation Simulation
    • General Drawing Code
    • Port AGV Service Process 3D Simulation Approach

Model Solving

In MicroCity, mathematical models can be solved. In this article, we will introduce the common process of solving mathematical models in MicroCity and provide some tips to help you better build models.

The detailed usage of all functions in the planning model can be found in the document 4.8 Mixed Integer Linear Programming.

Tips

The content on this page is based on MicroCity Desktop version. If you are looking for a solution for mixed integer programming in MicroCity Web version, please refer to the corresponding Mixed Integer Programming section in the MicroCity Web notes.

Creating Model Objects

Create a planning model object and store it in the variable lp.

local lp = CreateLP()

The mathematical model object created in the official documentation is stored in the variable LPModel, which has the same function as lp in this article.

Writing Mathematical Models

At this point, the object of the mathematical model has been created and stored in the variable lp, and further operations can be performed on it. A mathematical model generally consists of two parts:

  • Objective Function
  • Constraint Equations

Next, let's introduce how to create the objective function.

Creating the Objective Function

In MicroCity, SetObjectFunction() is used to set the objective function of the model object. It allows you to choose whether to optimize for maximum or minimum. The specific usage is as follows:

Maximum
SetObjFunction(lp, coeff, "max") -- Optimize for maximum
Minimum
SetObjFunction(lp, coeff, "min") -- Optimize for minimum

"min" and "max" are case-insensitive, so "MIN" and "MAX" can also be used.

Parameter Description and Example

ParameterDescription
lpMathematical model object. Input the mathematical model into the function to set the objective function.
coeffObjective function coefficients, which is a table type variable. Used to determine the coefficients of the objective function in the model.
"min" or "max"Determine whether to optimize for the maximum or the minimum of the objective function.

coeff is a coefficient list for the objective function, which is a table type variable. Suppose you want to minimize the function 4x1+12x2+18x34x_1+12x_2+18x_34x1​+12x2​+18x3​, the procedure to add the objective function is as follows:

-- Suppose you have already created the model object and stored it in the variable lp

-- 4*x1 + 12*x2 + 18*x3
local coeff = {4, 12, 18}

-- Set the objective function: minimize
SetObjFunction(lp, coeff, "min")

Adding Constraint Equations

In MicroCity, the function for adding model constraints is AddConstraint(), used as follows:

≤
-- Use symbols to express
AddConstraint(lp, cons, "<=", b)

-- Alternatively, you can use abbreviations
AddConstraint(lp, cons, "le", b)
≥
-- Use symbols to express
AddConstraint(lp, cons, ">=", b)

-- Alternatively, you can use abbreviations
AddConstraint(lp, cons, "ge", b)
=
-- Use symbols to express
AddConstraint(lp, cons, "==", b)

-- Or you can use abbreviations to express it

AddConstraint(lp, cons, "eq", b)

Parameter Description

ParameterDescription
lpMathematical model object. Input the mathematical model into the function to add constraints to it.
consConstraint equation coefficients. Similar to cons in setting the objective function, it is also a table type variable used to determine the coefficients of each variable in the constraint equation.
"<=" or ">=" or "==", or their corresponding alphabetic expressionsDetermines the relationship between the constraint equation and the right-hand side.
bA number representing the right-hand side of the constraint equation. It can be a variable or a constant.

Example

The objective function 4x1+12x2+18x34x_1+12x_2+18x_34x1​+12x2​+18x3​ has been set above. Suppose you want to add two constraint equations for this function:

{x1+3x3≥32x2+2x3≥5\left\{\begin{matrix} x_1+3x_3\ge3 \\ 2x_2+2x_3\ge5 \end{matrix}\right. {x1​+3x3​≥32x2​+2x3​≥5​

Add corresponding constraint equations:

-- Add constraint: x1+3*x3≥3
cons = { 1, 0, 3 }
AddConstraint(lp, cons, ">=", 3)

-- Add constraint: 2*x2+2*x3≥5
cons = { 0, 2, 2 }
AddConstraint(lp, cons, ">=", 5)

It is not difficult to notice that the number of coefficients is consistent with the number of variables in the objective function. Therefore, before programming the solution, you need to first determine the total number of variables and arrange the positions of each variable.

Set Variable Types

MicroCity's mathematical programming supports integer programming. If no SetUnbounded() is set for the variables, the default value range for the variables is non-negative real numbers (≥0). The following describes in detail how to set variable types.

You can set the integer variable or 0-1 variable for the i-th variable in the model. If the variable is not set to these types, the default variable is non-negative real number.

Integer Variables
SetInteger(lp, i) -- Integer variable
0-1 Variables
SetBinary(lp, i) --0-1 variable

To allow the value of the i-th variable to be negative (by default, it cannot be negative):

SetUnbounded(lp, i)

Model Solving and Output

Model Solving

Since both the objective function and the constraint equations have been added, solving the model is simple, just one step:

SolveLP(lp)

After executing this statement, the mathematical model stored in the variable lp is solved.

Output

After solving the problem, it still needs to be output to understand the result of the solution. The following are commonly used functions for outputting the solution result.

Obtain the objective function value:

GetObjective(lp)

Obtain the value of the i-th variable:

GetVariable(lp, i)

SolveLP

The SolveLP() function also has output after the solution is obtained, the meaning of the output code is as follows:

Output CodeMeaning
0Success
-1Invalid LP Model
-2Out of Memory
1Suboptimal
2Infeasible
3Unbounded
4Degenerate
5Numerical Error
6User Termination
7Timeout Error

For the meaning of other return values, please refer to the documentation 4.8 Mixed Integer Linear Programming for the SolveLP() function.

Model Solution Example

Here is a simple example of modeling and solving for reference. (Actually it just strings together the previous content)

Example:

minf=4x1+12x2+18x3s.t.{x1+3x3≥32x2+2x3≥5x1,x2,x3∈Nminf=4x_1+12x_2+18x_3\\ s.t.\left\{\begin{matrix} x_1+3x_3\ge3 \\ 2x_2+2x_3\ge5 \\ x_1,x_2,x_3\in N \end{matrix}\right. minf=4x1​+12x2​+18x3​s.t.⎩⎨⎧​x1​+3x3​≥32x2​+2x3​≥5x1​,x2​,x3​∈N​

N represents the set of natural numbers (non-negative integers)

Script:

-- Create linear programming object
local lp = CreateLP()

local n = 3 -- Set the number of objective functions

-- Objective function: 4*x1 + 12*x2 + 18*x3
-- Set the coefficients of the objective function, and the objective function is minimized
local coeff = { 4, 12, 18 }
SetObjFunction(lp, coeff, "min")

-- Add constraint 1: x1 + 3*x3 ≥ 3
cons = { 1, 0, 3 }
AddConstraint(lp, cons, ">=", 3)

-- Add constraint 2: 2*x2 + 2*x3 ≥ 5
cons = { 0, 2, 2 }
AddConstraint(lp, cons, ">=", 5)

-- Since SetUnbounded() is not set,
-- by default, all variables are non-negative,
-- so there is no need to add constraints for non-negative variables.

-- Set all variables to integers
for i = 1, n do
    SetInteger(lp, i)
end

-- Solve the model
SolveLP(lp)

-- Output the objective function value
print("Objective function value:", GetObjective(lp))

-- Output the values of each variable
for i = 1, n do
    print("x", i, "=", GetVariable(lp, i))
end

Output:

Objective function value: 42
x1=0
x2=2
x3=1

Some Techniques for Modeling

Linearization

Sometimes we encounter modeling problems with multiple subscripts, such as the decision variable xijx_{ij}xij​, which needs to be linearized.

Let's assume that the shape of the decision variable itself is 3 rows and 4 columns, that is:

Column 1Column 2Column 3Column 4
x11x_{11}x11​x12x_{12}x12​x13x_{13}x13​x14x_{14}x14​
x21x_{21}x21​x22x_{22}x22​x23x_{23}x23​x24x_{24}x24​
x31x_{31}x31​x32x_{32}x32​x33x_{33}x33​x34x_{34}x34​

Assuming that the objective function is to sum up these decision variables, which is F=∑i=13∑j=14xijF=\sum_{i=1}^3\sum_{j=1}^4x_{ij}F=∑i=13​∑j=14​xij​, if we want to input it into the objective function, we can linearize it as x11+x12+...+x14+x21+...+x24+x31+...+x34x_{11}+x_{12}+...+x_{14}+x_{21}+...+x_{24}+x_{31}+...+x_{34}x11​+x12​+...+x14​+x21​+...+x24​+x31​+...+x34​.

Since there are only two dimensions, we can use two for loops to achieve this:

local cons = {}
for i = 1, 3 do -- the first dimension
    for j = 1, 4 do -- the second dimension
        cons[4 * (i - 1) + j] = 1 -- fill in the coefficients
        -- the idea of 4 * (i - 1) + j is similar to carrying
    end
end

-- result:
-- cons has a length of 12, and all values are 1

Example: Assignment Model

Let's take a look at the specific usage and convenience of multidimensional linearization using an actual example.

Four people, A, B, C, and D, are assigned to deliver four types of goods, A, B, C, and D, with the corresponding delivery times shown in the table. If each person delivers only one type of goods, who should be assigned to deliver which type of goods to minimize the total time?

Person\GoodsABCD
A149415
B117910
C132105
D1791513

Let's assume that the numbers corresponding to goods A, B, C, D are 1, 2, 3, 4 respectively, and xij=1x_{ij}=1xij​=1 represents person i delivering goods j, and xij=0x_{ij}=0xij​=0 represents person i not delivering goods j.

The mathematical model of the above problem can be represented as

minZ=∑i=14∑j=14cijxijs.t.{∑j=14xij=1,i=1,2,...,4∑i=14xij=1,j=1,2,...,4xij=0,1minZ=\sum_{i=1}^4\sum_{j=1}^4c_{ij}x_{ij}\\ s.t.\left\{\begin{matrix} \sum_{j=1}^4x_{ij}=1, i=1,2,...,4 \\ \sum_{i=1}^4x_{ij}=1, j=1,2,...,4 \\ x_{ij}=0,1 \end{matrix}\right. minZ=i=1∑4​j=1∑4​cij​xij​s.t.⎩⎨⎧​∑j=14​xij​=1,i=1,2,...,4∑i=14​xij​=1,j=1,2,...,4xij​=0,1​

Solution code:

-- efficiency matrix
local cost = {
    { 14, 9, 4, 15 },
    { 11, 7, 9, 10 },
    { 13, 2, 10, 5 },
    { 17, 9, 15, 13 }
}

local lp = CreateLP()

-- create the objective function
local coeff = {}
for i = 1, 4 do
    for j = 1, 4 do
        -- it is easy to convert a two-dimensional array to a one-dimensional array here
        coeff[4 * (i - 1) + j] = cost[i][j]
    end
end

SetObjFunction(lp, coeff, "min")

-- add constraints
for k = 1, 4 do -- control the value of the i dimension
    local cons = {}
    for i = 1, 4 do
        for j = 1, 4 do
            if i == k then -- sum up j, check i
                cons[4 * (i - 1) + j] = 1
            else
                cons[4 * (i - 1) + j] = 0
            end
        end
    end
    AddConstraint(lp, cons, "==", 1)
end

for k = 1, 4 do -- Control the value of the jth dimension
    local cons = {}
    for i = 1, 4 do
        for j = 1, 4 do
            if j == k then -- Sum i and check j
                cons[4 * (i - 1) + j] = 1
            else
                cons[4 * (i - 1) + j] = 0
            end
        end
    end
    AddConstraint(lp, cons, "==", 1)
end

-- Solve the model
SolveLP(lp)

-- Output the objective function value
print("Objective function value:", GetObjective(lp))

-- Output the decision variables
for i = 1, 4 do -- First dimension
    for j = 1, 4 do -- Second dimension
        local x = GetVariable(lp, 4 * (i - 1) + j)
        if x ~= 0 then
            print("x[", i, "][", j, "]=", x)
        end
    end
end

Output

Objective function value: 29
x[1][3]=1
x[2][1]=1
x[3][4]=1
x[4][2]=1
ResultPersonItem
x13=1x_{13}=1x13​=1AC
x21=1x_{21}=1x21​=1BA
x34=1x_{34}=1x34​=1CD
x42=1x_{42}=1x42​=1DB

Handling Intermediate Variables

Sometimes there may be intermediate variables in the model that need to have corresponding positions in the matrix in order to be solved, but these intermediate variables do not participate in the calculation of the objective function value. You can set the coefficients of these intermediate variables to 0 at their corresponding positions.

Let x1,x2,x3,x4x_1, x_2, x_3, x_4x1​,x2​,x3​,x4​ be the decision variables and y1,y2y_1, y_2y1​,y2​ be the intermediate variables. The objective function is:

z=∑i=14xiz = \sum_{i=1}^4 x_i z=i=1∑4​xi​

Then the coefficients of the objective function can be set as:

local fcons = {1, 1, 1, 1, 0, 0}

After that, you can proceed with the general process 😎

This post is translated using ChatGPT, please feedback if any omissions.

Last Updated:
Contributors: huuhghhgyg
Prev
Operating Networks