Paintshop Color Change Scheduling with FICO Xpress#

color_change_scheduling.ipynb Open In Colab Open In Deepnote Open In Kaggle Open In Gradient Open In SageMaker Studio Lab Powered by AMPL

Description: A scheduling problem demonstrating high-level modeling and manual solver tuning in FICO Xpress

Tags: AMPLPY, MP, scheduling, color change scheduling, tuning, xpress

Notebook author: Gleb Belov <gleb@ampl.com>

Reference:

  1. F. Winter and N. Musliu (2022). A large neighborhood search approach for the paint shop scheduling problem. J Sched 25 pp 453-475.

  2. AMPL Xpress documentation. https://dev.ampl.com/solvers/xpress/index.html.

  3. AMPL MP Library: modeling guide. https://mp.ampl.com/.

# Install dependencies
%pip install -q amplpy pandas matplotlib
# Google Colab & Kaggle integration
from amplpy import AMPL, ampl_notebook

ampl = ampl_notebook(
    modules=["xpress"],  # modules to install
    license_uuid="default",  # license to use
)  # instantiate AMPL object and register magics

Problem description#

Paintshop color change scheduling problem (PCCSP) is a subproblem in the paintshop scheduling problem (PSSP). While PSSP optimizes a complete schedule, PCCSP is restricted to decisions concerning coloring operations.

Given a predefined sequence of skid types passing through coloring equipment, PCCSP assigns car parts to the skids so that to minimize color change costs. While in practice the skid type sequence comes from a larger problem, we generate that and other parameters randomly.

Car part sequence painting

aimtecglobal.com

We set up the model and manually adjust FICO Xpress parameters.

Model highlights#

  • Pre-defined sequence of skid types

  • Each skid type can hold one of a subset of pre-defined combinations (patterns) of car parts.

    • For example, skid type 926 can hold one of the patterns 20, 35, …

  • Each pattern has

    • minimal and extra demands (how many times it should be scheduled);

    • Several color specifications:

      • Two “simple” colors (can be quickly changed between skids)

      • “Maximal” color, if any (change requires 30 skids’ waiting time, however there are three Max coloring machines)

  • Minimize costs for over- and underproduction, as well as color change costs of each specification.

AMPL model#

Use %%writefile to save AMPL model, or %%ampl_eval to evaluate AMPL statements

%%writefile pccsp.mod

set SKID_TYPES;                          # Parameter sets
set PATTERNS;
set COLOR_SIMPLE_CATEGORIES;
set COLORS_SIMPLE {COLOR_SIMPLE_CATEGORIES};
set COLORS_MAX;
set COLOR_MAX_MACHINES default 1..3;

param n_slots;                           # Allocation parameters
set SLOTS := 1..n_slots;
param slot_skid_type {SLOTS} in SKID_TYPES;
set SKID_TYPE_PATTERNS {SKID_TYPES} within PATTERNS;
param pattern_demand_minimum {PATTERNS};
param pattern_demand_extra {PATTERNS};

                                         # Color parameters
param color_spec_simple {PATTERNS, cc in COLOR_SIMPLE_CATEGORIES}
        in COLORS_SIMPLE[cc];
param color_spec_MAX {PATTERNS} in COLORS_MAX union {0};   # 0 means not used
param wait_change_MAX integer default 30;  # For each MAX machine

                                         # Costs
param pattern_missing_cost {PATTERNS};
param pattern_overuse_cost {PATTERNS};
param color_simple_change_cost {COLOR_SIMPLE_CATEGORIES};
param color_MAX_change_cost;


# Primary variables
var slot_pattern {SLOTS} in PATTERNS union {0};  # 0 means slot empty
var slot_color_spec_MAX {SLOTS, COLOR_MAX_MACHINES} in COLORS_MAX;
var slot_color_MAX_machine_available {SLOTS, COLOR_MAX_MACHINES} binary;

# Secondary variables
var pattern_use {p in PATTERNS} >= pattern_demand_minimum[p];
var pattern_missing {p in PATTERNS} >= 0;
var pattern_overuse {p in PATTERNS} >= 0;
var slot_color_spec {SLOTS, cc in COLOR_SIMPLE_CATEGORIES} in COLORS_SIMPLE[cc];
var slot_color_change {1..n_slots-1, COLOR_SIMPLE_CATEGORIES} binary;
var slot_color_MAX_change {1..n_slots-1, COLOR_MAX_MACHINES} binary;

# Constraints
s.t. PatternUse {p in PATTERNS}:
    pattern_use[p] ==
        count {s in SLOTS} (p == slot_pattern[s]);

s.t. PatternUseBalance {p in PATTERNS}:
    pattern_demand_minimum[p] + pattern_demand_extra[p] +
        pattern_overuse[p] ==
        pattern_use[p] + pattern_missing[p];

s.t. PatternChoice {s in SLOTS}:                # Restrict pattern choice in the slot
    exists {p in {0} union SKID_TYPE_PATTERNS[slot_skid_type[s]]}
        (p == slot_pattern[s]);

s.t. ColorSimpleSpec {s in SLOTS,
                      p in SKID_TYPE_PATTERNS[slot_skid_type[s]],
                     cc in COLOR_SIMPLE_CATEGORIES}:
    (p == slot_pattern[s]) ==>                  # Pattern p selected ==>
        (slot_color_spec[s, cc] == color_spec_simple[p, cc]);  # Assign simple colors

s.t. ColorSimpleChanges {s in 1..n_slots-1,
                         cc in COLOR_SIMPLE_CATEGORIES}:
    (slot_color_spec[s, cc] != slot_color_spec[s+1, cc]) ==> slot_color_change[s, cc];

s.t. ColorMAXSpec {s in SLOTS,
                   p in SKID_TYPE_PATTERNS[slot_skid_type[s]]:
                   color_spec_MAX[p] in COLORS_MAX}:   # If p requires some color MAX:
    (p == slot_pattern[s]) ==>                  # Pattern allocated ==>
        (exists {cm in COLOR_MAX_MACHINES}      # some MAX machine must do it
            (slot_color_spec_MAX[s, cm] == color_spec_MAX[p]
                && slot_color_MAX_machine_available[s, cm]));

s.t. ColorMAXChanges {s in 1..n_slots-1,
                      cm in COLOR_MAX_MACHINES}:# Changing MAX color on machine cm ==>
    (slot_color_spec_MAX[s, cm] != slot_color_spec_MAX[s+1, cm]) ==>
        ((forall {s1 in s+1..min(n_slots, s+wait_change_MAX)}
            ! slot_color_MAX_machine_available[s1, cm])  # Block cm for 30 slots
         && slot_color_MAX_change[s, cm]);      # and bump change flag


# Objective
minimize TotalCosts:
    sum {p in PATTERNS} (pattern_missing_cost[p] * pattern_missing[p]
                         + pattern_overuse_cost[p] * pattern_overuse[p])
    + sum {s in 1.. n_slots-1}
          (sum {cc in COLOR_SIMPLE_CATEGORIES}
               color_simple_change_cost[cc] * slot_color_change[s, cc]
           + sum {cm in COLOR_MAX_MACHINES}
               color_MAX_change_cost * slot_color_MAX_change[s, cm]);
Overwriting pccsp.mod

Instance generation code#

import random
import math
from dataclasses import dataclass, field
from typing import List, Set, Dict


class InstGenParams:
    def __init__(self):
        self.nSkidTypes = 4
        self.nPatterns = 5
        self.nSlots = 50

        self.nSkidTypesForPatternMeanDev = [1, 2]  # Dev is variance
        self.dSkidTypeNWindowsMeanDev = [3, 10]
        self.demandMinMeanDev = [1, 4]
        self.demandExtraMeanDev = [10, 40]

        self.nColorsSimple = [4, 5]  # N colors for each simple category
        self.nColorsMax = 7
        self.pUsingColorMax = 0.7  # Probability for a pattern
        self.nColorMAXMachines = 3
        self.nChangeMAXWait = 30

        self.minCost = 1e-3  # For a cost
        self.patternMissingCostMeanDev = [10, 5]
        self.patternOveruseCostMeanDev = [2, 1]
        self.colorSimpleChangeCost = [1, 1]  # For each category
        self.colorMAXChangeCost = [10]


# -------------------- Data Model --------------------


@dataclass
class PatternData:
    id: int
    min_demand: int = 0
    extra_demand: int = 0
    allowable_skid_types: Set[int] = field(default_factory=set)
    total_assigned: int = 0


@dataclass
class SkidTypeData:
    id: int
    allowable_patterns: Set[int] = field(default_factory=set)
    total_usage: int = 0
    n_subsequences: int = 0
    n_subseq_merged: int = 0  # Some can be consecutive
    subsequences: List[int] = field(default_factory=list)  # sizes of each block
    subseq_merged: List[int] = field(default_factory=list)  # sizes of each block


@dataclass
class InstanceResult:
    skid_types: Dict[int, SkidTypeData]
    patterns: Dict[int, PatternData]
    skid_type_usages: List[int]
    sum_min_demands: int
    pattern_min_demands: List[int]
    pattern_extra_demands: List[int]
    overall_sequence: List[int]

    color_spec_simple: List[int]
    color_spec_MAX: List[int]
    nColorMAXMachines: int
    nChangeMAXWait: int

    patternMissingCost: List[int]
    patternOveruseCost: List[int]
    colorSimpleChangeCost: List[int]
    colorMAXChangeCost: int


# -------------------- Generator --------------------


class InstanceGenerator:

    def __init__(self, params: InstGenParams, seed: int = 42):
        self.params = params
        if seed is not None:
            random.seed(seed)

        self.patterns = {i: PatternData(i) for i in range(params.nPatterns)}
        self.skid_types = {i: SkidTypeData(i) for i in range(params.nSkidTypes)}
        self.total_used_skids = 0

    # --------- Utility Draw Methods ---------

    @staticmethod
    def _draw_nonnegative_int(mean_dev):
        """Gaussian draw, rounded to integer, truncated at 0."""
        mean, dev = mean_dev
        return max(0, int(round(random.gauss(mean, math.sqrt(dev)))))

    @staticmethod
    def _draw_positive_int(mean_dev):
        """Gaussian draw truncated at 1."""
        return max(1, InstanceGenerator._draw_nonnegative_int(mean_dev))

    # --------- Step 1 ---------

    def generate_pattern_demands(self):
        """
        1. For each pattern, generate minimal and extra demand.
           Negative draws are replaced by 0.
        """
        for p in self.patterns.values():
            p.min_demand = self._draw_nonnegative_int(self.params.demandMinMeanDev)
            p.extra_demand = self._draw_nonnegative_int(self.params.demandExtraMeanDev)

    # --------- Step 2 ---------

    def generate_allowable_sets(self):
        """
        2. For each pattern, generate allowable skid types.
           Cardinality drawn from mean/deviation.
           Also build inverse mapping: skid_type -> allowable patterns.
        """
        for p in self.patterns.values():
            k = self._draw_nonnegative_int(self.params.nSkidTypesForPatternMeanDev)

            # At least 1, at most total skid types
            k = min(max(1, k), self.params.nSkidTypes)

            allowable = set(random.sample(range(self.params.nSkidTypes), k))
            p.allowable_skid_types = allowable

            for s in allowable:
                self.skid_types[s].allowable_patterns.add(p.id)

    # --------- Step 3 & 4 ---------

    def assign_min_demands(self):
        """
        3. Assign each pattern to min_demand skids from its allowable set.
        4. If total usage exceeds nSlots → error.
        """
        for p in self.patterns.values():
            for _ in range(p.min_demand):
                skid = random.choice(list(p.allowable_skid_types))
                self._assign(p.id, skid)

        if self.total_used_skids > self.params.nSlots:
            raise ValueError("Minimal demands exceed total number of slots")

    # --------- Step 5 & 6 ---------

    def fill_remaining_slots(self):
        """
        5. total_used_skids already maintained.
        6. While below nSlots, repeatedly assign:
           - pattern chosen with probability proportional to extra_demand + 1
           - skid chosen uniformly from pattern's allowable set
        """
        while self.total_used_skids < self.params.nSlots:
            weights = [self.patterns[i].extra_demand + 1 for i in self.patterns]

            pattern_id = random.choices(
                population=list(self.patterns.keys()), weights=weights, k=1
            )[0]

            skid = random.choice(list(self.patterns[pattern_id].allowable_skid_types))

            self._assign(pattern_id, skid)

    def _assign(self, pattern_id: int, skid_id: int):
        """Internal consistent assignment update."""
        self.patterns[pattern_id].total_assigned += 1
        self.skid_types[skid_id].total_usage += 1
        self.total_used_skids += 1

    # --------- Step 7 & 8 ---------

    def generate_subsequences(self):
        """
        7. For each used skid type:
           - draw number of subsequences (>=1)
           - may exceed number of allowable patterns
           - cap only by total usage
        8. Split total usage into that many positive parts.
        """
        for s in self.skid_types.values():

            if s.total_usage == 0:
                continue

            # subsequence count may exceed allowable patterns
            n = self._draw_positive_int(self.params.dSkidTypeNWindowsMeanDev)

            # Cannot exceed total usage (must allow positive split)
            n = min(n, s.total_usage)

            s.n_subsequences = n

            # Random composition of total_usage into n positive integers
            if n == 1:
                s.subsequences = [s.total_usage]
                continue

            cuts = sorted(random.sample(range(1, s.total_usage), n - 1))

            parts = []
            prev = 0
            for c in cuts + [s.total_usage]:
                parts.append(c - prev)
                prev = c

            s.subsequences = parts

    # --------- Step 9 ---------

    def build_overall_sequence(self) -> List[int]:
        """
        9. Build sequence by shuffling whole subsequences (blocks),
           not individual skid units.
        """
        blocks = []

        for s in self.skid_types.values():
            for size in s.subsequences:
                # Each block is a contiguous identical skid type
                blocks.append([s.id] * size)

        # Shuffle blocks (not flattened list)
        random.shuffle(blocks)

        # Flatten blocks preserving block integrity
        sequence = [x for block in blocks for x in block]

        # Safety check
        if len(sequence) != self.params.nSlots:
            raise RuntimeError("Final sequence length mismatch")

        return sequence

    # --------- Step 10 ---------
    def generate_colors(self):
        self.color_spec_simple = [[] for cc in self.params.nColorsSimple]
        self.color_spec_MAX = []
        for s in self.patterns.values():
            if random.random() < self.params.pUsingColorMax:  # All int's to add +1
                self.color_spec_MAX.append(
                    random.randint(0, self.params.nColorsMax - 1)
                )
            else:
                self.color_spec_MAX.append(-1)  # No using color MAX
            for cc in range(len(self.params.nColorsSimple)):
                self.color_spec_simple[cc].append(
                    random.randint(0, self.params.nColorsSimple[cc] - 1)
                )

    # --------- Step 11 ---------
    def generate_costs(self):
        self.pattern_missing_cost = []
        self.pattern_overuse_cost = []
        mm, md = self.params.patternMissingCostMeanDev
        om, od = self.params.patternOveruseCostMeanDev
        for s in self.patterns.values():
            self.pattern_missing_cost.append(
                max(self.params.minCost, random.gauss(mm, math.sqrt(md)))
            )
            self.pattern_overuse_cost.append(
                max(self.params.minCost, random.gauss(om, math.sqrt(od)))
            )

    # --------- Step 12 ---------

    def generate(self) -> InstanceResult:
        """
        Full generation pipeline following steps 1–10.
        """
        self.generate_pattern_demands()
        self.generate_allowable_sets()
        self.assign_min_demands()
        self.fill_remaining_slots()
        self.generate_subsequences()
        sequence = self.build_overall_sequence()

        self.generate_colors()
        self.generate_costs()

        return InstanceResult(
            skid_types=self.skid_types,
            patterns=self.patterns,
            skid_type_usages=[
                self.skid_types[i].total_usage for i in range(self.params.nSkidTypes)
            ],
            sum_min_demands=sum(p.min_demand for p in self.patterns.values()),
            pattern_min_demands=[p.min_demand for p in self.patterns.values()],
            pattern_extra_demands=[p.extra_demand for p in self.patterns.values()],
            overall_sequence=sequence,
            color_spec_simple=self.color_spec_simple,
            color_spec_MAX=self.color_spec_MAX,
            nColorMAXMachines=self.params.nColorMAXMachines,
            nChangeMAXWait=self.params.nChangeMAXWait,
            patternMissingCost=self.pattern_missing_cost,
            patternOveruseCost=self.pattern_overuse_cost,
            colorSimpleChangeCost=self.params.colorSimpleChangeCost,
            colorMAXChangeCost=self.params.colorMAXChangeCost,
        )

Pretty-printing and visualization code#

import pandas as pd
from typing import Optional


def display_instance(
    result: InstanceResult,
    params: InstGenParams,
    max_sequence_display: int = 100,
    show_empty_skids: bool = False,
) -> None:
    """
    Pretty-print instance data for Jupyter Notebook usage.

    Parameters
    ----------
    result : InstanceResult
    params : InstGenParams
    max_sequence_display : int
        Maximum number of sequence entries to display.
    show_empty_skids : bool
        If False, hide skid types with zero usage.
    """

    print("========== INSTANCE SUMMARY ==========")
    print(f"Patterns          : {params.nPatterns}")
    print(f"Skid types        : {params.nSkidTypes}")
    print(f"Slots             : {params.nSlots}")
    print(f"Sum minimal demand: {result.sum_min_demands}")
    print(f"Total usage       : {sum(result.skid_type_usages)}")
    print()

    # ---------------- Patterns ----------------

    pattern_rows = []
    for p in result.patterns.values():
        pattern_rows.append(
            {
                "Pattern": p.id,
                "MinDemand": p.min_demand,
                "ExtraDemand": p.extra_demand,
                "TotalAssigned": p.total_assigned,
                "AllowableSkids": sorted(list(p.allowable_skid_types)),
            }
        )

    df_patterns = pd.DataFrame(pattern_rows)
    print("---------- PATTERNS ----------")
    display(df_patterns.sort_values("Pattern").reset_index(drop=True))
    print()

    # ---------------- Skid Types ----------------

    skid_rows = []
    for s in result.skid_types.values():
        if not show_empty_skids and s.total_usage == 0:
            continue

        skid_rows.append(
            {
                "SkidType": s.id,
                "TotalUsage": s.total_usage,
                "N_Subseq": s.n_subsequences,
                "SubseqSizes": s.subsequences,
                "AllowablePatterns": sorted(list(s.allowable_patterns)),
            }
        )

    df_skids = pd.DataFrame(skid_rows)
    print("---------- SKID TYPES (showing non-merged subsequence sizes) ----------")
    if not df_skids.empty:
        display(df_skids.sort_values("SkidType").reset_index(drop=True))
    else:
        print("(No used skid types)")
    print()

    # ---------------- Overall Sequence ----------------

    print("---------- OVERALL SEQUENCE (some subsequences can be merged) ----------")
    print(f"Length: {len(result.overall_sequence)}")

    s = 0
    i_subseq = 0
    while s < len(result.overall_sequence):
        l_subseq = 1
        s_next = s + 1
        while (
            s_next < len(result.overall_sequence)
            and result.overall_sequence[s_next] == result.overall_sequence[s]
        ):
            l_subseq += 1
            s_next += 1
        print(
            "{}:   Skid type x multiplicity: {} x {}".format(
                i_subseq, result.overall_sequence[s], l_subseq
            )
        )
        result.skid_types[result.overall_sequence[s]].n_subseq_merged += 1
        result.skid_types[result.overall_sequence[s]].subseq_merged.append(l_subseq)
        s = s_next
        i_subseq += 1

    print("======================================")
import matplotlib.pyplot as plt


def visualize_instance_statistics(
    result: InstanceResult, show_empty_skids: bool = False
) -> None:
    """
    Visualize key structural statistics of the generated instance.

    Produces three separate histograms:
      1) Skid type total usage
      2) Subsequence sizes (block lengths)
      3) Number of subsequences per skid type

    Parameters
    ----------
    result : InstanceResult
    show_empty_skids : bool
        If False, exclude skid types with zero usage.
    """

    # -------------------------
    # Collect data
    # -------------------------

    skid_types_with_usage = []
    skid_types_non0 = []
    usages = []
    n_subseq = []
    subseq_sizes = []

    for s in result.skid_types.values():

        if not show_empty_skids and s.total_usage == 0:
            continue

        skid_types_with_usage.append(s.id)
        usages.append(s.total_usage)

        if s.total_usage > 0:
            skid_types_non0.append(s.id)
            n_subseq.append(s.n_subseq_merged)
            subseq_sizes.extend(s.subseq_merged)

    # -------------------------
    # 1. Histogram: Skid Usage
    # -------------------------

    print("Create usage histogram: usages", usages)

    plt.figure()
    plt.bar(skid_types_with_usage, usages, color="green")
    plt.title("Histogram of Skid Type Total Usage")
    plt.xlabel("Skid type")
    plt.ylabel("Usage")
    # plt.set_xticks(skid_types_with_usage)
    plt.show()

    # -------------------------
    # 2. Histogram: Subsequence Sizes
    # -------------------------

    if subseq_sizes:
        plt.figure()
        plt.hist(subseq_sizes, max(subseq_sizes), color="red")
        plt.title("Histogram of Subsequence Sizes")
        plt.xlabel("Subsequence Size (block length)")
        plt.ylabel("Frequency")
        plt.show()
    else:
        print("No subsequences to display.")

    # -------------------------
    # 3. Histogram: Number of Subsequences per Skid
    # -------------------------

    if n_subseq:
        plt.figure()
        plt.bar(skid_types_non0, n_subseq)
        plt.title("Histogram of Number of Subsequences per Skid Type")
        plt.ylabel("Number of Subsequences")
        plt.xlabel("Skid type")
        plt.show()
    else:
        print("No subsequence-count data to display.")

Generate & visualize data#

params = InstGenParams()
generator = InstanceGenerator(params)

instance = generator.generate()
display_instance(instance, params)
========== INSTANCE SUMMARY ==========
Patterns          : 5
Skid types        : 4
Slots             : 50
Sum minimal demand: 6
Total usage       : 50

---------- PATTERNS ----------
Pattern MinDemand ExtraDemand TotalAssigned AllowableSkids
0 0 1 9 9 [0]
1 1 1 14 12 [1, 2, 3]
2 2 1 1 2 [0]
3 3 2 8 15 [1, 2, 3]
4 4 1 11 12 [2]
---------- SKID TYPES (showing non-merged subsequence sizes) ----------
SkidType TotalUsage N_Subseq SubseqSizes AllowablePatterns
0 0 11 5 [2, 1, 4, 2, 2] [0, 2]
1 1 10 1 [10] [1, 3]
2 2 22 1 [22] [1, 3, 4]
3 3 7 1 [7] [1, 3]
---------- OVERALL SEQUENCE (some subsequences can be merged) ----------
Length: 50
0:   Skid type x multiplicity: 0 x 2
1:   Skid type x multiplicity: 3 x 7
2:   Skid type x multiplicity: 0 x 9
3:   Skid type x multiplicity: 2 x 22
4:   Skid type x multiplicity: 1 x 10
======================================
visualize_instance_statistics(instance, True)
Create usage histogram: usages [11, 10, 22, 7]
../_images/8315441dd72fb70e33130540b286867ac2ac0503f5ae6e8796296cf553a9cec0.png ../_images/bab289230d535eed44cd888be039e6abfca97b67d48f61a6537b200d5774b198.png ../_images/02a773d3f5f63c62c459cfd3ed80ba1da8fda138ce03218766667d2e870dfe2d.png

Load data directly from Python data structures using amplpy#

import numpy as np
import pandas as pd


def load_instance_into_ampl_vectorized_1based(
    ampl: AMPL, result: InstanceResult, params: InstGenParams
) -> None:
    """
    Vectorized AMPL loader with 0→1 index shifting
    for skid types and patterns.
    """

    # ------------------------------------------------
    # 1. Shifted SKID_TYPES and PATTERNS
    # ------------------------------------------------

    skid_ids = np.array(list(result.skid_types.keys()), dtype=int) + 1
    pattern_ids = np.array(list(result.patterns.keys()), dtype=int) + 1

    ampl.set["SKID_TYPES"] = skid_ids
    ampl.set["PATTERNS"] = pattern_ids

    # ------------------------------------------------
    # 2. Scalar parameter
    # ------------------------------------------------

    ampl.param["n_slots"] = params.nSlots

    # ------------------------------------------------
    # 3. Slot → Skid mapping (shift skid values)
    # ------------------------------------------------

    slot_df = pd.DataFrame(
        {
            "SLOTS": np.arange(1, params.nSlots + 1),
            "slot_skid_type": np.array(result.overall_sequence, dtype=int) + 1,
        }
    ).set_index("SLOTS")

    ampl.setData(slot_df)

    # ------------------------------------------------
    # 4. SKID_TYPE_PATTERNS relation (shift both sides)
    # ------------------------------------------------

    rows = []

    for skid_id, skid in result.skid_types.items():
        skid_shifted = skid_id + 1
        patterns_shifted = np.array(list(skid.allowable_patterns), dtype=int) + 1
        ampl.set["SKID_TYPE_PATTERNS"][skid_shifted] = patterns_shifted

    # ------------------------------------------------
    # 5. Pattern demand parameters (shift index)
    # ------------------------------------------------

    demand_df = pd.DataFrame(
        {
            "PATTERNS": pattern_ids,
            "pattern_demand_minimum": [p.min_demand for p in result.patterns.values()],
            "pattern_demand_extra": [p.extra_demand for p in result.patterns.values()],
        }
    ).set_index("PATTERNS")

    ampl.setData(demand_df)

    # ------------------------------------------------
    # 6. Colors
    # ------------------------------------------------

    ampl.set["COLOR_SIMPLE_CATEGORIES"] = range(1, len(result.color_spec_simple) + 1)
    ampl.set["COLORS_MAX"] = range(1, params.nColorsMax + 1)
    ampl.set["COLOR_MAX_MACHINES"] = range(1, result.nColorMAXMachines + 1)
    for cc in range(len(result.color_spec_simple)):
        ampl.set["COLORS_SIMPLE"][cc + 1] = range(1, params.nColorsSimple[cc] + 1)
        for p in range(len(result.patternMissingCost)):  # Rather slow
            ampl.param["color_spec_simple"][p + 1, cc + 1] = (
                result.color_spec_simple[cc][p] + 1
            )
    ampl.param["color_spec_MAX"] = np.array(list(result.color_spec_MAX), dtype=int) + 1
    ampl.param["wait_change_MAX"] = result.nChangeMAXWait

    # ------------------------------------------------
    # 6. Colors
    # ------------------------------------------------

    ampl.param["pattern_missing_cost"] = np.array(
        list(result.patternMissingCost), dtype=float
    )
    ampl.param["pattern_overuse_cost"] = np.array(
        list(result.patternOveruseCost), dtype=float
    )
    ampl.param["color_simple_change_cost"] = np.array(
        list(result.colorSimpleChangeCost), dtype=float
    )
    ampl.param["color_MAX_change_cost"] = result.colorMAXChangeCost
ampl = AMPL()
ampl.read("pccsp.mod")

load_instance_into_ampl_vectorized_1based(ampl, instance, params)

Solve with FICO Xpress#

First, let us solve the instance with default settings.

ampl.option["solver"] = "xpress"
ampl.option["mp_options"] = "outlev=1 " + "lim:time=60"

ampl.snapshot(
    "pccsp_snapshot.run"
)  # Debug feature: save AMPL state, including the instance

ampl.solve()
XPRESS 9.8.0 (46.01.01):   tech:outlev = 1
  lim:time = 60

AMPL MP initial flat model has 710 variables (300 integer, 395 binary);
Objectives: 1 linear; 
Constraints:  10 linear;
Algebraic expressions:  5 count;
Logical expressions:  917 conditional (in)equalitie(s); 297 and; 269 not; 589 or;

AMPL MP final model has 2981 variables (894 integer, 2072 binary);
Objectives: 1 linear; 
Constraints:  379 linear;
Logical expressions:  297 and; 617 indeq; 589 or;


FICO Xpress v9.8.0, Hyper, solve started 16:56:30, Mar 3, 2026
Heap usage: 1398KB (peak 1398KB, 54KB system)
Minimizing MILP  using up to 8 threads and up to 16GB memory, with these control settings:
TIMELIMIT = 60
Original problem has:
       996 rows         2981 cols         2270 elements      2178 entities
       617 inds
       886 gencons
Presolved problem has:
      1750 rows         1168 cols         7208 elements      1153 entities
LP relaxation tightened
Presolve finished in 0 seconds
Heap usage: 5518KB (peak 6248KB, 190KB system)

Coefficient range                    original                 solved        
  Coefficients   [min,max] : [ 1.00e+00,  5.00e+00] / [ 6.25e-02,  1.88e+00]
  RHS and bounds [min,max] : [ 1.00e+00,  1.50e+01] / [ 2.50e-01,  3.90e+01]
  Objective      [min,max] : [ 6.55e-01,  1.00e+01] / [ 6.55e-01,  1.00e+01]
Autoscaling applied standard scaling

Symmetric problem: generators: 2, support set: 711
 Number of orbits: 237, largest orbit: 3
 Row orbits: 326, row support: 978
Will try to keep branch and bound tree memory usage below 15.1GB
 *** Solution found:   387.306070   Time:   0.08    Heuristic: e ***
Starting concurrent solve with dual (1 thread)

 Concurrent-Solve,   0s
            Dual        
    objective   sum inf 
 P  8.8582631   .0000000
                        
------- optimal --------
Concurrent statistics:
           Dual: 1286 simplex iterations, 0.02s
Optimal solution found
 
   Its         Obj Value      S   Ninf  Nneg        Sum Inf  Time
  1286          8.858263      P      0     0        .000000     0
Dual solved problem
  1286 simplex iterations in 0.02 seconds at time 0

Final objective                       : 8.858263143934892e+00
  Max primal violation      (abs/rel) : 1.110e-15 / 1.110e-15
  Max dual violation        (abs/rel) : 7.105e-15 / 7.105e-15
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Starting root cutting & heuristics
Deterministic mode with up to 2 additional threads
 
 Its Type    BestSoln    BestBound   Sols    Add    Del     Gap     GInf   Time
a          174.620879     8.858263      2                 94.93%       0      0
   1  K    174.620879    10.031479      2    651      0   94.26%     415      0
P          173.040639    10.031479      3                 94.20%       0      0
P          170.694632    10.031479      4                 94.12%       0      0
P          129.053008    10.031479      5                 92.23%       0      0
P          108.266420    10.031479      6                 90.73%       0      0
P          107.266420    10.031479      7                 90.65%       0      0
P          106.266420    10.031479      8                 90.56%       0      0
P          105.266420    10.031479      9                 90.47%       0      0
P           83.409770    10.031479     10                 87.97%       0      0
P           82.409770    10.031479     11                 87.83%       0      0
P           79.053727    10.031479     12                 87.31%       0      0
P           78.829529    10.031479     13                 87.27%       0      0
P           77.829529    10.031479     14                 87.11%       0      0
P           74.249288    10.031479     15                 86.49%       0      0
   2  K     74.249288    10.618005     15    244    447   85.70%     656      0
P           66.669048    10.618005     16                 84.07%       0      0
P           64.669048    10.618005     17                 83.58%       0      0
P           54.508566    10.618005     18                 80.52%       0      0
P           53.732763    10.618005     19                 80.24%       0      0
P           53.508566    10.618005     20                 80.16%       0      0
P           52.508566    10.618005     21                 79.78%       0      0
P           51.508566    10.618005     22                 79.39%       0      0
P           44.928325    10.618005     23                 76.37%       0      0
P           42.928325    10.618005     24                 75.27%       0      0
   3  K     42.928325    10.900395     24    136    174   74.61%     536      0
P           41.928325    10.900395     25                 74.00%       0      0
P           40.928325    10.900395     26                 73.37%       0      0
P           39.928325    10.900395     27                 72.70%       0      0
   4  K     39.928325    11.310295     27    137    104   71.67%     468      0
P           38.928325    11.310295     28                 70.95%       0      0
P           36.928325    11.310295     29                 69.37%       0      0
   5  K     36.928325    11.374333     29    211    119   69.20%     471      0
   6  K     36.928325    11.424315     29     86    146   69.06%     476      0
   7  K     36.928325    11.450172     29     73     69   68.99%     534      0
   8  K     36.928325    11.527816     29     88     49   68.78%     522      0
   9  K     36.928325    11.653084     29    146    143   68.44%     530      0
q           22.858263    11.753555     30                 48.58%       0      0
  10  K     22.858263    11.753555     30     83     79   48.58%     525      0
  11  K     22.858263    11.930751     30     78     71   47.81%     494      0
  12  K     22.858263    12.167057     30    205    127   46.77%     422      0
  13  K     22.858263    12.250232     30    173    148   46.41%     459      0
  14  K     22.858263    12.367191     30    164    129   45.90%     324      0
  15  K     22.858263    12.528982     30    117    166   45.19%     395      0
  16  K     22.858263    12.573604     30     73    119   44.99%     290      0
  17  K     22.858263    12.592551     30     56     30   44.91%     285      0
  18  K     22.858263    12.601555     30     26     50   44.87%     278      0
  19  K     22.858263    12.603192     30     31     18   44.86%     275      0
  20  K     22.858263    12.609901     30     18     20   44.83%     273      0
  21  K     22.858263    12.613684     30     20     30   44.82%     287      0
  22  K     22.858263    12.615898     30     39     46   44.81%     302      0
  23  K     22.858263    12.618380     30     35     31   44.80%     293      0
  24  K     22.858263    12.620199     30     32     21   44.79%     293      0
  25  K     22.858263    12.634125     30     26    264   44.73%     269      0
  26  G     22.858263    12.774378     30     40      0   44.11%     270      0
  27  G     22.858263    12.923963     30     53     99   43.46%     307      0
 
Cuts in the matrix         : 342
Cut elements in the matrix : 8244

Performing root presolve...

Reduced problem has:    1301 rows     551 columns     10045 elements
Presolve dropped   :     791 rows     617 columns      5407 elements
Symmetric problem: generators: 2, support set: 153
 Number of orbits: 51, largest orbit: 3
 Row orbits: 89, row support: 267
Will try to keep branch and bound tree memory usage below 15.1GB
Crash basis containing 147 structural columns created
 
   Its         Obj Value      S   Ninf  Nneg        Sum Inf  Time
  8141          9.114682      P      0     0        .000000     0
Optimal solution found
Dual solved problem
  8141 simplex iterations in 0.01 seconds at time 0

Final objective                       : 9.114682343403359e+00
  Max primal violation      (abs/rel) : 2.220e-16 / 2.220e-16
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Starting root cutting & heuristics
Deterministic mode with up to 2 additional threads
 
 Its Type    BestSoln    BestBound   Sols    Add    Del     Gap     GInf   Time
   1  K     22.858263    13.126183     30     64     99   42.58%     287      0
   2  K     22.858263    13.199209     30     30    181   42.26%     321      0
Heuristic search 'R' started
Heuristic search 'R' stopped
 
Cuts in the matrix         : 156
Cut elements in the matrix : 3195

Starting tree search.
Deterministic mode with up to 8 running threads and up to 16 tasks.
Heap usage: 12MB (peak 37MB, 608KB system)
 
    Node     BestSoln    BestBound   Sols Active  Depth     Gap     GInf   Time
       1    22.858263    13.259863     30      2      1   41.99%     297      0
       2    22.858263    13.416274     30      2      3   41.31%     310      0
       3    22.858263    13.515141     30      3      4   40.87%     279      0
       4    22.858263    13.570937     30      4      3   40.63%     268      0
       5    22.858263    13.570937     30      5      4   40.63%     232      0
       6    22.858263    13.570937     30      6      5   40.63%     181      0
       7    22.858263    13.570937     30      7      5   40.63%     247      0
       8    22.858263    13.970958     30      8      4   38.88%     288      0
       9    22.858263    13.970958     30      9      6   38.88%     243      0
      10    22.858263    13.986500     30     10      6   38.81%     201      0
      20    22.858263    13.986500     30     18      9   38.81%     287      1
      30    22.858263    14.098909     30     26      8   38.32%     206      1
      42    22.858263    14.098909     30     36      9   38.32%      93      1
      52    22.858263    14.098909     30     45     14   38.32%     231      1
      62    22.858263    14.098909     30     48     15   38.32%     199      1
      73    22.858263    14.098909     30     56     20   38.32%      60      1
      83    22.858263    14.098909     30     79     18   38.32%     192      1
      93    22.858263    14.098909     30     89     19   38.32%     151      1
g    101    21.858263    14.098909     31     98     35   35.50%       0      1
Elapsed time (sec): 1, estimated tree completion: 0.00000
Heap usage: 40MB (peak 40MB, 728KB system)
B&B tree size: 337k total
 
    Node     BestSoln    BestBound   Sols Active  Depth     Gap     GInf   Time
     103    21.858263    14.098909     31     99     21   35.50%     102      1
q    103    19.858263    14.098909     32    100     36   29.00%       0      1
g    185    17.928325    14.098909     33    111     25   21.36%       0      1
     229    17.928325    14.098909     33     95      1   21.36%       2      1
     329    17.928325    14.098909     33    106      1   21.36%       2      1
     429    17.928325    14.205945     33    168     21   20.76%     102      1
     535    17.928325    14.205945     33    181     17   20.76%     187      1
     641    17.928325    14.237536     33    197     15   20.59%      35      1
     751    17.928325    14.237536     33    216     20   20.59%      28      1
     854    17.928325    14.237536     33    241     17   20.59%      79      1
     956    17.928325    14.341585     33    287     19   20.01%     141      1
    1063    17.928325    14.341585     33    292     16   20.01%      37      1
    1163    17.928325    14.356895     33    322     15   19.92%     164      1
    1265    17.928325    14.356895     33    348     14   19.92%     153      2
    1371    17.928325    14.356895     33    405     26   19.92%      79      2
    1471    17.928325    14.356895     33    427     21   19.92%     145      2
    1581    17.928325    14.356895     33    434     14   19.92%     110      2
    1685    17.928325    14.356895     33    460     24   19.92%      58      2
    1787    17.928325    14.449573     33    519     15   19.40%     139      2
    1896    17.928325    14.467161     33    552     18   19.31%      66      2
Elapsed time (sec): 2, estimated tree completion: 0.36186
Heap usage: 128MB (peak 128MB, 1098KB system)
B&B tree size: 2.5MB total
 
    Node     BestSoln    BestBound   Sols Active  Depth     Gap     GInf   Time
    1999    17.928325    14.467161     33    584     28   19.31%      21      2
    2107    17.928325    14.467161     33    616     17   19.31%     148      2
    2211    17.928325    14.467161     33    628     18   19.31%     104      2
    2314    17.928325    14.544106     33    650     32   18.88%      51      2
g   2343    16.928325    14.544106     34    656     28   14.08%       0      2
    2713    16.928325    14.544106     34    303      1   14.08%       2      2
    2814    16.928325    14.544407     34    315     28   14.08%      52      2
    2924    16.928325    14.544407     34    337     24   14.08%      34      2
    3028    16.928325    14.544407     34    347      1   14.08%       2      2
    3135    16.928325    14.544407     34    354     25   14.08%      13      2
    3235    16.928325    14.544407     34    363     16   14.08%      16      2
    3342    16.928325    14.544407     34    379     25   14.08%      20      2
    3448    16.928325    14.619793     34    394     19   13.64%      85      2
    3557    16.928325    14.619793     34    413     20   13.64%      69      2
    3661    16.928325    14.688055     34    415      8   13.23%     170      2
    3773    16.928325    14.725343     34    438     27   13.01%       8      2
    3873    16.928325    14.725343     34    465     12   13.01%      52      3
    3975    16.928325    14.725343     34    447     21   13.01%      73      3
    4087    16.928325    14.746742     34    454     24   12.89%      62      3
    4187    16.928325    14.772653     34    455     25   12.73%      63      3
Elapsed time (sec): 3, estimated tree completion: 0.67645
Heap usage: 127MB (peak 128MB, 1098KB system)
B&B tree size: 2.7MB total
 
    Node     BestSoln    BestBound   Sols Active  Depth     Gap     GInf   Time
    4288    16.928325    14.772653     34    480     11   12.73%     163      3
    4388    16.928325    14.807701     34    488     18   12.53%      91      3
    4488    16.928325    14.807701     34    487     28   12.53%      45      3
    4594    16.928325    14.807701     34    488     17   12.53%     185      3
    4699    16.928325    14.807701     34    488     28   12.53%      13      3
    4803    16.928325    14.807701     34    501     23   12.53%      18      3
    4923    16.928325    14.907555     34    512     31   11.94%       8      3
    5023    16.928325    14.907555     34    529     26   11.94%      95      3
    5125    16.928325    14.907555     34    510     18   11.94%      15      3
    5243    16.928325    14.943412     34    507     28   11.73%      68      3
    5348    16.928325    14.943412     34    487     21   11.73%      65      3
    5448    16.928325    14.943412     34    466     14   11.73%     106      3
    5548    16.928325    14.943412     34    455     13   11.73%     118      3
    5649    16.928325    14.982786     34    435     15   11.49%      71      3
    5749    16.928325    14.982786     34    421     21   11.49%      74      3
    5849    16.928325    14.982786     34    400     21   11.49%     121      3
    5955    16.928325    15.067916     34    393     25   10.99%      58      3
    6055    16.928325    15.067916     34    371     19   10.99%      54      3
    6158    16.928325    15.068970     34    340     27   10.98%      70      3
    6260    16.928325    15.068970     34    330     18   10.98%      67      3
Elapsed time (sec): 3, estimated tree completion: 0.86516
Heap usage: 129MB (peak 129MB, 1098KB system)
B&B tree size: 2.8MB total
 
    Node     BestSoln    BestBound   Sols Active  Depth     Gap     GInf   Time
    6365    16.928325    15.068970     34    295     21   10.98%     126      3
    6465    16.928325    15.068970     34    255     16   10.98%      29      3
    6565    16.928325    15.068970     34    240     20   10.98%     179      4
    6665    16.928325    15.094992     34    219     14   10.83%      86      4
    6768    16.928325    15.113909     34    150     16   10.72%      89      4
    6868    16.928325    15.113909     34     74     15   10.72%     101      4
    6968    16.928325    15.135292     34     55     15   10.59%      18      4
    7073    16.928325    15.253468     34     60     14    9.89%      85      4
    7174    16.928325    15.253468     34     42     24    9.89%      84      4
    7276    16.928325    15.253468     34     30     12    9.89%      41      4
    7379    16.928325    15.253468     34     13     12    9.89%     200      4
 *** Search completed ***
Uncrunching matrix
Final MIP objective                   : 1.692832483996361e+01
Final MIP bound                       : 1.692830791163877e+01
  Solution time / primaldual integral :      4.34s/ 27.314068%
  Work / work units per second        :      5.66 /      1.30
  Number of solutions found / nodes   :        34 /      7449
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max integer violation     (abs    ) : 6.661e-16
XPRESS 9.8.0 (46.01.01): optimal solution; objective 16.92832484
494831 simplex iterations
7449 branching nodes
absmipgap=1.69283e-05, relmipgap=1e-06

Check solution in AMPL#

The below code displays AMPL’s solution correctness indicators (in particular, tolerance violations). Additional Python code can be used for independent checking.

print("AMPL solve result:", ampl.solve_result, " code:", ampl.solve_result_num)

print(
    "Minimal variable bound slack:",
    ampl.get_value("min {i in 1.._nvars} _var[i].slack"),
)
print(
    "Minimal algebraic constraint slack:",
    ampl.get_value("min {i in 1.._ncons} _con[i].slack"),
)
print(
    "Minimal logical constraint value:",
    ampl.get_value("min {i in 1.._nlogcons} _logcon[i].val"),
)

ampl.eval("display _varname, _var.slack;")
ampl.eval("display _conname, _con.slack;")
ampl.eval("display _logconname, _logcon.val;")
AMPL solve result: solved  code: 0
Minimal variable bound slack: 0
Minimal algebraic constraint slack: 0
Minimal logical constraint value: 1
:                     _varname                    _var.slack     :=
1     'slot_pattern[1]'                           2
2     'slot_pattern[2]'                           2
3     'slot_pattern[3]'                           2
4     'slot_pattern[4]'                           2
5     'slot_pattern[5]'                           2
6     'slot_pattern[6]'                           2
7     'slot_pattern[7]'                           2
8     'slot_pattern[8]'                           2
9     'slot_pattern[9]'                           2
10    'slot_pattern[10]'                          1
11    'slot_pattern[11]'                          1
12    'slot_pattern[12]'                          1
13    'slot_pattern[13]'                          1
14    'slot_pattern[14]'                          1
15    'slot_pattern[15]'                          1
16    'slot_pattern[16]'                          1
17    'slot_pattern[17]'                          1
18    'slot_pattern[18]'                          1
19    'slot_pattern[19]'                          0
20    'slot_pattern[20]'                          0
21    'slot_pattern[21]'                          0
22    'slot_pattern[22]'                          0
23    'slot_pattern[23]'                          0
24    'slot_pattern[24]'                          0
25    'slot_pattern[25]'                          0
26    'slot_pattern[26]'                          0
27    'slot_pattern[27]'                          0
28    'slot_pattern[28]'                          0
29    'slot_pattern[29]'                          0
30    'slot_pattern[30]'                          0
31    'slot_pattern[31]'                          1
32    'slot_pattern[32]'                          1
33    'slot_pattern[33]'                          1
34    'slot_pattern[34]'                          1
35    'slot_pattern[35]'                          1
36    'slot_pattern[36]'                          1
37    'slot_pattern[37]'                          1
38    'slot_pattern[38]'                          0
39    'slot_pattern[39]'                          1
40    'slot_pattern[40]'                          1
41    'slot_pattern[41]'                          1
42    'slot_pattern[42]'                          0
43    'slot_pattern[43]'                          2
44    'slot_pattern[44]'                          2
45    'slot_pattern[45]'                          2
46    'slot_pattern[46]'                          2
47    'slot_pattern[47]'                          2
48    'slot_pattern[48]'                          2
49    'slot_pattern[49]'                          2
50    'slot_pattern[50]'                          2
51    'slot_color_spec_MAX[1,1]'                  1
52    'slot_color_spec_MAX[1,2]'                  0
53    'slot_color_spec_MAX[1,3]'                  1
54    'slot_color_spec_MAX[2,1]'                  1
55    'slot_color_spec_MAX[2,2]'                  0
56    'slot_color_spec_MAX[2,3]'                  1
57    'slot_color_spec_MAX[3,1]'                  1
58    'slot_color_spec_MAX[3,2]'                  0
59    'slot_color_spec_MAX[3,3]'                  1
60    'slot_color_spec_MAX[4,1]'                  1
61    'slot_color_spec_MAX[4,2]'                  0
62    'slot_color_spec_MAX[4,3]'                  1
63    'slot_color_spec_MAX[5,1]'                  1
64    'slot_color_spec_MAX[5,2]'                  0
65    'slot_color_spec_MAX[5,3]'                  1
66    'slot_color_spec_MAX[6,1]'                  1
67    'slot_color_spec_MAX[6,2]'                  0
68    'slot_color_spec_MAX[6,3]'                  1
69    'slot_color_spec_MAX[7,1]'                  1
70    'slot_color_spec_MAX[7,2]'                  0
71    'slot_color_spec_MAX[7,3]'                  1
72    'slot_color_spec_MAX[8,1]'                  1
73    'slot_color_spec_MAX[8,2]'                  0
74    'slot_color_spec_MAX[8,3]'                  1
75    'slot_color_spec_MAX[9,1]'                  1
76    'slot_color_spec_MAX[9,2]'                  0
77    'slot_color_spec_MAX[9,3]'                  1
78    'slot_color_spec_MAX[10,1]'                 1
79    'slot_color_spec_MAX[10,2]'                 0
80    'slot_color_spec_MAX[10,3]'                 1
81    'slot_color_spec_MAX[11,1]'                 1
82    'slot_color_spec_MAX[11,2]'                 0
83    'slot_color_spec_MAX[11,3]'                 1
84    'slot_color_spec_MAX[12,1]'                 1
85    'slot_color_spec_MAX[12,2]'                 0
86    'slot_color_spec_MAX[12,3]'                 1
87    'slot_color_spec_MAX[13,1]'                 1
88    'slot_color_spec_MAX[13,2]'                 0
89    'slot_color_spec_MAX[13,3]'                 1
90    'slot_color_spec_MAX[14,1]'                 1
91    'slot_color_spec_MAX[14,2]'                 0
92    'slot_color_spec_MAX[14,3]'                 1
93    'slot_color_spec_MAX[15,1]'                 1
94    'slot_color_spec_MAX[15,2]'                 0
95    'slot_color_spec_MAX[15,3]'                 1
96    'slot_color_spec_MAX[16,1]'                 1
97    'slot_color_spec_MAX[16,2]'                 0
98    'slot_color_spec_MAX[16,3]'                 1
99    'slot_color_spec_MAX[17,1]'                 1
100   'slot_color_spec_MAX[17,2]'                 0
101   'slot_color_spec_MAX[17,3]'                 1
102   'slot_color_spec_MAX[18,1]'                 1
103   'slot_color_spec_MAX[18,2]'                 0
104   'slot_color_spec_MAX[18,3]'                 1
105   'slot_color_spec_MAX[19,1]'                 1
106   'slot_color_spec_MAX[19,2]'                 0
107   'slot_color_spec_MAX[19,3]'                 1
108   'slot_color_spec_MAX[20,1]'                 1
109   'slot_color_spec_MAX[20,2]'                 0
110   'slot_color_spec_MAX[20,3]'                 1
111   'slot_color_spec_MAX[21,1]'                 1
112   'slot_color_spec_MAX[21,2]'                 0
113   'slot_color_spec_MAX[21,3]'                 1
114   'slot_color_spec_MAX[22,1]'                 1
115   'slot_color_spec_MAX[22,2]'                 0
116   'slot_color_spec_MAX[22,3]'                 1
117   'slot_color_spec_MAX[23,1]'                 1
118   'slot_color_spec_MAX[23,2]'                 0
119   'slot_color_spec_MAX[23,3]'                 1
120   'slot_color_spec_MAX[24,1]'                 1
121   'slot_color_spec_MAX[24,2]'                 0
122   'slot_color_spec_MAX[24,3]'                 1
123   'slot_color_spec_MAX[25,1]'                 1
124   'slot_color_spec_MAX[25,2]'                 0
125   'slot_color_spec_MAX[25,3]'                 1
126   'slot_color_spec_MAX[26,1]'                 1
127   'slot_color_spec_MAX[26,2]'                 0
128   'slot_color_spec_MAX[26,3]'                 1
129   'slot_color_spec_MAX[27,1]'                 1
130   'slot_color_spec_MAX[27,2]'                 0
131   'slot_color_spec_MAX[27,3]'                 1
132   'slot_color_spec_MAX[28,1]'                 1
133   'slot_color_spec_MAX[28,2]'                 0
134   'slot_color_spec_MAX[28,3]'                 1
135   'slot_color_spec_MAX[29,1]'                 1
136   'slot_color_spec_MAX[29,2]'                 0
137   'slot_color_spec_MAX[29,3]'                 1
138   'slot_color_spec_MAX[30,1]'                 1
139   'slot_color_spec_MAX[30,2]'                 0
140   'slot_color_spec_MAX[30,3]'                 1
141   'slot_color_spec_MAX[31,1]'                 1
142   'slot_color_spec_MAX[31,2]'                 0
143   'slot_color_spec_MAX[31,3]'                 1
144   'slot_color_spec_MAX[32,1]'                 1
145   'slot_color_spec_MAX[32,2]'                 0
146   'slot_color_spec_MAX[32,3]'                 1
147   'slot_color_spec_MAX[33,1]'                 1
148   'slot_color_spec_MAX[33,2]'                 0
149   'slot_color_spec_MAX[33,3]'                 1
150   'slot_color_spec_MAX[34,1]'                 1
151   'slot_color_spec_MAX[34,2]'                 0
152   'slot_color_spec_MAX[34,3]'                 1
153   'slot_color_spec_MAX[35,1]'                 1
154   'slot_color_spec_MAX[35,2]'                 0
155   'slot_color_spec_MAX[35,3]'                 1
156   'slot_color_spec_MAX[36,1]'                 1
157   'slot_color_spec_MAX[36,2]'                 0
158   'slot_color_spec_MAX[36,3]'                 1
159   'slot_color_spec_MAX[37,1]'                 1
160   'slot_color_spec_MAX[37,2]'                 0
161   'slot_color_spec_MAX[37,3]'                 1
162   'slot_color_spec_MAX[38,1]'                 1
163   'slot_color_spec_MAX[38,2]'                 0
164   'slot_color_spec_MAX[38,3]'                 1
165   'slot_color_spec_MAX[39,1]'                 1
166   'slot_color_spec_MAX[39,2]'                 0
167   'slot_color_spec_MAX[39,3]'                 1
168   'slot_color_spec_MAX[40,1]'                 1
169   'slot_color_spec_MAX[40,2]'                 0
170   'slot_color_spec_MAX[40,3]'                 1
171   'slot_color_spec_MAX[41,1]'                 1
172   'slot_color_spec_MAX[41,2]'                 0
173   'slot_color_spec_MAX[41,3]'                 1
174   'slot_color_spec_MAX[42,1]'                 1
175   'slot_color_spec_MAX[42,2]'                 0
176   'slot_color_spec_MAX[42,3]'                 1
177   'slot_color_spec_MAX[43,1]'                 1
178   'slot_color_spec_MAX[43,2]'                 0
179   'slot_color_spec_MAX[43,3]'                 1
180   'slot_color_spec_MAX[44,1]'                 1
181   'slot_color_spec_MAX[44,2]'                 0
182   'slot_color_spec_MAX[44,3]'                 1
183   'slot_color_spec_MAX[45,1]'                 1
184   'slot_color_spec_MAX[45,2]'                 0
185   'slot_color_spec_MAX[45,3]'                 1
186   'slot_color_spec_MAX[46,1]'                 1
187   'slot_color_spec_MAX[46,2]'                 0
188   'slot_color_spec_MAX[46,3]'                 1
189   'slot_color_spec_MAX[47,1]'                 1
190   'slot_color_spec_MAX[47,2]'                 0
191   'slot_color_spec_MAX[47,3]'                 1
192   'slot_color_spec_MAX[48,1]'                 1
193   'slot_color_spec_MAX[48,2]'                 0
194   'slot_color_spec_MAX[48,3]'                 1
195   'slot_color_spec_MAX[49,1]'                 1
196   'slot_color_spec_MAX[49,2]'                 0
197   'slot_color_spec_MAX[49,3]'                 1
198   'slot_color_spec_MAX[50,1]'                 1
199   'slot_color_spec_MAX[50,2]'                 0
200   'slot_color_spec_MAX[50,3]'                 1
201   'slot_color_MAX_machine_available[1,1]'     0
202   'slot_color_MAX_machine_available[1,2]'     0
203   'slot_color_MAX_machine_available[1,3]'     0
204   'slot_color_MAX_machine_available[2,1]'     0
205   'slot_color_MAX_machine_available[2,2]'     0
206   'slot_color_MAX_machine_available[2,3]'     0
207   'slot_color_MAX_machine_available[3,1]'     0
208   'slot_color_MAX_machine_available[3,2]'     0
209   'slot_color_MAX_machine_available[3,3]'     0
210   'slot_color_MAX_machine_available[4,1]'     0
211   'slot_color_MAX_machine_available[4,2]'     0
212   'slot_color_MAX_machine_available[4,3]'     0
213   'slot_color_MAX_machine_available[5,1]'     0
214   'slot_color_MAX_machine_available[5,2]'     0
215   'slot_color_MAX_machine_available[5,3]'     0
216   'slot_color_MAX_machine_available[6,1]'     0
217   'slot_color_MAX_machine_available[6,2]'     0
218   'slot_color_MAX_machine_available[6,3]'     0
219   'slot_color_MAX_machine_available[7,1]'     0
220   'slot_color_MAX_machine_available[7,2]'     0
221   'slot_color_MAX_machine_available[7,3]'     0
222   'slot_color_MAX_machine_available[8,1]'     0
223   'slot_color_MAX_machine_available[8,2]'     0
224   'slot_color_MAX_machine_available[8,3]'     0
225   'slot_color_MAX_machine_available[9,1]'     0
226   'slot_color_MAX_machine_available[9,2]'     0
227   'slot_color_MAX_machine_available[9,3]'     0
228   'slot_color_MAX_machine_available[10,1]'    0
229   'slot_color_MAX_machine_available[10,2]'    0
230   'slot_color_MAX_machine_available[10,3]'    0
231   'slot_color_MAX_machine_available[11,1]'    0
232   'slot_color_MAX_machine_available[11,2]'    0
233   'slot_color_MAX_machine_available[11,3]'    0
234   'slot_color_MAX_machine_available[12,1]'    0
235   'slot_color_MAX_machine_available[12,2]'    0
236   'slot_color_MAX_machine_available[12,3]'    0
237   'slot_color_MAX_machine_available[13,1]'    0
238   'slot_color_MAX_machine_available[13,2]'    0
239   'slot_color_MAX_machine_available[13,3]'    0
240   'slot_color_MAX_machine_available[14,1]'    0
241   'slot_color_MAX_machine_available[14,2]'    0
242   'slot_color_MAX_machine_available[14,3]'    0
243   'slot_color_MAX_machine_available[15,1]'    0
244   'slot_color_MAX_machine_available[15,2]'    0
245   'slot_color_MAX_machine_available[15,3]'    0
246   'slot_color_MAX_machine_available[16,1]'    0
247   'slot_color_MAX_machine_available[16,2]'    0
248   'slot_color_MAX_machine_available[16,3]'    0
249   'slot_color_MAX_machine_available[17,1]'    0
250   'slot_color_MAX_machine_available[17,2]'    0
251   'slot_color_MAX_machine_available[17,3]'    0
252   'slot_color_MAX_machine_available[18,1]'    0
253   'slot_color_MAX_machine_available[18,2]'    0
254   'slot_color_MAX_machine_available[18,3]'    0
255   'slot_color_MAX_machine_available[19,1]'    0
256   'slot_color_MAX_machine_available[19,2]'    0
257   'slot_color_MAX_machine_available[19,3]'    0
258   'slot_color_MAX_machine_available[20,1]'    0
259   'slot_color_MAX_machine_available[20,2]'    0
260   'slot_color_MAX_machine_available[20,3]'    0
261   'slot_color_MAX_machine_available[21,1]'    0
262   'slot_color_MAX_machine_available[21,2]'    0
263   'slot_color_MAX_machine_available[21,3]'    0
264   'slot_color_MAX_machine_available[22,1]'    0
265   'slot_color_MAX_machine_available[22,2]'    0
266   'slot_color_MAX_machine_available[22,3]'    0
267   'slot_color_MAX_machine_available[23,1]'    0
268   'slot_color_MAX_machine_available[23,2]'    0
269   'slot_color_MAX_machine_available[23,3]'    0
270   'slot_color_MAX_machine_available[24,1]'    0
271   'slot_color_MAX_machine_available[24,2]'    0
272   'slot_color_MAX_machine_available[24,3]'    0
273   'slot_color_MAX_machine_available[25,1]'    0
274   'slot_color_MAX_machine_available[25,2]'    0
275   'slot_color_MAX_machine_available[25,3]'    0
276   'slot_color_MAX_machine_available[26,1]'    0
277   'slot_color_MAX_machine_available[26,2]'    0
278   'slot_color_MAX_machine_available[26,3]'    0
279   'slot_color_MAX_machine_available[27,1]'    0
280   'slot_color_MAX_machine_available[27,2]'    0
281   'slot_color_MAX_machine_available[27,3]'    0
282   'slot_color_MAX_machine_available[28,1]'    0
283   'slot_color_MAX_machine_available[28,2]'    0
284   'slot_color_MAX_machine_available[28,3]'    0
285   'slot_color_MAX_machine_available[29,1]'    0
286   'slot_color_MAX_machine_available[29,2]'    0
287   'slot_color_MAX_machine_available[29,3]'    0
288   'slot_color_MAX_machine_available[30,1]'    0
289   'slot_color_MAX_machine_available[30,2]'    0
290   'slot_color_MAX_machine_available[30,3]'    0
291   'slot_color_MAX_machine_available[31,1]'    0
292   'slot_color_MAX_machine_available[31,2]'    0
293   'slot_color_MAX_machine_available[31,3]'    0
294   'slot_color_MAX_machine_available[32,1]'    0
295   'slot_color_MAX_machine_available[32,2]'    0
296   'slot_color_MAX_machine_available[32,3]'    0
297   'slot_color_MAX_machine_available[33,1]'    0
298   'slot_color_MAX_machine_available[33,2]'    0
299   'slot_color_MAX_machine_available[33,3]'    0
300   'slot_color_MAX_machine_available[34,1]'    0
301   'slot_color_MAX_machine_available[34,2]'    0
302   'slot_color_MAX_machine_available[34,3]'    0
303   'slot_color_MAX_machine_available[35,1]'    0
304   'slot_color_MAX_machine_available[35,2]'    0
305   'slot_color_MAX_machine_available[35,3]'    0
306   'slot_color_MAX_machine_available[36,1]'    0
307   'slot_color_MAX_machine_available[36,2]'    0
308   'slot_color_MAX_machine_available[36,3]'    0
309   'slot_color_MAX_machine_available[37,1]'    0
310   'slot_color_MAX_machine_available[37,2]'    0
311   'slot_color_MAX_machine_available[37,3]'    0
312   'slot_color_MAX_machine_available[38,1]'    0
313   'slot_color_MAX_machine_available[38,2]'    0
314   'slot_color_MAX_machine_available[38,3]'    0
315   'slot_color_MAX_machine_available[39,1]'    0
316   'slot_color_MAX_machine_available[39,2]'    0
317   'slot_color_MAX_machine_available[39,3]'    0
318   'slot_color_MAX_machine_available[40,1]'    0
319   'slot_color_MAX_machine_available[40,2]'    0
320   'slot_color_MAX_machine_available[40,3]'    0
321   'slot_color_MAX_machine_available[41,1]'    0
322   'slot_color_MAX_machine_available[41,2]'    0
323   'slot_color_MAX_machine_available[41,3]'    0
324   'slot_color_MAX_machine_available[42,1]'    0
325   'slot_color_MAX_machine_available[42,2]'    0
326   'slot_color_MAX_machine_available[42,3]'    0
327   'slot_color_MAX_machine_available[43,1]'    0
328   'slot_color_MAX_machine_available[43,2]'    0
329   'slot_color_MAX_machine_available[43,3]'    0
330   'slot_color_MAX_machine_available[44,1]'    0
331   'slot_color_MAX_machine_available[44,2]'    0
332   'slot_color_MAX_machine_available[44,3]'    0
333   'slot_color_MAX_machine_available[45,1]'    0
334   'slot_color_MAX_machine_available[45,2]'    0
335   'slot_color_MAX_machine_available[45,3]'    0
336   'slot_color_MAX_machine_available[46,1]'    0
337   'slot_color_MAX_machine_available[46,2]'    0
338   'slot_color_MAX_machine_available[46,3]'    0
339   'slot_color_MAX_machine_available[47,1]'    0
340   'slot_color_MAX_machine_available[47,2]'    0
341   'slot_color_MAX_machine_available[47,3]'    0
342   'slot_color_MAX_machine_available[48,1]'    0
343   'slot_color_MAX_machine_available[48,2]'    0
344   'slot_color_MAX_machine_available[48,3]'    0
345   'slot_color_MAX_machine_available[49,1]'    0
346   'slot_color_MAX_machine_available[49,2]'    0
347   'slot_color_MAX_machine_available[49,3]'    0
348   'slot_color_MAX_machine_available[50,1]'    0
349   'slot_color_MAX_machine_available[50,2]'    0
350   'slot_color_MAX_machine_available[50,3]'    0
351   'pattern_use[1]'                            8
352   'pattern_use[2]'                           14
353   'pattern_use[3]'                            1
354   'pattern_use[4]'                            8
355   'pattern_use[5]'                           11
356   'pattern_missing[1]'                        1
357   'pattern_missing[2]'                        0
358   'pattern_missing[3]'                        0
359   'pattern_missing[4]'                        0
360   'pattern_missing[5]'                        0
361   'pattern_overuse[1]'                        0
362   'pattern_overuse[2]'                        0
363   'pattern_overuse[3]'                        0
364   'pattern_overuse[4]'                        0
365   'pattern_overuse[5]'                        0
366   'slot_color_spec[1,1]'                      0
367   'slot_color_spec[1,2]'                      0
368   'slot_color_spec[2,1]'                      0
369   'slot_color_spec[2,2]'                      0
370   'slot_color_spec[3,1]'                      0
371   'slot_color_spec[3,2]'                      0
372   'slot_color_spec[4,1]'                      0
373   'slot_color_spec[4,2]'                      0
374   'slot_color_spec[5,1]'                      0
375   'slot_color_spec[5,2]'                      0
376   'slot_color_spec[6,1]'                      0
377   'slot_color_spec[6,2]'                      0
378   'slot_color_spec[7,1]'                      0
379   'slot_color_spec[7,2]'                      0
380   'slot_color_spec[8,1]'                      0
381   'slot_color_spec[8,2]'                      0
382   'slot_color_spec[9,1]'                      0
383   'slot_color_spec[9,2]'                      0
384   'slot_color_spec[10,1]'                     1
385   'slot_color_spec[10,2]'                     2
386   'slot_color_spec[11,1]'                     1
387   'slot_color_spec[11,2]'                     2
388   'slot_color_spec[12,1]'                     1
389   'slot_color_spec[12,2]'                     2
390   'slot_color_spec[13,1]'                     1
391   'slot_color_spec[13,2]'                     2
392   'slot_color_spec[14,1]'                     1
393   'slot_color_spec[14,2]'                     2
394   'slot_color_spec[15,1]'                     1
395   'slot_color_spec[15,2]'                     2
396   'slot_color_spec[16,1]'                     1
397   'slot_color_spec[16,2]'                     2
398   'slot_color_spec[17,1]'                     1
399   'slot_color_spec[17,2]'                     2
400   'slot_color_spec[18,1]'                     1
401   'slot_color_spec[18,2]'                     2
402   'slot_color_spec[19,1]'                     1
403   'slot_color_spec[19,2]'                     2
404   'slot_color_spec[20,1]'                     1
405   'slot_color_spec[20,2]'                     2
406   'slot_color_spec[21,1]'                     1
407   'slot_color_spec[21,2]'                     2
408   'slot_color_spec[22,1]'                     1
409   'slot_color_spec[22,2]'                     2
410   'slot_color_spec[23,1]'                     1
411   'slot_color_spec[23,2]'                     2
412   'slot_color_spec[24,1]'                     1
413   'slot_color_spec[24,2]'                     2
414   'slot_color_spec[25,1]'                     1
415   'slot_color_spec[25,2]'                     2
416   'slot_color_spec[26,1]'                     1
417   'slot_color_spec[26,2]'                     2
418   'slot_color_spec[27,1]'                     1
419   'slot_color_spec[27,2]'                     2
420   'slot_color_spec[28,1]'                     1
421   'slot_color_spec[28,2]'                     2
422   'slot_color_spec[29,1]'                     1
423   'slot_color_spec[29,2]'                     2
424   'slot_color_spec[30,1]'                     1
425   'slot_color_spec[30,2]'                     2
426   'slot_color_spec[31,1]'                     1
427   'slot_color_spec[31,2]'                     1
428   'slot_color_spec[32,1]'                     1
429   'slot_color_spec[32,2]'                     1
430   'slot_color_spec[33,1]'                     1
431   'slot_color_spec[33,2]'                     1
432   'slot_color_spec[34,1]'                     1
433   'slot_color_spec[34,2]'                     1
434   'slot_color_spec[35,1]'                     1
435   'slot_color_spec[35,2]'                     1
436   'slot_color_spec[36,1]'                     1
437   'slot_color_spec[36,2]'                     1
438   'slot_color_spec[37,1]'                     1
439   'slot_color_spec[37,2]'                     1
440   'slot_color_spec[38,1]'                     1
441   'slot_color_spec[38,2]'                     1
442   'slot_color_spec[39,1]'                     1
443   'slot_color_spec[39,2]'                     1
444   'slot_color_spec[40,1]'                     1
445   'slot_color_spec[40,2]'                     1
446   'slot_color_spec[41,1]'                     1
447   'slot_color_spec[41,2]'                     1
448   'slot_color_spec[42,1]'                     1
449   'slot_color_spec[42,2]'                     0
450   'slot_color_spec[43,1]'                     0
451   'slot_color_spec[43,2]'                     0
452   'slot_color_spec[44,1]'                     0
453   'slot_color_spec[44,2]'                     0
454   'slot_color_spec[45,1]'                     0
455   'slot_color_spec[45,2]'                     0
456   'slot_color_spec[46,1]'                     0
457   'slot_color_spec[46,2]'                     0
458   'slot_color_spec[47,1]'                     0
459   'slot_color_spec[47,2]'                     0
460   'slot_color_spec[48,1]'                     0
461   'slot_color_spec[48,2]'                     0
462   'slot_color_spec[49,1]'                     0
463   'slot_color_spec[49,2]'                     0
464   'slot_color_spec[50,1]'                     0
465   'slot_color_spec[50,2]'                     0
466   'slot_color_change[1,1]'                    0
467   'slot_color_change[1,2]'                    0
468   'slot_color_change[2,1]'                    0
469   'slot_color_change[2,2]'                    0
470   'slot_color_change[3,1]'                    0
471   'slot_color_change[3,2]'                    0
472   'slot_color_change[4,1]'                    0
473   'slot_color_change[4,2]'                    0
474   'slot_color_change[5,1]'                    0
475   'slot_color_change[5,2]'                    0
476   'slot_color_change[6,1]'                    0
477   'slot_color_change[6,2]'                    0
478   'slot_color_change[7,1]'                    0
479   'slot_color_change[7,2]'                    0
480   'slot_color_change[8,1]'                    0
481   'slot_color_change[8,2]'                    0
482   'slot_color_change[9,1]'                    0
483   'slot_color_change[9,2]'                    0
484   'slot_color_change[10,1]'                   0
485   'slot_color_change[10,2]'                   0
486   'slot_color_change[11,1]'                   0
487   'slot_color_change[11,2]'                   0
488   'slot_color_change[12,1]'                   0
489   'slot_color_change[12,2]'                   0
490   'slot_color_change[13,1]'                   0
491   'slot_color_change[13,2]'                   0
492   'slot_color_change[14,1]'                   0
493   'slot_color_change[14,2]'                   0
494   'slot_color_change[15,1]'                   0
495   'slot_color_change[15,2]'                   0
496   'slot_color_change[16,1]'                   0
497   'slot_color_change[16,2]'                   0
498   'slot_color_change[17,1]'                   6.66134e-16
499   'slot_color_change[17,2]'                   0
500   'slot_color_change[18,1]'                   0
501   'slot_color_change[18,2]'                   0
502   'slot_color_change[19,1]'                   0
503   'slot_color_change[19,2]'                   0
504   'slot_color_change[20,1]'                   0
505   'slot_color_change[20,2]'                   0
506   'slot_color_change[21,1]'                   0
507   'slot_color_change[21,2]'                   0
508   'slot_color_change[22,1]'                   0
509   'slot_color_change[22,2]'                   0
510   'slot_color_change[23,1]'                   0
511   'slot_color_change[23,2]'                   0
512   'slot_color_change[24,1]'                   0
513   'slot_color_change[24,2]'                   0
514   'slot_color_change[25,1]'                   0
515   'slot_color_change[25,2]'                   0
516   'slot_color_change[26,1]'                   0
517   'slot_color_change[26,2]'                   0
518   'slot_color_change[27,1]'                   0
519   'slot_color_change[27,2]'                   0
520   'slot_color_change[28,1]'                   0
521   'slot_color_change[28,2]'                   0
522   'slot_color_change[29,1]'                   0
523   'slot_color_change[29,2]'                   0
524   'slot_color_change[30,1]'                   0
525   'slot_color_change[30,2]'                   0
526   'slot_color_change[31,1]'                   0
527   'slot_color_change[31,2]'                   0
528   'slot_color_change[32,1]'                   0
529   'slot_color_change[32,2]'                   0
530   'slot_color_change[33,1]'                   0
531   'slot_color_change[33,2]'                   0
532   'slot_color_change[34,1]'                   0
533   'slot_color_change[34,2]'                   0
534   'slot_color_change[35,1]'                   0
535   'slot_color_change[35,2]'                   0
536   'slot_color_change[36,1]'                   0
537   'slot_color_change[36,2]'                   0
538   'slot_color_change[37,1]'                   0
539   'slot_color_change[37,2]'                   0
540   'slot_color_change[38,1]'                   0
541   'slot_color_change[38,2]'                   0
542   'slot_color_change[39,1]'                   0
543   'slot_color_change[39,2]'                   0
544   'slot_color_change[40,1]'                   0
545   'slot_color_change[40,2]'                   0
546   'slot_color_change[41,1]'                   0
547   'slot_color_change[41,2]'                   0
548   'slot_color_change[42,1]'                   0
549   'slot_color_change[42,2]'                   0
550   'slot_color_change[43,1]'                   0
551   'slot_color_change[43,2]'                   0
552   'slot_color_change[44,1]'                   0
553   'slot_color_change[44,2]'                   0
554   'slot_color_change[45,1]'                   0
555   'slot_color_change[45,2]'                   0
556   'slot_color_change[46,1]'                   0
557   'slot_color_change[46,2]'                   0
558   'slot_color_change[47,1]'                   0
559   'slot_color_change[47,2]'                   0
560   'slot_color_change[48,1]'                   0
561   'slot_color_change[48,2]'                   0
562   'slot_color_change[49,1]'                   0
563   'slot_color_change[49,2]'                   0
564   'slot_color_MAX_change[1,1]'                0
565   'slot_color_MAX_change[1,2]'                0
566   'slot_color_MAX_change[1,3]'                0
567   'slot_color_MAX_change[2,1]'                0
568   'slot_color_MAX_change[2,2]'                0
569   'slot_color_MAX_change[2,3]'                0
570   'slot_color_MAX_change[3,1]'                0
571   'slot_color_MAX_change[3,2]'                0
572   'slot_color_MAX_change[3,3]'                0
573   'slot_color_MAX_change[4,1]'                0
574   'slot_color_MAX_change[4,2]'                0
575   'slot_color_MAX_change[4,3]'                0
576   'slot_color_MAX_change[5,1]'                0
577   'slot_color_MAX_change[5,2]'                0
578   'slot_color_MAX_change[5,3]'                0
579   'slot_color_MAX_change[6,1]'                0
580   'slot_color_MAX_change[6,2]'                0
581   'slot_color_MAX_change[6,3]'                0
582   'slot_color_MAX_change[7,1]'                0
583   'slot_color_MAX_change[7,2]'                0
584   'slot_color_MAX_change[7,3]'                0
585   'slot_color_MAX_change[8,1]'                0
586   'slot_color_MAX_change[8,2]'                0
587   'slot_color_MAX_change[8,3]'                0
588   'slot_color_MAX_change[9,1]'                0
589   'slot_color_MAX_change[9,2]'                0
590   'slot_color_MAX_change[9,3]'                0
591   'slot_color_MAX_change[10,1]'               0
592   'slot_color_MAX_change[10,2]'               0
593   'slot_color_MAX_change[10,3]'               0
594   'slot_color_MAX_change[11,1]'               0
595   'slot_color_MAX_change[11,2]'               0
596   'slot_color_MAX_change[11,3]'               0
597   'slot_color_MAX_change[12,1]'               0
598   'slot_color_MAX_change[12,2]'               0
599   'slot_color_MAX_change[12,3]'               0
600   'slot_color_MAX_change[13,1]'               0
601   'slot_color_MAX_change[13,2]'               0
602   'slot_color_MAX_change[13,3]'               0
603   'slot_color_MAX_change[14,1]'               0
604   'slot_color_MAX_change[14,2]'               0
605   'slot_color_MAX_change[14,3]'               0
606   'slot_color_MAX_change[15,1]'               0
607   'slot_color_MAX_change[15,2]'               0
608   'slot_color_MAX_change[15,3]'               0
609   'slot_color_MAX_change[16,1]'               0
610   'slot_color_MAX_change[16,2]'               0
611   'slot_color_MAX_change[16,3]'               0
612   'slot_color_MAX_change[17,1]'               0
613   'slot_color_MAX_change[17,2]'               0
614   'slot_color_MAX_change[17,3]'               0
615   'slot_color_MAX_change[18,1]'               0
616   'slot_color_MAX_change[18,2]'               0
617   'slot_color_MAX_change[18,3]'               0
618   'slot_color_MAX_change[19,1]'               0
619   'slot_color_MAX_change[19,2]'               0
620   'slot_color_MAX_change[19,3]'               0
621   'slot_color_MAX_change[20,1]'               0
622   'slot_color_MAX_change[20,2]'               0
623   'slot_color_MAX_change[20,3]'               0
624   'slot_color_MAX_change[21,1]'               0
625   'slot_color_MAX_change[21,2]'               0
626   'slot_color_MAX_change[21,3]'               0
627   'slot_color_MAX_change[22,1]'               0
628   'slot_color_MAX_change[22,2]'               0
629   'slot_color_MAX_change[22,3]'               0
630   'slot_color_MAX_change[23,1]'               0
631   'slot_color_MAX_change[23,2]'               0
632   'slot_color_MAX_change[23,3]'               0
633   'slot_color_MAX_change[24,1]'               0
634   'slot_color_MAX_change[24,2]'               0
635   'slot_color_MAX_change[24,3]'               0
636   'slot_color_MAX_change[25,1]'               0
637   'slot_color_MAX_change[25,2]'               0
638   'slot_color_MAX_change[25,3]'               0
639   'slot_color_MAX_change[26,1]'               0
640   'slot_color_MAX_change[26,2]'               0
641   'slot_color_MAX_change[26,3]'               0
642   'slot_color_MAX_change[27,1]'               0
643   'slot_color_MAX_change[27,2]'               0
644   'slot_color_MAX_change[27,3]'               0
645   'slot_color_MAX_change[28,1]'               0
646   'slot_color_MAX_change[28,2]'               0
647   'slot_color_MAX_change[28,3]'               0
648   'slot_color_MAX_change[29,1]'               0
649   'slot_color_MAX_change[29,2]'               0
650   'slot_color_MAX_change[29,3]'               0
651   'slot_color_MAX_change[30,1]'               0
652   'slot_color_MAX_change[30,2]'               0
653   'slot_color_MAX_change[30,3]'               0
654   'slot_color_MAX_change[31,1]'               0
655   'slot_color_MAX_change[31,2]'               0
656   'slot_color_MAX_change[31,3]'               0
657   'slot_color_MAX_change[32,1]'               0
658   'slot_color_MAX_change[32,2]'               0
659   'slot_color_MAX_change[32,3]'               0
660   'slot_color_MAX_change[33,1]'               0
661   'slot_color_MAX_change[33,2]'               0
662   'slot_color_MAX_change[33,3]'               0
663   'slot_color_MAX_change[34,1]'               0
664   'slot_color_MAX_change[34,2]'               0
665   'slot_color_MAX_change[34,3]'               0
666   'slot_color_MAX_change[35,1]'               0
667   'slot_color_MAX_change[35,2]'               0
668   'slot_color_MAX_change[35,3]'               0
669   'slot_color_MAX_change[36,1]'               0
670   'slot_color_MAX_change[36,2]'               0
671   'slot_color_MAX_change[36,3]'               0
672   'slot_color_MAX_change[37,1]'               0
673   'slot_color_MAX_change[37,2]'               0
674   'slot_color_MAX_change[37,3]'               0
675   'slot_color_MAX_change[38,1]'               0
676   'slot_color_MAX_change[38,2]'               0
677   'slot_color_MAX_change[38,3]'               0
678   'slot_color_MAX_change[39,1]'               0
679   'slot_color_MAX_change[39,2]'               0
680   'slot_color_MAX_change[39,3]'               0
681   'slot_color_MAX_change[40,1]'               0
682   'slot_color_MAX_change[40,2]'               0
683   'slot_color_MAX_change[40,3]'               0
684   'slot_color_MAX_change[41,1]'               0
685   'slot_color_MAX_change[41,2]'               0
686   'slot_color_MAX_change[41,3]'               0
687   'slot_color_MAX_change[42,1]'               0
688   'slot_color_MAX_change[42,2]'               0
689   'slot_color_MAX_change[42,3]'               0
690   'slot_color_MAX_change[43,1]'               0
691   'slot_color_MAX_change[43,2]'               0
692   'slot_color_MAX_change[43,3]'               0
693   'slot_color_MAX_change[44,1]'               0
694   'slot_color_MAX_change[44,2]'               0
695   'slot_color_MAX_change[44,3]'               0
696   'slot_color_MAX_change[45,1]'               0
697   'slot_color_MAX_change[45,2]'               0
698   'slot_color_MAX_change[45,3]'               0
699   'slot_color_MAX_change[46,1]'               0
700   'slot_color_MAX_change[46,2]'               0
701   'slot_color_MAX_change[46,3]'               0
702   'slot_color_MAX_change[47,1]'               0
703   'slot_color_MAX_change[47,2]'               0
704   'slot_color_MAX_change[47,3]'               0
705   'slot_color_MAX_change[48,1]'               0
706   'slot_color_MAX_change[48,2]'               0
707   'slot_color_MAX_change[48,3]'               0
708   'slot_color_MAX_change[49,1]'               0
709   'slot_color_MAX_change[49,2]'               0
710   'slot_color_MAX_change[49,3]'               0
;

:           _conname        _con.slack    :=
1    'PatternUse[1]'             0
2    'PatternUse[2]'             0
3    'PatternUse[3]'             0
4    'PatternUse[4]'             0
5    'PatternUse[5]'             0
6    'PatternUseBalance[1]'      0
7    'PatternUseBalance[2]'      0
8    'PatternUseBalance[3]'      0
9    'PatternUseBalance[4]'      0
10   'PatternUseBalance[5]'      0
;

:            _logconname         _logcon.val    :=
1     'PatternChoice[1]'               1
2     'PatternChoice[2]'               1
3     'PatternChoice[3]'               1
4     'PatternChoice[4]'               1
5     'PatternChoice[5]'               1
6     'PatternChoice[6]'               1
7     'PatternChoice[7]'               1
8     'PatternChoice[8]'               1
9     'PatternChoice[9]'               1
10    'PatternChoice[10]'              1
11    'PatternChoice[11]'              1
12    'PatternChoice[12]'              1
13    'PatternChoice[13]'              1
14    'PatternChoice[14]'              1
15    'PatternChoice[15]'              1
16    'PatternChoice[16]'              1
17    'PatternChoice[17]'              1
18    'PatternChoice[18]'              1
19    'PatternChoice[19]'              1
20    'PatternChoice[20]'              1
21    'PatternChoice[21]'              1
22    'PatternChoice[22]'              1
23    'PatternChoice[23]'              1
24    'PatternChoice[24]'              1
25    'PatternChoice[25]'              1
26    'PatternChoice[26]'              1
27    'PatternChoice[27]'              1
28    'PatternChoice[28]'              1
29    'PatternChoice[29]'              1
30    'PatternChoice[30]'              1
31    'PatternChoice[31]'              1
32    'PatternChoice[32]'              1
33    'PatternChoice[33]'              1
34    'PatternChoice[34]'              1
35    'PatternChoice[35]'              1
36    'PatternChoice[36]'              1
37    'PatternChoice[37]'              1
38    'PatternChoice[38]'              1
39    'PatternChoice[39]'              1
40    'PatternChoice[40]'              1
41    'PatternChoice[41]'              1
42    'PatternChoice[42]'              1
43    'PatternChoice[43]'              1
44    'PatternChoice[44]'              1
45    'PatternChoice[45]'              1
46    'PatternChoice[46]'              1
47    'PatternChoice[47]'              1
48    'PatternChoice[48]'              1
49    'PatternChoice[49]'              1
50    'PatternChoice[50]'              1
51    'ColorSimpleSpec[1,1,1]'         1
52    'ColorSimpleSpec[1,1,2]'         1
53    'ColorSimpleSpec[1,3,1]'         1
54    'ColorSimpleSpec[1,3,2]'         1
55    'ColorSimpleSpec[2,1,1]'         1
56    'ColorSimpleSpec[2,1,2]'         1
57    'ColorSimpleSpec[2,3,1]'         1
58    'ColorSimpleSpec[2,3,2]'         1
59    'ColorSimpleSpec[3,2,1]'         1
60    'ColorSimpleSpec[3,2,2]'         1
61    'ColorSimpleSpec[3,4,1]'         1
62    'ColorSimpleSpec[3,4,2]'         1
63    'ColorSimpleSpec[4,2,1]'         1
64    'ColorSimpleSpec[4,2,2]'         1
65    'ColorSimpleSpec[4,4,1]'         1
66    'ColorSimpleSpec[4,4,2]'         1
67    'ColorSimpleSpec[5,2,1]'         1
68    'ColorSimpleSpec[5,2,2]'         1
69    'ColorSimpleSpec[5,4,1]'         1
70    'ColorSimpleSpec[5,4,2]'         1
71    'ColorSimpleSpec[6,2,1]'         1
72    'ColorSimpleSpec[6,2,2]'         1
73    'ColorSimpleSpec[6,4,1]'         1
74    'ColorSimpleSpec[6,4,2]'         1
75    'ColorSimpleSpec[7,2,1]'         1
76    'ColorSimpleSpec[7,2,2]'         1
77    'ColorSimpleSpec[7,4,1]'         1
78    'ColorSimpleSpec[7,4,2]'         1
79    'ColorSimpleSpec[8,2,1]'         1
80    'ColorSimpleSpec[8,2,2]'         1
81    'ColorSimpleSpec[8,4,1]'         1
82    'ColorSimpleSpec[8,4,2]'         1
83    'ColorSimpleSpec[9,2,1]'         1
84    'ColorSimpleSpec[9,2,2]'         1
85    'ColorSimpleSpec[9,4,1]'         1
86    'ColorSimpleSpec[9,4,2]'         1
87    'ColorSimpleSpec[10,1,1]'        1
88    'ColorSimpleSpec[10,1,2]'        1
89    'ColorSimpleSpec[10,3,1]'        1
90    'ColorSimpleSpec[10,3,2]'        1
91    'ColorSimpleSpec[11,1,1]'        1
92    'ColorSimpleSpec[11,1,2]'        1
93    'ColorSimpleSpec[11,3,1]'        1
94    'ColorSimpleSpec[11,3,2]'        1
95    'ColorSimpleSpec[12,1,1]'        1
96    'ColorSimpleSpec[12,1,2]'        1
97    'ColorSimpleSpec[12,3,1]'        1
98    'ColorSimpleSpec[12,3,2]'        1
99    'ColorSimpleSpec[13,1,1]'        1
100   'ColorSimpleSpec[13,1,2]'        1
101   'ColorSimpleSpec[13,3,1]'        1
102   'ColorSimpleSpec[13,3,2]'        1
103   'ColorSimpleSpec[14,1,1]'        1
104   'ColorSimpleSpec[14,1,2]'        1
105   'ColorSimpleSpec[14,3,1]'        1
106   'ColorSimpleSpec[14,3,2]'        1
107   'ColorSimpleSpec[15,1,1]'        1
108   'ColorSimpleSpec[15,1,2]'        1
109   'ColorSimpleSpec[15,3,1]'        1
110   'ColorSimpleSpec[15,3,2]'        1
111   'ColorSimpleSpec[16,1,1]'        1
112   'ColorSimpleSpec[16,1,2]'        1
113   'ColorSimpleSpec[16,3,1]'        1
114   'ColorSimpleSpec[16,3,2]'        1
115   'ColorSimpleSpec[17,1,1]'        1
116   'ColorSimpleSpec[17,1,2]'        1
117   'ColorSimpleSpec[17,3,1]'        1
118   'ColorSimpleSpec[17,3,2]'        1
119   'ColorSimpleSpec[18,1,1]'        1
120   'ColorSimpleSpec[18,1,2]'        1
121   'ColorSimpleSpec[18,3,1]'        1
122   'ColorSimpleSpec[18,3,2]'        1
123   'ColorSimpleSpec[19,2,1]'        1
124   'ColorSimpleSpec[19,2,2]'        1
125   'ColorSimpleSpec[19,4,1]'        1
126   'ColorSimpleSpec[19,4,2]'        1
127   'ColorSimpleSpec[19,5,1]'        1
128   'ColorSimpleSpec[19,5,2]'        1
129   'ColorSimpleSpec[20,2,1]'        1
130   'ColorSimpleSpec[20,2,2]'        1
131   'ColorSimpleSpec[20,4,1]'        1
132   'ColorSimpleSpec[20,4,2]'        1
133   'ColorSimpleSpec[20,5,1]'        1
134   'ColorSimpleSpec[20,5,2]'        1
135   'ColorSimpleSpec[21,2,1]'        1
136   'ColorSimpleSpec[21,2,2]'        1
137   'ColorSimpleSpec[21,4,1]'        1
138   'ColorSimpleSpec[21,4,2]'        1
139   'ColorSimpleSpec[21,5,1]'        1
140   'ColorSimpleSpec[21,5,2]'        1
141   'ColorSimpleSpec[22,2,1]'        1
142   'ColorSimpleSpec[22,2,2]'        1
143   'ColorSimpleSpec[22,4,1]'        1
144   'ColorSimpleSpec[22,4,2]'        1
145   'ColorSimpleSpec[22,5,1]'        1
146   'ColorSimpleSpec[22,5,2]'        1
147   'ColorSimpleSpec[23,2,1]'        1
148   'ColorSimpleSpec[23,2,2]'        1
149   'ColorSimpleSpec[23,4,1]'        1
150   'ColorSimpleSpec[23,4,2]'        1
151   'ColorSimpleSpec[23,5,1]'        1
152   'ColorSimpleSpec[23,5,2]'        1
153   'ColorSimpleSpec[24,2,1]'        1
154   'ColorSimpleSpec[24,2,2]'        1
155   'ColorSimpleSpec[24,4,1]'        1
156   'ColorSimpleSpec[24,4,2]'        1
157   'ColorSimpleSpec[24,5,1]'        1
158   'ColorSimpleSpec[24,5,2]'        1
159   'ColorSimpleSpec[25,2,1]'        1
160   'ColorSimpleSpec[25,2,2]'        1
161   'ColorSimpleSpec[25,4,1]'        1
162   'ColorSimpleSpec[25,4,2]'        1
163   'ColorSimpleSpec[25,5,1]'        1
164   'ColorSimpleSpec[25,5,2]'        1
165   'ColorSimpleSpec[26,2,1]'        1
166   'ColorSimpleSpec[26,2,2]'        1
167   'ColorSimpleSpec[26,4,1]'        1
168   'ColorSimpleSpec[26,4,2]'        1
169   'ColorSimpleSpec[26,5,1]'        1
170   'ColorSimpleSpec[26,5,2]'        1
171   'ColorSimpleSpec[27,2,1]'        1
172   'ColorSimpleSpec[27,2,2]'        1
173   'ColorSimpleSpec[27,4,1]'        1
174   'ColorSimpleSpec[27,4,2]'        1
175   'ColorSimpleSpec[27,5,1]'        1
176   'ColorSimpleSpec[27,5,2]'        1
177   'ColorSimpleSpec[28,2,1]'        1
178   'ColorSimpleSpec[28,2,2]'        1
179   'ColorSimpleSpec[28,4,1]'        1
180   'ColorSimpleSpec[28,4,2]'        1
181   'ColorSimpleSpec[28,5,1]'        1
182   'ColorSimpleSpec[28,5,2]'        1
183   'ColorSimpleSpec[29,2,1]'        1
184   'ColorSimpleSpec[29,2,2]'        1
185   'ColorSimpleSpec[29,4,1]'        1
186   'ColorSimpleSpec[29,4,2]'        1
187   'ColorSimpleSpec[29,5,1]'        1
188   'ColorSimpleSpec[29,5,2]'        1
189   'ColorSimpleSpec[30,2,1]'        1
190   'ColorSimpleSpec[30,2,2]'        1
191   'ColorSimpleSpec[30,4,1]'        1
192   'ColorSimpleSpec[30,4,2]'        1
193   'ColorSimpleSpec[30,5,1]'        1
194   'ColorSimpleSpec[30,5,2]'        1
195   'ColorSimpleSpec[31,2,1]'        1
196   'ColorSimpleSpec[31,2,2]'        1
197   'ColorSimpleSpec[31,4,1]'        1
198   'ColorSimpleSpec[31,4,2]'        1
199   'ColorSimpleSpec[31,5,1]'        1
200   'ColorSimpleSpec[31,5,2]'        1
201   'ColorSimpleSpec[32,2,1]'        1
202   'ColorSimpleSpec[32,2,2]'        1
203   'ColorSimpleSpec[32,4,1]'        1
204   'ColorSimpleSpec[32,4,2]'        1
205   'ColorSimpleSpec[32,5,1]'        1
206   'ColorSimpleSpec[32,5,2]'        1
207   'ColorSimpleSpec[33,2,1]'        1
208   'ColorSimpleSpec[33,2,2]'        1
209   'ColorSimpleSpec[33,4,1]'        1
210   'ColorSimpleSpec[33,4,2]'        1
211   'ColorSimpleSpec[33,5,1]'        1
212   'ColorSimpleSpec[33,5,2]'        1
213   'ColorSimpleSpec[34,2,1]'        1
214   'ColorSimpleSpec[34,2,2]'        1
215   'ColorSimpleSpec[34,4,1]'        1
216   'ColorSimpleSpec[34,4,2]'        1
217   'ColorSimpleSpec[34,5,1]'        1
218   'ColorSimpleSpec[34,5,2]'        1
219   'ColorSimpleSpec[35,2,1]'        1
220   'ColorSimpleSpec[35,2,2]'        1
221   'ColorSimpleSpec[35,4,1]'        1
222   'ColorSimpleSpec[35,4,2]'        1
223   'ColorSimpleSpec[35,5,1]'        1
224   'ColorSimpleSpec[35,5,2]'        1
225   'ColorSimpleSpec[36,2,1]'        1
226   'ColorSimpleSpec[36,2,2]'        1
227   'ColorSimpleSpec[36,4,1]'        1
228   'ColorSimpleSpec[36,4,2]'        1
229   'ColorSimpleSpec[36,5,1]'        1
230   'ColorSimpleSpec[36,5,2]'        1
231   'ColorSimpleSpec[37,2,1]'        1
232   'ColorSimpleSpec[37,2,2]'        1
233   'ColorSimpleSpec[37,4,1]'        1
234   'ColorSimpleSpec[37,4,2]'        1
235   'ColorSimpleSpec[37,5,1]'        1
236   'ColorSimpleSpec[37,5,2]'        1
237   'ColorSimpleSpec[38,2,1]'        1
238   'ColorSimpleSpec[38,2,2]'        1
239   'ColorSimpleSpec[38,4,1]'        1
240   'ColorSimpleSpec[38,4,2]'        1
241   'ColorSimpleSpec[38,5,1]'        1
242   'ColorSimpleSpec[38,5,2]'        1
243   'ColorSimpleSpec[39,2,1]'        1
244   'ColorSimpleSpec[39,2,2]'        1
245   'ColorSimpleSpec[39,4,1]'        1
246   'ColorSimpleSpec[39,4,2]'        1
247   'ColorSimpleSpec[39,5,1]'        1
248   'ColorSimpleSpec[39,5,2]'        1
249   'ColorSimpleSpec[40,2,1]'        1
250   'ColorSimpleSpec[40,2,2]'        1
251   'ColorSimpleSpec[40,4,1]'        1
252   'ColorSimpleSpec[40,4,2]'        1
253   'ColorSimpleSpec[40,5,1]'        1
254   'ColorSimpleSpec[40,5,2]'        1
255   'ColorSimpleSpec[41,2,1]'        1
256   'ColorSimpleSpec[41,2,2]'        1
257   'ColorSimpleSpec[41,4,1]'        1
258   'ColorSimpleSpec[41,4,2]'        1
259   'ColorSimpleSpec[42,2,1]'        1
260   'ColorSimpleSpec[42,2,2]'        1
261   'ColorSimpleSpec[42,4,1]'        1
262   'ColorSimpleSpec[42,4,2]'        1
263   'ColorSimpleSpec[43,2,1]'        1
264   'ColorSimpleSpec[43,2,2]'        1
265   'ColorSimpleSpec[43,4,1]'        1
266   'ColorSimpleSpec[43,4,2]'        1
267   'ColorSimpleSpec[44,2,1]'        1
268   'ColorSimpleSpec[44,2,2]'        1
269   'ColorSimpleSpec[44,4,1]'        1
270   'ColorSimpleSpec[44,4,2]'        1
271   'ColorSimpleSpec[45,2,1]'        1
272   'ColorSimpleSpec[45,2,2]'        1
273   'ColorSimpleSpec[45,4,1]'        1
274   'ColorSimpleSpec[45,4,2]'        1
275   'ColorSimpleSpec[46,2,1]'        1
276   'ColorSimpleSpec[46,2,2]'        1
277   'ColorSimpleSpec[46,4,1]'        1
278   'ColorSimpleSpec[46,4,2]'        1
279   'ColorSimpleSpec[47,2,1]'        1
280   'ColorSimpleSpec[47,2,2]'        1
281   'ColorSimpleSpec[47,4,1]'        1
282   'ColorSimpleSpec[47,4,2]'        1
283   'ColorSimpleSpec[48,2,1]'        1
284   'ColorSimpleSpec[48,2,2]'        1
285   'ColorSimpleSpec[48,4,1]'        1
286   'ColorSimpleSpec[48,4,2]'        1
287   'ColorSimpleSpec[49,2,1]'        1
288   'ColorSimpleSpec[49,2,2]'        1
289   'ColorSimpleSpec[49,4,1]'        1
290   'ColorSimpleSpec[49,4,2]'        1
291   'ColorSimpleSpec[50,2,1]'        1
292   'ColorSimpleSpec[50,2,2]'        1
293   'ColorSimpleSpec[50,4,1]'        1
294   'ColorSimpleSpec[50,4,2]'        1
295   'ColorSimpleChanges[1,1]'        1
296   'ColorSimpleChanges[1,2]'        1
297   'ColorSimpleChanges[2,1]'        1
298   'ColorSimpleChanges[2,2]'        1
299   'ColorSimpleChanges[3,1]'        1
300   'ColorSimpleChanges[3,2]'        1
301   'ColorSimpleChanges[4,1]'        1
302   'ColorSimpleChanges[4,2]'        1
303   'ColorSimpleChanges[5,1]'        1
304   'ColorSimpleChanges[5,2]'        1
305   'ColorSimpleChanges[6,1]'        1
306   'ColorSimpleChanges[6,2]'        1
307   'ColorSimpleChanges[7,1]'        1
308   'ColorSimpleChanges[7,2]'        1
309   'ColorSimpleChanges[8,1]'        1
310   'ColorSimpleChanges[8,2]'        1
311   'ColorSimpleChanges[9,1]'        1
312   'ColorSimpleChanges[9,2]'        1
313   'ColorSimpleChanges[10,1]'       1
314   'ColorSimpleChanges[10,2]'       1
315   'ColorSimpleChanges[11,1]'       1
316   'ColorSimpleChanges[11,2]'       1
317   'ColorSimpleChanges[12,1]'       1
318   'ColorSimpleChanges[12,2]'       1
319   'ColorSimpleChanges[13,1]'       1
320   'ColorSimpleChanges[13,2]'       1
321   'ColorSimpleChanges[14,1]'       1
322   'ColorSimpleChanges[14,2]'       1
323   'ColorSimpleChanges[15,1]'       1
324   'ColorSimpleChanges[15,2]'       1
325   'ColorSimpleChanges[16,1]'       1
326   'ColorSimpleChanges[16,2]'       1
327   'ColorSimpleChanges[17,1]'       1
328   'ColorSimpleChanges[17,2]'       1
329   'ColorSimpleChanges[18,1]'       1
330   'ColorSimpleChanges[18,2]'       1
331   'ColorSimpleChanges[19,1]'       1
332   'ColorSimpleChanges[19,2]'       1
333   'ColorSimpleChanges[20,1]'       1
334   'ColorSimpleChanges[20,2]'       1
335   'ColorSimpleChanges[21,1]'       1
336   'ColorSimpleChanges[21,2]'       1
337   'ColorSimpleChanges[22,1]'       1
338   'ColorSimpleChanges[22,2]'       1
339   'ColorSimpleChanges[23,1]'       1
340   'ColorSimpleChanges[23,2]'       1
341   'ColorSimpleChanges[24,1]'       1
342   'ColorSimpleChanges[24,2]'       1
343   'ColorSimpleChanges[25,1]'       1
344   'ColorSimpleChanges[25,2]'       1
345   'ColorSimpleChanges[26,1]'       1
346   'ColorSimpleChanges[26,2]'       1
347   'ColorSimpleChanges[27,1]'       1
348   'ColorSimpleChanges[27,2]'       1
349   'ColorSimpleChanges[28,1]'       1
350   'ColorSimpleChanges[28,2]'       1
351   'ColorSimpleChanges[29,1]'       1
352   'ColorSimpleChanges[29,2]'       1
353   'ColorSimpleChanges[30,1]'       1
354   'ColorSimpleChanges[30,2]'       1
355   'ColorSimpleChanges[31,1]'       1
356   'ColorSimpleChanges[31,2]'       1
357   'ColorSimpleChanges[32,1]'       1
358   'ColorSimpleChanges[32,2]'       1
359   'ColorSimpleChanges[33,1]'       1
360   'ColorSimpleChanges[33,2]'       1
361   'ColorSimpleChanges[34,1]'       1
362   'ColorSimpleChanges[34,2]'       1
363   'ColorSimpleChanges[35,1]'       1
364   'ColorSimpleChanges[35,2]'       1
365   'ColorSimpleChanges[36,1]'       1
366   'ColorSimpleChanges[36,2]'       1
367   'ColorSimpleChanges[37,1]'       1
368   'ColorSimpleChanges[37,2]'       1
369   'ColorSimpleChanges[38,1]'       1
370   'ColorSimpleChanges[38,2]'       1
371   'ColorSimpleChanges[39,1]'       1
372   'ColorSimpleChanges[39,2]'       1
373   'ColorSimpleChanges[40,1]'       1
374   'ColorSimpleChanges[40,2]'       1
375   'ColorSimpleChanges[41,1]'       1
376   'ColorSimpleChanges[41,2]'       1
377   'ColorSimpleChanges[42,1]'       1
378   'ColorSimpleChanges[42,2]'       1
379   'ColorSimpleChanges[43,1]'       1
380   'ColorSimpleChanges[43,2]'       1
381   'ColorSimpleChanges[44,1]'       1
382   'ColorSimpleChanges[44,2]'       1
383   'ColorSimpleChanges[45,1]'       1
384   'ColorSimpleChanges[45,2]'       1
385   'ColorSimpleChanges[46,1]'       1
386   'ColorSimpleChanges[46,2]'       1
387   'ColorSimpleChanges[47,1]'       1
388   'ColorSimpleChanges[47,2]'       1
389   'ColorSimpleChanges[48,1]'       1
390   'ColorSimpleChanges[48,2]'       1
391   'ColorSimpleChanges[49,1]'       1
392   'ColorSimpleChanges[49,2]'       1
393   'ColorMAXSpec[1,1]'              1
394   'ColorMAXSpec[2,1]'              1
395   'ColorMAXSpec[3,2]'              1
396   'ColorMAXSpec[4,2]'              1
397   'ColorMAXSpec[5,2]'              1
398   'ColorMAXSpec[6,2]'              1
399   'ColorMAXSpec[7,2]'              1
400   'ColorMAXSpec[8,2]'              1
401   'ColorMAXSpec[9,2]'              1
402   'ColorMAXSpec[10,1]'             1
403   'ColorMAXSpec[11,1]'             1
404   'ColorMAXSpec[12,1]'             1
405   'ColorMAXSpec[13,1]'             1
406   'ColorMAXSpec[14,1]'             1
407   'ColorMAXSpec[15,1]'             1
408   'ColorMAXSpec[16,1]'             1
409   'ColorMAXSpec[17,1]'             1
410   'ColorMAXSpec[18,1]'             1
411   'ColorMAXSpec[19,2]'             1
412   'ColorMAXSpec[20,2]'             1
413   'ColorMAXSpec[21,2]'             1
414   'ColorMAXSpec[22,2]'             1
415   'ColorMAXSpec[23,2]'             1
416   'ColorMAXSpec[24,2]'             1
417   'ColorMAXSpec[25,2]'             1
418   'ColorMAXSpec[26,2]'             1
419   'ColorMAXSpec[27,2]'             1
420   'ColorMAXSpec[28,2]'             1
421   'ColorMAXSpec[29,2]'             1
422   'ColorMAXSpec[30,2]'             1
423   'ColorMAXSpec[31,2]'             1
424   'ColorMAXSpec[32,2]'             1
425   'ColorMAXSpec[33,2]'             1
426   'ColorMAXSpec[34,2]'             1
427   'ColorMAXSpec[35,2]'             1
428   'ColorMAXSpec[36,2]'             1
429   'ColorMAXSpec[37,2]'             1
430   'ColorMAXSpec[38,2]'             1
431   'ColorMAXSpec[39,2]'             1
432   'ColorMAXSpec[40,2]'             1
433   'ColorMAXSpec[41,2]'             1
434   'ColorMAXSpec[42,2]'             1
435   'ColorMAXSpec[43,2]'             1
436   'ColorMAXSpec[44,2]'             1
437   'ColorMAXSpec[45,2]'             1
438   'ColorMAXSpec[46,2]'             1
439   'ColorMAXSpec[47,2]'             1
440   'ColorMAXSpec[48,2]'             1
441   'ColorMAXSpec[49,2]'             1
442   'ColorMAXSpec[50,2]'             1
443   'ColorMAXChanges[1,1]'           1
444   'ColorMAXChanges[1,2]'           1
445   'ColorMAXChanges[1,3]'           1
446   'ColorMAXChanges[2,1]'           1
447   'ColorMAXChanges[2,2]'           1
448   'ColorMAXChanges[2,3]'           1
449   'ColorMAXChanges[3,1]'           1
450   'ColorMAXChanges[3,2]'           1
451   'ColorMAXChanges[3,3]'           1
452   'ColorMAXChanges[4,1]'           1
453   'ColorMAXChanges[4,2]'           1
454   'ColorMAXChanges[4,3]'           1
455   'ColorMAXChanges[5,1]'           1
456   'ColorMAXChanges[5,2]'           1
457   'ColorMAXChanges[5,3]'           1
458   'ColorMAXChanges[6,1]'           1
459   'ColorMAXChanges[6,2]'           1
460   'ColorMAXChanges[6,3]'           1
461   'ColorMAXChanges[7,1]'           1
462   'ColorMAXChanges[7,2]'           1
463   'ColorMAXChanges[7,3]'           1
464   'ColorMAXChanges[8,1]'           1
465   'ColorMAXChanges[8,2]'           1
466   'ColorMAXChanges[8,3]'           1
467   'ColorMAXChanges[9,1]'           1
468   'ColorMAXChanges[9,2]'           1
469   'ColorMAXChanges[9,3]'           1
470   'ColorMAXChanges[10,1]'          1
471   'ColorMAXChanges[10,2]'          1
472   'ColorMAXChanges[10,3]'          1
473   'ColorMAXChanges[11,1]'          1
474   'ColorMAXChanges[11,2]'          1
475   'ColorMAXChanges[11,3]'          1
476   'ColorMAXChanges[12,1]'          1
477   'ColorMAXChanges[12,2]'          1
478   'ColorMAXChanges[12,3]'          1
479   'ColorMAXChanges[13,1]'          1
480   'ColorMAXChanges[13,2]'          1
481   'ColorMAXChanges[13,3]'          1
482   'ColorMAXChanges[14,1]'          1
483   'ColorMAXChanges[14,2]'          1
484   'ColorMAXChanges[14,3]'          1
485   'ColorMAXChanges[15,1]'          1
486   'ColorMAXChanges[15,2]'          1
487   'ColorMAXChanges[15,3]'          1
488   'ColorMAXChanges[16,1]'          1
489   'ColorMAXChanges[16,2]'          1
490   'ColorMAXChanges[16,3]'          1
491   'ColorMAXChanges[17,1]'          1
492   'ColorMAXChanges[17,2]'          1
493   'ColorMAXChanges[17,3]'          1
494   'ColorMAXChanges[18,1]'          1
495   'ColorMAXChanges[18,2]'          1
496   'ColorMAXChanges[18,3]'          1
497   'ColorMAXChanges[19,1]'          1
498   'ColorMAXChanges[19,2]'          1
499   'ColorMAXChanges[19,3]'          1
500   'ColorMAXChanges[20,1]'          1
501   'ColorMAXChanges[20,2]'          1
502   'ColorMAXChanges[20,3]'          1
503   'ColorMAXChanges[21,1]'          1
504   'ColorMAXChanges[21,2]'          1
505   'ColorMAXChanges[21,3]'          1
506   'ColorMAXChanges[22,1]'          1
507   'ColorMAXChanges[22,2]'          1
508   'ColorMAXChanges[22,3]'          1
509   'ColorMAXChanges[23,1]'          1
510   'ColorMAXChanges[23,2]'          1
511   'ColorMAXChanges[23,3]'          1
512   'ColorMAXChanges[24,1]'          1
513   'ColorMAXChanges[24,2]'          1
514   'ColorMAXChanges[24,3]'          1
515   'ColorMAXChanges[25,1]'          1
516   'ColorMAXChanges[25,2]'          1
517   'ColorMAXChanges[25,3]'          1
518   'ColorMAXChanges[26,1]'          1
519   'ColorMAXChanges[26,2]'          1
520   'ColorMAXChanges[26,3]'          1
521   'ColorMAXChanges[27,1]'          1
522   'ColorMAXChanges[27,2]'          1
523   'ColorMAXChanges[27,3]'          1
524   'ColorMAXChanges[28,1]'          1
525   'ColorMAXChanges[28,2]'          1
526   'ColorMAXChanges[28,3]'          1
527   'ColorMAXChanges[29,1]'          1
528   'ColorMAXChanges[29,2]'          1
529   'ColorMAXChanges[29,3]'          1
530   'ColorMAXChanges[30,1]'          1
531   'ColorMAXChanges[30,2]'          1
532   'ColorMAXChanges[30,3]'          1
533   'ColorMAXChanges[31,1]'          1
534   'ColorMAXChanges[31,2]'          1
535   'ColorMAXChanges[31,3]'          1
536   'ColorMAXChanges[32,1]'          1
537   'ColorMAXChanges[32,2]'          1
538   'ColorMAXChanges[32,3]'          1
539   'ColorMAXChanges[33,1]'          1
540   'ColorMAXChanges[33,2]'          1
541   'ColorMAXChanges[33,3]'          1
542   'ColorMAXChanges[34,1]'          1
543   'ColorMAXChanges[34,2]'          1
544   'ColorMAXChanges[34,3]'          1
545   'ColorMAXChanges[35,1]'          1
546   'ColorMAXChanges[35,2]'          1
547   'ColorMAXChanges[35,3]'          1
548   'ColorMAXChanges[36,1]'          1
549   'ColorMAXChanges[36,2]'          1
550   'ColorMAXChanges[36,3]'          1
551   'ColorMAXChanges[37,1]'          1
552   'ColorMAXChanges[37,2]'          1
553   'ColorMAXChanges[37,3]'          1
554   'ColorMAXChanges[38,1]'          1
555   'ColorMAXChanges[38,2]'          1
556   'ColorMAXChanges[38,3]'          1
557   'ColorMAXChanges[39,1]'          1
558   'ColorMAXChanges[39,2]'          1
559   'ColorMAXChanges[39,3]'          1
560   'ColorMAXChanges[40,1]'          1
561   'ColorMAXChanges[40,2]'          1
562   'ColorMAXChanges[40,3]'          1
563   'ColorMAXChanges[41,1]'          1
564   'ColorMAXChanges[41,2]'          1
565   'ColorMAXChanges[41,3]'          1
566   'ColorMAXChanges[42,1]'          1
567   'ColorMAXChanges[42,2]'          1
568   'ColorMAXChanges[42,3]'          1
569   'ColorMAXChanges[43,1]'          1
570   'ColorMAXChanges[43,2]'          1
571   'ColorMAXChanges[43,3]'          1
572   'ColorMAXChanges[44,1]'          1
573   'ColorMAXChanges[44,2]'          1
574   'ColorMAXChanges[44,3]'          1
575   'ColorMAXChanges[45,1]'          1
576   'ColorMAXChanges[45,2]'          1
577   'ColorMAXChanges[45,3]'          1
578   'ColorMAXChanges[46,1]'          1
579   'ColorMAXChanges[46,2]'          1
580   'ColorMAXChanges[46,3]'          1
581   'ColorMAXChanges[47,1]'          1
582   'ColorMAXChanges[47,2]'          1
583   'ColorMAXChanges[47,3]'          1
584   'ColorMAXChanges[48,1]'          1
585   'ColorMAXChanges[48,2]'          1
586   'ColorMAXChanges[48,3]'          1
587   'ColorMAXChanges[49,1]'          1
588   'ColorMAXChanges[49,2]'          1
589   'ColorMAXChanges[49,3]'          1
;

Parameter adjustment#

Let us manually adjust solver settings and see if this improves performance.

ampl.option["reset_initial_guesses"] = (
    1  # Don't send the known solution as initial guess
)

ampl.option["mp_options"] = "outlev=1 " + "mip:sbestimate=6 " + "mip:sbeffort=0.25"

ampl.solve()
XPRESS 9.8.0 (46.01.01):   tech:outlev = 1
  mip:sbestimate = 6
  mip:sbeffort = 0.25

AMPL MP initial flat model has 710 variables (300 integer, 395 binary);
Objectives: 1 linear; 
Constraints:  10 linear;
Algebraic expressions:  5 count;
Logical expressions:  917 conditional (in)equalitie(s); 297 and; 269 not; 589 or;

AMPL MP final model has 2981 variables (894 integer, 2072 binary);
Objectives: 1 linear; 
Constraints:  379 linear;
Logical expressions:  297 and; 617 indeq; 589 or;


FICO Xpress v9.8.0, Hyper, solve started 16:56:35, Mar 3, 2026
Heap usage: 1398KB (peak 1398KB, 54KB system)
Minimizing MILP  using up to 8 threads and up to 16GB memory, with these control settings:
SBESTIMATE = 6
SBEFFORT = .25
Original problem has:
       996 rows         2981 cols         2270 elements      2178 entities
       617 inds
       886 gencons
Presolved problem has:
      1750 rows         1168 cols         7208 elements      1153 entities
LP relaxation tightened
Presolve finished in 0 seconds
Heap usage: 5518KB (peak 6248KB, 190KB system)

Coefficient range                    original                 solved        
  Coefficients   [min,max] : [ 1.00e+00,  5.00e+00] / [ 6.25e-02,  1.88e+00]
  RHS and bounds [min,max] : [ 1.00e+00,  1.50e+01] / [ 2.50e-01,  3.90e+01]
  Objective      [min,max] : [ 6.55e-01,  1.00e+01] / [ 6.55e-01,  1.00e+01]
Autoscaling applied standard scaling

Symmetric problem: generators: 2, support set: 711
 Number of orbits: 237, largest orbit: 3
 Row orbits: 326, row support: 978
Will try to keep branch and bound tree memory usage below 15.1GB
 *** Solution found:   387.306070   Time:   0.05    Heuristic: e ***
Starting concurrent solve with dual (1 thread)

 Concurrent-Solve,   0s
            Dual        
    objective   sum inf 
 P  8.8582631   .0000000
                        
------- optimal --------
Concurrent statistics:
           Dual: 1286 simplex iterations, 0.02s
Optimal solution found
 
   Its         Obj Value      S   Ninf  Nneg        Sum Inf  Time
  1286          8.858263      P      0     0        .000000     0
Dual solved problem
  1286 simplex iterations in 0.02 seconds at time 0

Final objective                       : 8.858263143934892e+00
  Max primal violation      (abs/rel) : 1.110e-15 / 1.110e-15
  Max dual violation        (abs/rel) : 7.105e-15 / 7.105e-15
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Starting root cutting & heuristics
Deterministic mode with up to 2 additional threads
 
 Its Type    BestSoln    BestBound   Sols    Add    Del     Gap     GInf   Time
a          174.620879     8.858263      2                 94.93%       0      0
   1  K    174.620879    10.031479      2    651      0   94.26%     415      0
P          173.040639    10.031479      3                 94.20%       0      0
P          170.694632    10.031479      4                 94.12%       0      0
P          129.053008    10.031479      5                 92.23%       0      0
P          108.266420    10.031479      6                 90.73%       0      0
P          107.266420    10.031479      7                 90.65%       0      0
P          106.266420    10.031479      8                 90.56%       0      0
P          105.266420    10.031479      9                 90.47%       0      0
P           83.409770    10.031479     10                 87.97%       0      0
P           82.409770    10.031479     11                 87.83%       0      0
P           79.053727    10.031479     12                 87.31%       0      0
P           78.829529    10.031479     13                 87.27%       0      0
P           77.829529    10.031479     14                 87.11%       0      0
P           74.249288    10.031479     15                 86.49%       0      0
   2  K     74.249288    10.618005     15    244    447   85.70%     656      0
P           66.669048    10.618005     16                 84.07%       0      0
P           64.669048    10.618005     17                 83.58%       0      0
P           54.508566    10.618005     18                 80.52%       0      0
P           53.732763    10.618005     19                 80.24%       0      0
P           53.508566    10.618005     20                 80.16%       0      0
P           52.508566    10.618005     21                 79.78%       0      0
P           51.508566    10.618005     22                 79.39%       0      0
P           44.928325    10.618005     23                 76.37%       0      0
P           42.928325    10.618005     24                 75.27%       0      0
   3  K     42.928325    10.900395     24    136    174   74.61%     536      0
P           41.928325    10.900395     25                 74.00%       0      0
P           40.928325    10.900395     26                 73.37%       0      0
P           39.928325    10.900395     27                 72.70%       0      0
   4  K     39.928325    11.310295     27    137    104   71.67%     468      0
P           38.928325    11.310295     28                 70.95%       0      0
P           36.928325    11.310295     29                 69.37%       0      0
   5  K     36.928325    11.374333     29    211    119   69.20%     471      0
   6  K     36.928325    11.424315     29     86    146   69.06%     476      0
   7  K     36.928325    11.450172     29     73     69   68.99%     534      0
   8  K     36.928325    11.527816     29     88     49   68.78%     522      0
   9  K     36.928325    11.653084     29    146    143   68.44%     530      0
q           22.858263    11.753555     30                 48.58%       0      0
  10  K     22.858263    11.753555     30     83     79   48.58%     525      0
  11  K     22.858263    11.930751     30     78     71   47.81%     494      0
  12  K     22.858263    12.167057     30    205    127   46.77%     422      0
  13  K     22.858263    12.250232     30    173    148   46.41%     459      0
  14  K     22.858263    12.367191     30    164    129   45.90%     324      0
  15  K     22.858263    12.528982     30    117    166   45.19%     395      0
  16  K     22.858263    12.573604     30     73    119   44.99%     290      0
  17  K     22.858263    12.592551     30     56     30   44.91%     285      0
  18  K     22.858263    12.601555     30     26     50   44.87%     278      0
  19  K     22.858263    12.603192     30     31     18   44.86%     275      0
  20  K     22.858263    12.609901     30     18     20   44.83%     273      0
  21  K     22.858263    12.613684     30     20     30   44.82%     287      0
  22  K     22.858263    12.615898     30     39     46   44.81%     302      0
  23  K     22.858263    12.618380     30     35     31   44.80%     293      0
  24  K     22.858263    12.620199     30     32     21   44.79%     293      0
  25  K     22.858263    12.634125     30     26    264   44.73%     269      0
  26  G     22.858263    12.774378     30     40      0   44.11%     270      0
  27  G     22.858263    12.923963     30     53     99   43.46%     307      0
 
Cuts in the matrix         : 342
Cut elements in the matrix : 8244

Performing root presolve...

Reduced problem has:    1301 rows     551 columns     10045 elements
Presolve dropped   :     791 rows     617 columns      5407 elements
Symmetric problem: generators: 2, support set: 153
 Number of orbits: 51, largest orbit: 3
 Row orbits: 89, row support: 267
Will try to keep branch and bound tree memory usage below 15.1GB
Crash basis containing 147 structural columns created
 
   Its         Obj Value      S   Ninf  Nneg        Sum Inf  Time
  8141          9.114682      P      0     0        .000000     0
Optimal solution found
Dual solved problem
  8141 simplex iterations in 0.01 seconds at time 0

Final objective                       : 9.114682343403359e+00
  Max primal violation      (abs/rel) : 2.220e-16 / 2.220e-16
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Starting root cutting & heuristics
Deterministic mode with up to 2 additional threads
 
 Its Type    BestSoln    BestBound   Sols    Add    Del     Gap     GInf   Time
   1  K     22.858263    13.126183     30     64     99   42.58%     287      0
   2  K     22.858263    13.199209     30     30    181   42.26%     321      0
Heuristic search 'R' started
Heuristic search 'R' stopped
 
Cuts in the matrix         : 156
Cut elements in the matrix : 3195

Starting tree search.
Deterministic mode with up to 8 running threads and up to 16 tasks.
Heap usage: 12MB (peak 35MB, 607KB system)
 
    Node     BestSoln    BestBound   Sols Active  Depth     Gap     GInf   Time
       1    22.858263    13.271696     30      2      1   41.94%     297      0
       2    22.858263    13.415500     30      2      3   41.31%     294      0
       3    22.858263    13.508573     30      3      3   40.90%     280      0
       4    22.858263    13.508573     30      4      4   40.90%     274      0
       5    22.858263    13.555142     30      5      4   40.70%     279      0
       6    22.858263    13.555142     30      6      4   40.70%     209      0
       7    22.858263    13.555142     30      7      4   40.70%     278      0
       8    22.858263    13.555142     30      8      5   40.70%      88      0
       9    22.858263    13.623471     30      9      5   40.40%     242      0
      10    22.858263    13.824121     30     10      5   39.52%     228      0
      21    22.858263    13.859932     30     20      8   39.37%      77      0
      37    22.858263    13.861824     30     28     16   39.36%     105      0
      47    22.858263    13.973917     30     40     10   38.87%     196      0
      69    22.858263    13.973917     30     52     30   38.87%      40      0
q     75    21.858263    13.973917     31     52     36   36.07%       0      1
      80    21.858263    13.973917     31     68      1   36.07%       2      1
      95    21.858263    13.973917     31     76     17   36.07%     149      1
     118    21.858263    13.973917     31     83     40   36.07%      38      1
q    149    17.858263    13.973917     32    116     35   21.75%       0      1
Elapsed time (sec): 1, estimated tree completion: 0.00042
Heap usage: 60MB (peak 60MB, 818KB system)
B&B tree size: 336k total
 
    Node     BestSoln    BestBound   Sols Active  Depth     Gap     GInf   Time
     221    17.858263    13.973917     32     82      1   21.75%       2      1
     324    17.858263    13.987125     32    100     22   21.68%      52      1
     432    17.858263    13.990463     32    152     32   21.66%      58      1
     535    17.858263    14.069346     32    191     35   21.22%      18      1
     635    17.858263    14.069346     32    245     24   21.22%      69      1
     737    17.858263    14.069346     32    280     17   21.22%     111      1
     846    17.858263    14.186636     32    336     19   20.56%      29      1
     949    17.858263    14.189736     32    372     16   20.54%     101      1
    1058    17.858263    14.189736     32    396     21   20.54%      42      1
    1166    17.858263    14.299165     32    436     20   19.93%     105      1
    1268    17.858263    14.299165     32    455     16   19.93%      96      1
    1368    17.858263    14.299165     32    463     13   19.93%     109      1
    1471    17.858263    14.299165     32    491     18   19.93%      37      2
    1575    17.858263    14.299165     32    511     24   19.93%     101      2
    1680    17.858263    14.299165     32    533     20   19.93%      40      2
    1782    17.858263    14.428325     32    561     17   19.21%      96      2
q   1868    16.928325    14.428325     33    591     13   14.77%       0      2
    2110    16.928325    14.428325     33    355      1   14.77%       2      2
    2214    16.928325    14.428325     33    369      1   14.77%       2      2
    2318    16.928325    14.428325     33    375     18   14.77%     174      2
Elapsed time (sec): 2, estimated tree completion: 0.27327
Heap usage: 126MB (peak 126MB, 1096KB system)
B&B tree size: 1.8MB total
 
    Node     BestSoln    BestBound   Sols Active  Depth     Gap     GInf   Time
    2421    16.928325    14.514313     33    398     23   14.26%     146      2
    2523    16.928325    14.514313     33    401      1   14.26%       2      2
    2631    16.928325    14.518826     33    395     16   14.23%      88      2
    2738    16.928325    14.518826     33    396     15   14.23%     137      2
    2853    16.928325    14.518826     33    383     24   14.23%      38      2
    2957    16.928325    14.518826     33    387     15   14.23%      86      2
    3057    16.928325    14.518826     33    392     12   14.23%     133      2
    3165    16.928325    14.523405     33    401     21   14.21%      50      2
    3270    16.928325    14.537249     33    401     16   14.12%     192      2
    3371    16.928325    14.537249     33    396     20   14.12%      39      2
    3477    16.928325    14.537249     33    402     13   14.12%     122      2
    3579    16.928325    14.537249     33    403     13   14.12%      65      2
    3685    16.928325    14.618792     33    396     19   13.64%      92      2
    3785    16.928325    14.618792     33    407     28   13.64%      59      2
    3890    16.928325    14.765557     33    407     25   12.78%      38      2
    3992    16.928325    14.765557     33    396     12   12.78%      64      3
    4092    16.928325    14.765557     33    394     13   12.78%     143      3
    4195    16.928325    14.953008     33    371     30   11.67%      25      3
    4299    16.928325    14.953008     33    366     16   11.67%      94      3
    4406    16.928325    14.963144     33    336     20   11.61%     105      3
Elapsed time (sec): 3, estimated tree completion: 0.78700
Heap usage: 126MB (peak 126MB, 1096KB system)
B&B tree size: 2.4MB total
 
    Node     BestSoln    BestBound   Sols Active  Depth     Gap     GInf   Time
    4517    16.928325    14.975981     33    319     29   11.53%      20      3
    4621    16.928325    14.981675     33    304     21   11.50%      72      3
    4724    16.928325    14.997455     33    305     14   11.41%      87      3
    4826    16.928325    14.997455     33    286     24   11.41%       9      3
    4926    16.928325    14.997455     33    248     13   11.41%      61      3
    5026    16.928325    15.009350     33    228     18   11.34%     155      3
    5129    16.928325    15.071985     33    183     25   10.97%      60      3
    5229    16.928325    15.159958     33    144     19   10.45%      83      3
    5335    16.928325    15.159958     33     66     20   10.45%      84      3
    5435    16.928325    15.259026     33     56     15    9.86%     147      3
    5535    16.928325    15.320438     33     40     13    9.50%     100      3
    5636    16.928325    15.320438     33     22     17    9.50%      48      3
    5744    16.928325    15.650473     33     31     28    7.55%      37      3
    5846    16.928325    15.830323     33     30     18    6.49%      77      3
    5946    16.928325    15.928325     33     15     17    5.91%      68      3
 *** Search completed ***
Uncrunching matrix
Final MIP objective                   : 1.692832483996361e+01
Final MIP bound                       : 1.692830791163877e+01
  Solution time / primaldual integral :      3.68s/ 27.497451%
  Work / work units per second        :      4.66 /      1.27
  Number of solutions found / nodes   :        33 /      5995
  Max primal violation      (abs/rel) : 2.442e-15 / 2.442e-15
  Max integer violation     (abs    ) : 4.885e-15
XPRESS 9.8.0 (46.01.01): optimal solution; objective 16.92832484
438820 simplex iterations
5995 branching nodes
absmipgap=1.69283e-05, relmipgap=1e-06

Retrieve solution as a Pandas dataframe#

ampl.var["slot_pattern"].to_pandas()
slot_pattern.val
1 3
2 3
3 2
4 2
5 2
6 2
7 2
8 2
9 2
10 1
11 1
12 1
13 1
14 1
15 1
16 1
17 1
18 1
19 0
20 0
21 5
22 5
23 5
24 5
25 5
26 5
27 5
28 5
29 5
30 5
31 5
32 5
33 4
34 4
35 4
36 4
37 4
38 4
39 4
40 4
41 4
42 4
43 2
44 2
45 2
46 2
47 2
48 2
49 2
50 2

Conclusion#

Manual parameter adjustment FICO Xpress 9.8.0 reduced solve time from 4.34s to 3.68s on Mac M1 Pro. With enough preparation time, Xpress Tuner is recommended for automatic adjustment (AMPL Xpress option tech:xprs_tunemode).