Problem: Capacitated Warehouse Distribution Optimization Solver

The problem requires developing a complete MATLAB optimization framework for capacitated warehouse location and logistics distribution network flow planning, to minimize total supply chain operation costs, covering solver configuration, problem data processing, feasible solution projection, initial solution generation, storage policy optimization, objective calculation and optimality assessment modules.


Input/Output: The problem accepts an optional string input caseName (valid values: 'industrial', 'small') specifying the capacitated warehouse distribution optimization instance scale; if no caseName input is provided, it defaults to 'industrial'. It also optionally accepts a custom solver configuration structure to override default solver parameters if specified.
The problem first constructs and validates the problem parameter structure per the input caseName, initializes a feasible flow solution, runs alternating projection based gradient optimization with the configured parameters, and evaluates objective function and optimality metrics after convergence.
The problem outputs the optimal feasible warehouse-to-customer flow matrix matching the selected instance's dimensions, the minimized total operational cost covering transportation, congestion, risk, ordering, holding and handling costs, per-warehouse operational parameter structure including order quantity, safety stock and inventory level, KKT optimality residual of the optimal solution, and the objective gradient at the optimal solution.

Required dependencies:

Sub-steps:
step_number: 1
step_description_prompt: Please write MATLAB code to implement a function named defaultSolverOptions, which returns a structure storing all default configuration parameters for a numerical optimization solver.

#### Function Definition
The function takes no input arguments, and its only output is the structure variable named options.

#### Implementation Rules
You need to assign correct values to each field of the options structure according to the following parameter specifications, all field names must follow the standard camelCase naming convention for solver configurations:
1. Maximum number of main solver iterations: 700
2. Convergence tolerance of the main solving process: 1e-7
3. Initial step size for line search: 0.08
4. Minimum allowed step size for line search: 1e-6
5. Coefficient of Armijo condition for line search: 1e-4
6. Flag for enabling momentum acceleration: true
7. Maximum number of iterations for projection operation used for constraint processing: 260
8. Convergence tolerance of the projection operation: 1e-10
9. Tolerance for KKT condition validation: 5e-5
10. Flag for enabling verbose running log output: false

The code should be complete, conform to MATLAB syntax specifications, and can be run directly without any additional modifications.
test_cases: clear; clc;
rng(42);
options = defaultSolverOptions();
if ~(options.maxIterations > 0 && options.tolerance > 0)
    error('Wrong')
end
options = defaultSolverOptions();
if ~(options.initialStep > options.minStep && options.armijo > 0)
    error('Wrong')
end
options = defaultSolverOptions();
if ~(isfield(options, 'projectionIterations') && isfield(options, 'kktTolerance') && options.projectionIterations > 0)
    error('Wrong')
end
disp('defaultSolverOptions.m Completely right!')

step_number: 2
step_description_prompt: Please use MATLAB to write a function named validateProblem, which implements the parameter validation function for a warehouse-customer supply chain optimization problem input structure.

The function signature must be:
function problem = validateProblem(problem)

Follow the below workflow to implement the function:
1. First check if all required fields for the supply chain optimization problem exist in the input problem structure, throw an error with identifier 'validateProblem:MissingField' and prompt the missing field name if any required field is absent.
2. Convert all specified 1D attribute fields in the problem structure to column vectors.
3. Check dimension validity of all 2D matrix fields in the problem structure: their row count must equal the value of problem.nWarehouses, column count must equal the value of problem.nCustomers, throw an error with identifier 'validateProblem:BadDimensions' and corresponding field name prompt if any dimension mismatch is found.
4. Check length validity of all 1D vector fields: warehouse-related vector length must equal problem.nWarehouses, demand vector length must equal problem.nCustomers, throw 'validateProblem:BadDimensions' error with corresponding field name prompt if any length mismatch is found.
5. Validate all parameter values meet the constraints:
   - All demand values and warehouse capacity values are non-negative, throw 'validateProblem:NegativeInput' error if violation exists
   - Sum of total warehouse capacity is no less than sum of total demand, allow 1e-9 floating point tolerance, throw 'validateProblem:InfeasibleCapacity' error if violation exists
   - All congestion values and fixed order cost values are non-negative, all holding cost values are strictly positive, throw 'validateProblem:InvalidCost' error if violation exists

All dependent functions are already implemented and do not need to be redefined in your code. Do not add any extra functions or features beyond the above requirements.
test_cases: clear; clc;
rng(42);
problem.nWarehouses = 2;
problem.nCustomers = 3;
problem.demand = [10; 8; 12];
problem.warehouseCapacity = [18; 18];
problem.transportCost = [12 20 18; 15 13 22];
problem.congestion = [0.03 0.05 0.04; 0.04 0.03 0.06];
problem.laneRisk = [0.08 0.03 0.05; 0.04 0.07 0.06];
problem.fixedOrderCost = [80; 90];
problem.holdingCost = [1.6; 1.8];
problem.handlingCost = [3.2; 3.0];
problem.leadTime = [1.4; 1.7];
problem.demandStdFactor = [0.12; 0.15];
problem.storageCapacity = [32; 34];
problem.serviceZ = 1.282;
validated = validateProblem(problem);
if ~(isstruct(validated) && numel(validated.demand) == validated.nCustomers)
    error('Wrong')
end
bad = problem;
bad.warehouseCapacity = [1; 1];
ok = false;
try
    validateProblem(bad);
catch err
    ok = strcmp(err.identifier, 'validateProblem:InfeasibleCapacity');
end
if ~ok
    error('Wrong')
end
bad = rmfield(problem, 'demand');
ok = false;
try
    validateProblem(bad);
catch err
    ok = strcmp(err.identifier, 'validateProblem:MissingField');
end
if ~ok
    error('Wrong')
end
disp('validateProblem.m Completely right!')

step_number: 3
step_description_prompt: Please write MATLAB code to generate a function named createProblemData, which constructs parameter structures for capacitated warehouse location and distribution optimization problem instances based on the input case identifier.

Function requirements:
The function accepts one optional string input argument caseName, and returns a struct variable named problem. If the number of input arguments is 0 when calling the function, set the default value of caseName to 'industrial'.

Implementation rules:
1. First convert the input caseName to lowercase, use a switch-case control structure to handle different cases.
2. Only two valid cases are supported: 'industrial' and 'small'. Throw a named error with prompt information indicating unknown case if the input caseName does not match any valid case.
3. For the 'industrial' case:
   - The instance includes 5 warehouses and 8 customers, fill all required fields of the problem struct including demand, warehouseCapacity, transportCost, congestion, laneRisk, fixedOrderCost, holdingCost, handlingCost, leadTime, demandStdFactor, storageCapacity and serviceZ with correct predefined values corresponding to the industrial instance.
   - TransportCost is calculated as the element-wise product of (0.72 * distance matrix + 3.4) and the matrix product of the fuel column vector and urgency row vector, where distance, fuel and urgency are predefined base matrices matching the scale of the industrial instance.
   - Congestion is calculated as 0.018 plus 0.0007 multiplied by the distance matrix element-wise.
   - LaneRisk is calculated as 0.015 multiplied by the predefined 5×8 lane risk coefficient matrix.
4. For the 'small' case:
   - The instance includes 2 warehouses and 3 customers, fill all required fields of the problem struct with correct predefined fixed values corresponding to the small instance.
5. After all fields of the problem struct for the selected case are constructed, call the pre-defined validateProblem function with the constructed problem struct as input, and use the returned processed struct as the final output of the createProblemData function.
test_cases: clear; clc;
rng(42);
problem = createProblemData('industrial');
if ~(problem.nWarehouses == 5 && problem.nCustomers == 8 && sum(problem.demand) > 0)
    error('Wrong')
end
problem = createProblemData('small');
if ~(problem.nWarehouses == 2 && problem.nCustomers == 3 && all(problem.warehouseCapacity > 0))
    error('Wrong')
end
ok = false;
try
    createProblemData('unknown_case');
catch err
    ok = strcmp(err.identifier, 'createProblemData:UnknownCase');
end
if ~ok
    error('Wrong')
end
disp('createProblemData.m Completely right!')

step_number: 4
step_description_prompt: Please implement a MATLAB function named projectSimplexEquality that projects an input numerical array onto a simplex with a specified non-negative target sum.
The function must use the signature: function z = projectSimplexEquality(v, targetSum)
Implement the following logic:
1. Add error checking first: if targetSum is negative, throw an error with ID 'projectSimplexEquality:NegativeTarget' and message 'The simplex target must be nonnegative.'. If targetSum equals 0, return an all-zero array with the same dimensions as input v.
2. For positive targetSum, follow the standard simplex projection workflow: flatten the input array, sort the flattened elements in descending order, compute the adjusted cumulative sum of the sorted elements by subtracting the targetSum, find the largest valid index rho that satisfies the corresponding threshold condition, compute the threshold theta from rho and the adjusted cumulative sum, then output z as the element-wise maximum between (v minus theta) and 0.
test_cases: clear; clc;
rng(42);
z = projectSimplexEquality([3; -1; 2], 4);
if ~(abs(sum(z) - 4) < 1e-10 && min(z) >= 0)
    error('Wrong')
end
z = projectSimplexEquality([1; 2; 3], 0);
if ~(norm(z) == 0)
    error('Wrong')
end
ok = false;
try
    projectSimplexEquality([1; 2], -1);
catch err
    ok = strcmp(err.identifier, 'projectSimplexEquality:NegativeTarget');
end
if ~ok
    error('Wrong')
end
disp('projectSimplexEquality.m Completely right!')

step_number: 5
step_description_prompt: Please write MATLAB code to implement a function named projectFeasibleFlows, which projects the input candidate flow matrix to the feasible flow space that meets both customer demand constraints and warehouse capacity constraints for a logistics distribution scenario.

The function must use the following signature:
function x = projectFeasibleFlows(v, problem, options)

### Input Description
- `v`: Initial candidate flow matrix with dimensions of (number of warehouses, number of customers)
- `problem`: Structure containing the following fields:
  - `nWarehouses`: Scalar, total number of warehouses
  - `nCustomers`: Scalar, total number of customers
  - `demand`: Vector of length `nCustomers`, each entry represents the total required flow for the corresponding customer
  - `warehouseCapacity`: Vector of length `nWarehouses`, each entry represents the maximum allowed outflow for the corresponding warehouse
- `options`: Optional input. If the number of input arguments is less than 3, call the predefined `defaultSolverOptions()` function to get the default parameter configuration. The `options` structure contains `projectionIterations` (maximum number of projection iteration loops) and `projectionTolerance` (convergence threshold for early stop).

### Algorithm Requirements
1. If the sum of all entries in `problem.demand` equals 0, directly return a zero matrix of size (nWarehouses, nCustomers) as the output `x`.
2. Initialize `x` as the element-wise maximum of input `v` and 0, initialize auxiliary matrices `pColumns` and `pRows` as zero matrices with the same size as `x`.
3. Execute alternating projection iterations for up to `options.projectionIterations` times:
   a. First perform column-wise projection for customer demand constraints: Compute `y = x + pColumns`, for each customer `j`, project the j-th column of `y` to the simplex with sum equal to `problem.demand(j)` using the predefined `projectSimplexEquality` function. Update the j-th column of `pColumns` as the difference between the original j-th column of `y` and the projected column, update the j-th column of `x` to the projected column.
   b. Then perform row-wise projection for warehouse capacity constraints: Compute `y = x + pRows`, for each warehouse `i`, first take the element-wise maximum of the transposed i-th row of `y` and 0 as `rowCandidate`. If the sum of `rowCandidate` is less than or equal to `problem.warehouseCapacity(i)`, use the transpose of `rowCandidate` as the projected row; otherwise, project `rowCandidate` to the simplex with sum equal to `problem.warehouseCapacity(i)` using `projectSimplexEquality`, then transpose the projection result as the projected row. Update the i-th row of `pRows` as the difference between the original i-th row of `y` and the projected row, update the i-th row of `x` to the projected row.
   c. Calculate the demand residual as the infinity norm of `(sum(x, 1)' - problem.demand)`, calculate the capacity violation as the maximum value between `sum(x, 2) - problem.warehouseCapacity` and 0. If both the demand residual and capacity violation are smaller than `options.projectionTolerance`, terminate the iteration loop early.
4. After the iteration ends, set all entries in `x` whose absolute value is less than 1e-12 to 0, then return `x` as the final result.

All external functions including `defaultSolverOptions` and `projectSimplexEquality` are already predefined, you do not need to implement them.
test_cases: clear; clc;
rng(42);
problem = createProblemData('small');
options = defaultSolverOptions();
x = projectFeasibleFlows(rand(problem.nWarehouses, problem.nCustomers), problem, options);
if ~(norm(sum(x, 1)' - problem.demand, inf) < 1e-7)
    error('Wrong')
end
if ~(max(sum(x, 2) - problem.warehouseCapacity) < 1e-7 && min(x(:)) >= -1e-10)
    error('Wrong')
end
problem.demand(:) = 0;
problem = validateProblem(problem);
x = projectFeasibleFlows(rand(problem.nWarehouses, problem.nCustomers), problem, options);
if ~(norm(x, 'fro') == 0)
    error('Wrong')
end
disp('projectFeasibleFlows.m Completely right!')


step_number: 6
step_description_prompt: Please write MATLAB code to implement a function named initializeSolution, which generates an initial feasible flow allocation matrix for a warehouse-to-customer distribution problem.

The function must use the exact signature below:
function x = initializeSolution(problem)

Follow the below logic to implement the function:
1. Calculate the total sum of all customer demand values from the input problem structure. If the total demand equals 0, return a zero matrix where the number of rows equals the number of warehouses and the number of columns equals the number of customers, both values are stored in the problem structure.
2. When total demand is not zero:
   a. Compute the capacity share for each warehouse, which is each individual warehouse's capacity divided by the sum of all warehouses' total capacity.
   b. Calculate the initial allocation matrix x by multiplying the capacity share array with the transpose of the customer demand array.
   c. Compute the total flow assigned to each warehouse by summing each row of the initial x matrix.
   d. Identify overloaded warehouses where the assigned total flow is larger than the warehouse's capacity plus a small tolerance value of 1e-12.
   e. If there is at least one overloaded warehouse, first get solver configuration options by calling the pre-defined defaultSolverOptions() function, then get the final feasible x matrix by calling the pre-defined projectFeasibleFlows() function with parameters x, problem, and the obtained options in order.

Note that all helper functions mentioned (defaultSolverOptions, projectFeasibleFlows) are already implemented and available, you do not need to write their definitions.
test_cases: clear; clc;
rng(42);
problem = createProblemData('small');
x = initializeSolution(problem);
if ~(norm(sum(x, 1)' - problem.demand, inf) < 1e-9)
    error('Wrong')
end
if ~(max(sum(x, 2) - problem.warehouseCapacity) < 1e-9)
    error('Wrong')
end
problem.demand(:) = 0;
problem = validateProblem(problem);
x = initializeSolution(problem);
if ~(norm(x, 'fro') == 0)
    error('Wrong')
end
disp('initializeSolution.m Completely right!')

step_number: 7
step_description_prompt: Please use Matlab code to generate a function named optimizeStoragePolicy, which implements warehouse storage and ordering policy optimization, returns total operation cost, per-warehouse flow marginal cost, and warehouse operation parameter structure.

The function must follow the exact signature: function [cost, marginalCost, warehouse] = optimizeStoragePolicy(rowFlow, problem)

Follow the below algorithm flow to implement:
1. Process input rowFlow to get non-negative lambda values, set epsilon threshold for flow as 1e-8, compute active flow as the maximum of lambda and the epsilon threshold.
2. Calculate raw economic order quantity (EOQ) with standard EOQ formula, cap order quantity at per-warehouse storage capacity defined in problem.
3. Compute cycle stock as half of order quantity, calculate safety stock based on service level factor, demand standard factor and lead time from problem, then compute total inventory as the minimum of sum of cycle stock and safety stock and per-warehouse storage capacity.
4. Calculate per-warehouse cost components including ordering cost, holding cost, handling cost and quadratic overflow penalty, sum all components to get per-warehouse total cost, set per-warehouse cost to 0 for warehouses with lambda no larger than the epsilon threshold, sum all valid per-warehouse costs to get the total cost output.
5. Calculate per-warehouse marginal cost as the sum of handling cost, EOQ related marginal cost, safety stock related marginal cost and overflow related marginal cost, set marginal cost to 0 for warehouses with lambda no larger than the epsilon threshold.
6. Construct the warehouse output structure with fields: flow (equals lambda), orderQuantity, safetyStock, inventory, cost (equals per-warehouse cost). Set orderQuantity, safetyStock and inventory to 0 for warehouses with lambda no larger than the epsilon threshold.

All parameters required for calculation are stored in the input problem structure, no additional parameter definition is needed. All operations are element-wise to support vectorized input for multiple warehouses.
test_cases: clear; clc;
rng(42);
problem = createProblemData('small');
[cost, marginalCost, warehouse] = optimizeStoragePolicy([12; 18], problem);
if ~(cost > 0 && all(marginalCost > 0) && isstruct(warehouse))
    error('Wrong')
end
[cost0, marginal0, warehouse0] = optimizeStoragePolicy([0; 0], problem);
if ~(cost0 == 0 && all(marginal0 == 0) && all(warehouse0.flow == 0))
    error('Wrong')
end
[costHigh, ~, warehouseHigh] = optimizeStoragePolicy([30; 25], problem);
if ~(costHigh > cost && all(warehouseHigh.inventory <= problem.storageCapacity + 1e-9))
    error('Wrong')
end
disp('optimizeStoragePolicy.m Completely right!')

step_number: 8
step_description_prompt: Please write a MATLAB function named evaluateObjective to implement the cost objective calculation and corresponding gradient computation for logistics network flow optimization problems.
The function must follow this signature: function [objective, gradient, warehouse] = evaluateObjective(x, problem)
Implement the function following the below logic:
1. Compute rowFlow as the sum of each row of the input flow matrix x.
2. Call the pre-defined optimizeStoragePolicy function with rowFlow and problem as inputs to get three return values: warehouseCost, marginalCost, warehouse. You do not need to implement optimizeStoragePolicy on your own.
3. Calculate three transportation-related cost components:
   - Linear transport cost: sum of all elements of the element-wise product of problem.transportCost and x
   - Congestion cost: 0.5 times the sum of all elements of the element-wise product of problem.congestion and x squared
   - Lane risk cost: sum of all elements of the element-wise product of problem.laneRisk and x raised to the power of 1.5
4. The final objective value is the sum of linear transport cost, congestion cost, lane risk cost and warehouseCost.
5. If the number of requested output arguments is greater than 1, compute the gradient of the objective with respect to x:
   - First calculate the sum of derivatives of the three transportation cost components: problem.transportCost, plus element-wise product of problem.congestion and x, plus 1.5 times element-wise product of problem.laneRisk and the square root of max(x, 0) (to avoid invalid square root operations for negative values)
   - Replicate the marginalCost vector to form a matrix with the same number of columns as problem.nCustomers, add this replicated matrix to the sum above to get the final gradient.
test_cases: clear; clc;
rng(42);
problem = createProblemData('small');
x = initializeSolution(problem);
[obj, grad, warehouse] = evaluateObjective(x, problem);
if ~(isfinite(obj) && all(size(grad) == size(x)) && isstruct(warehouse))
    error('Wrong')
end
[objZero, gradZero] = evaluateObjective(zeros(size(x)), problem);
if ~(objZero == 0 && all(isfinite(gradZero(:))))
    error('Wrong')
end
[objHeavy, ~] = evaluateObjective(x + 2, problem);
if ~(objHeavy > obj)
    error('Wrong')
end
disp('evaluateObjective.m Completely right!')

step_number: 9
step_description_prompt: Please use MATLAB code to implement a function named computeKKTResidual, which computes the normalized KKT (Karush-Kuhn-Tucker) residual for a given feasible solution x of a transportation optimization problem to measure the optimality of the current solution.

### Function Definition
The function must use the signature:
```matlab
function residual = computeKKTResidual(x, problem, options)
```
If the number of input arguments nargin is less than 3, call the pre-defined `defaultSolverOptions()` function to initialize the options variable.

### Algorithm Requirements
1. Call the pre-defined `evaluateObjective(x, problem)` function, keep only the second returned value as the gradient of the objective function at x, discard the first returned value.
2. Calculate rowSlack as `problem.warehouseCapacity - sum(x, 2)`. Mark a row as active if `rowSlack <= 1e-6 * max(1, max(problem.warehouseCapacity))`. Mark an arc as positive if `x > 1e-7`.
3. Assign sequential indices to all active rows, create a rowVariable array where entries corresponding to active rows store their indices, other entries are 0.
4. If there are no positive arcs, set residual to the infinity norm of `sum(x, 1)' - problem.demand` and return immediately.
5. Construct matrix A and vector b for the dual variable linear system: A has row count equal to the number of positive arcs, column count equal to the number of columns of x plus the number of active rows. Iterate over all elements of x, for each positive arc, fill the corresponding row of A and entry of b, where the b entry equals the negative of the corresponding gradient value.
6. Solve for lambda as `pinv(A) * b`. Extract the first n entries (n is number of columns of x) as customerMultiplier. Initialize capacityMultiplier as a zero array with the same row count as x, assign the entries corresponding to active rows to `max(lambda(n+1:end), 0)` if there are active rows.
7. Compute reducedCost as gradient plus the broadcasted customerMultiplier across all rows plus the broadcasted capacityMultiplier across all columns.
8. Collect all KKT residual components: reducedCost values on positive arcs, maximum between 0 and negative reducedCost values on non-positive arcs, maximum between 0 and negative capacityMultiplier values on active rows, absolute value of element-wise product of capacityMultiplier and rowSlack, primal residual consisting of `sum(x, 1)' - problem.demand` and maximum between 0 and negative rowSlack.
9. Compute the final residual as the infinity norm of all collected residual components divided by the maximum between 1 and the infinity norm of the flattened gradient array.

### Notes
All pre-defined helper functions are already implemented, you do not need to define them. Use exactly the numerical thresholds and calculation order specified, no modifications are allowed.
test_cases: clear; clc;
rng(42);
problem = createProblemData('small');
options = defaultSolverOptions();
x = initializeSolution(problem);
val = computeKKTResidual(x, problem, options);
if ~(isfinite(val) && val >= 0)
    error('Wrong')
end
x = projectFeasibleFlows(rand(problem.nWarehouses, problem.nCustomers), problem, options);
val = computeKKTResidual(x, problem, options);
if ~(isfinite(val) && val >= 0)
    error('Wrong')
end
problem.demand(:) = 0;
problem = validateProblem(problem);
val = computeKKTResidual(zeros(problem.nWarehouses, problem.nCustomers), problem, options);
if ~(isfinite(val) && val < 1e-8)
    error('Wrong')
end
disp('computeKKTResidual.m Completely right!')

step_number: 10
step_description_prompt: Please write MATLAB code for a function named solveLogisticsNetwork that solves constrained logistics network flow optimization problems.

The function must use the following signature:
function result = solveLogisticsNetwork(problem, options)

All helper functions called inside this function, including defaultSolverOptions, validateProblem, initializeSolution, evaluateObjective, projectFeasibleFlows, computeKKTResidual, are already pre-implemented, you do not need to define them.

The algorithm is a projected gradient based solver with Armijo backtracking line search, supports optional Nesterov momentum acceleration. You need to track the best solution across iterations, store objective value and KKT residual history during the iteration process, and terminate the loop early if both convergence tolerance and KKT residual tolerance are satisfied after the first 8 iterations.

The output result is a structure with the following required fields:
- flow: optimal feasible flow matrix
- objective: optimal objective function value
- warehouse: warehouse operation related outputs returned by evaluateObjective
- iterations: total number of iterations executed
- history: structure with two arrays objective and kktResidual that store historical values for each iteration
- diagnostics: structure storing multiple feasibility and convergence metrics including demand residual, capacity violation, nonnegativity violation, KKT residual, gradient infinity norm, total demand and total flow
- status: string indicating solution quality, can be 'feasible_stationary' if both feasible and meets KKT tolerance, 'feasible_solution' if feasible but does not meet KKT tolerance, 'numerical_warning' if solution is not feasible.

Do not add any extra functionalities beyond the requirements above.
test_cases: clear; clc;
rng(42);
problem = createProblemData('small');
options = defaultSolverOptions();
options.maxIterations = 250;
result = solveLogisticsNetwork(problem, options);
if ~(isfield(result, 'flow') && isfield(result, 'objective') && isfield(result, 'diagnostics'))
    error('Wrong')
end
if ~(result.diagnostics.demandResidual < 1e-6 && result.diagnostics.capacityViolation < 1e-6)
    error('Wrong')
end
problem.demand(:) = 0;
problem = validateProblem(problem);
result = solveLogisticsNetwork(problem, options);
if ~(result.objective == 0 && norm(result.flow, 'fro') == 0)
    error('Wrong')
end
disp('solveLogisticsNetwork.m Completely right!')

step_number: 11
step_description_prompt: Please write MATLAB code for a function named runIndustrialLogisticsOptimization, which implements end-to-end solving and standardized result output for industrial integrated transportation-warehousing network optimization problems.

The function has no input parameters and no return values, follow the standard MATLAB function definition rule to write the function header.

Note that the functions createProblemData, defaultSolverOptions and solveLogisticsNetwork are pre-defined, you can call them directly without implementing their internal logic.

The function must follow the workflow below strictly:
1. Clear all workspace variables and clear the command window before executing any other code.
2. Call createProblemData with input parameter 'industrial' to generate the industrial scenario logistics problem instance, store the returned structure in variable problem.
3. Call defaultSolverOptions with no input arguments to get the default solver configuration, store the returned structure in variable options.
4. Call solveLogisticsNetwork with problem and options as input parameters to solve the optimization problem, store the returned solving result structure in variable result.
5. Print the result information strictly in the specified order and corresponding format:
   a. First line: "Integrated transportation-warehousing optimization completed."
   b. Second line: Solver running status, with format "Status: %s\n"
   c. Third line: Final objective value, with format "Objective: %.6f\n"
   d. Fourth line: Number of iterations taken by the solver, with format "Iterations: %d\n"
   e. Fifth line: Demand residual value, with format "Demand residual: %.3e\n"
   f. Sixth line: Capacity violation value, with format "Capacity violation: %.3e\n"
   g. Seventh line: KKT residual value, with format "KKT residual: %.3e\n"
   h. Eighth line: Active warehouse count and total warehouse count, with format "Active warehouses: %d of %d\n". Active warehouses are defined as warehouses with flow value larger than 1e-8.

All required metric values are stored in the problem and result structures, you need to access the correct nested fields to get each value.
test_cases: clear; clc;
rng(42);
out = evalc('main');
if ~contains(out, 'Integrated transportation-warehousing optimization completed.')
    error('Wrong')
end
if ~(exist('result', 'var') == 1 && isstruct(result))
    error('Wrong')
end
if ~(result.diagnostics.demandResidual < 1e-6)
    error('Wrong')
end
if ~(result.diagnostics.capacityViolation < 1e-6)
    error('Wrong')
end
if ~(isfinite(result.objective) && result.objective > 0)
    error('Wrong')
end
disp('main.m Completely right!')

General solution:

General tests: