# Create variables representing from index and to index for each move fromIndex = mdl.integer_var_list(NB_MOVES, 0, SIZE - 1, "From_") toIndex = mdl.integer_var_list(NB_MOVES, 0, SIZE - 1, "To_") # Add constraints between each state for m in range(NB_MOVES): fvar = fromIndex[m] tvar = toIndex[m] fromState = states[m] toState = states[m + 1] # Constrain location of holes mdl.add(mdl.element(fromState, tvar) == HOLE) # Constrain move size and direction delta = tvar - fvar mdl.add(mdl.allowed_assignments(delta, [-2, -1, 1, 2])) peg = mdl.element(fromState, fvar) mdl.add( ((peg == RED) & (delta > 0)) | ((peg == BLUE) & (delta < 0)) ) # Make moves mdl.add(mdl.element(toState, tvar) == mdl.element(fromState, fvar)) mdl.add(mdl.element(toState, fvar) == HOLE) # Force equality of other positions for p in range(SIZE): mdl.add(mdl.if_then((p != fvar) & (p != tvar), fromState[p] == toState[p])) # Set initial position for p in range(NB_PEGS): mdl.add(states[0][p] == RED) mdl.add(states[0][p + NB_PEGS + 1] == BLUE) mdl.add(states[0][NB_PEGS] == HOLE)
where = mdl.integer_var_list(nbOrders, 0, maxDeliveries - 1, "where") # Load of a truck load = mdl.integer_var_list(maxDeliveries, 0, maxLoad, "load") # Number of deliveries that are required nbDeliveries = mdl.integer_var(0, maxDeliveries) # Identification of which customer is assigned to a delivery customerOfDelivery = mdl.integer_var_list(maxDeliveries, 0, nbCustomers, "customerOfTruck") # Transition cost for each delivery transitionCost = mdl.integer_var_list(maxDeliveries - 1, 0, 1000, "transitionCost") # transitionCost[i] = transition cost between configurations i and i+1 for i in range(1, maxDeliveries): auxVars = (truckConfigs[i - 1], truckConfigs[i], transitionCost[i - 1]) mdl.add(mdl.allowed_assignments(auxVars, CONFIGURATION_TRANSITION_COST)) # Constrain the volume of the orders in each truck mdl.add(mdl.pack(load, where, volumes, nbDeliveries)) for i in range(0, maxDeliveries): mdl.add(load[i] <= mdl.element(truckConfigs[i], maxTruckConfigLoad)) # Compatibility between the product type of an order and the configuration of its truck for j in range(0, nbOrders): configOfContainer = mdl.integer_var( ALLOWED_CONTAINER_CONFIGS[productType[j]]) mdl.add(configOfContainer == mdl.element(truckConfigs, where[j])) # Only one customer per delivery for j in range(0, nbOrders): mdl.add(mdl.element(customerOfDelivery, where[j]) == CUSTOMER_ORDERS[j][0])