All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.chocosolver.examples.tutorial.AircraftLanding Maven / Gradle / Ivy

/*
 * This file is part of examples, http://choco-solver.org/
 *
 * Copyright (c) 2023, IMT Atlantique. All rights reserved.
 *
 * Licensed under the BSD 4-clause license.
 *
 * See LICENSE file in the project root for full license information.
 */
package org.chocosolver.examples.tutorial;

import org.chocosolver.solver.Model;
import org.chocosolver.solver.Solver;
import org.chocosolver.solver.constraints.Constraint;
import org.chocosolver.solver.search.loop.monitors.IMonitorSolution;
import org.chocosolver.solver.search.strategy.Search;
import org.chocosolver.solver.search.strategy.assignments.DecisionOperatorFactory;
import org.chocosolver.solver.variables.IntVar;
import org.chocosolver.util.tools.ArrayUtils;

import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 *
 * 

* Project: samples. * @author Charles Prud'homme * @since 26/09/2016. */ public class AircraftLanding { public void modelAndSolve() { // number of planes int N = 10; // Times per plane: // {earliest landing time, target landing time, latest landing time} int[][] LT = { {129, 155, 559}, {195, 258, 744}, {89, 98, 510}, {96, 106, 521}, {110, 123, 555}, {120, 135, 576}, {124, 138, 577}, {126, 140, 573}, {135, 150, 591}, {160, 180, 657}}; // penalty cost penalty cost per unit of time per plane: // {for landing before target, after target} int[][] PC = { {10, 10}, {10, 10}, {30, 30}, {30, 30}, {30, 30}, {30, 30}, {30, 30}, {30, 30}, {30, 30}, {30, 30}}; // Separation time required after i lands before j can land int[][] ST = { {99999, 3, 15, 15, 15, 15, 15, 15, 15, 15}, {3, 99999, 15, 15, 15, 15, 15, 15, 15, 15}, {15, 15, 99999, 8, 8, 8, 8, 8, 8, 8}, {15, 15, 8, 99999, 8, 8, 8, 8, 8, 8}, {15, 15, 8, 8, 99999, 8, 8, 8, 8, 8}, {15, 15, 8, 8, 8, 99999, 8, 8, 8, 8}, {15, 15, 8, 8, 8, 8, 99999, 8, 8, 8}, {15, 15, 8, 8, 8, 8, 8, 999999, 8, 8}, {15, 15, 8, 8, 8, 8, 8, 8, 99999, 8}, {15, 15, 8, 8, 8, 8, 8, 8, 8, 99999}}; Model model = new Model("Aircraft landing"); // Variables declaration IntVar[] planes = IntStream .range(0, N) .mapToObj(i -> model.intVar("plane #" + i, LT[i][0], LT[i][2], false)) .toArray(IntVar[]::new); IntVar[] earliness = IntStream .range(0, N) .mapToObj(i -> model.intVar("earliness #" + i, 0, LT[i][1] - LT[i][0], false)) .toArray(IntVar[]::new); IntVar[] tardiness = IntStream .range(0, N) .mapToObj(i -> model.intVar("tardiness #" + i, 0, LT[i][2] - LT[i][1], false)) .toArray(IntVar[]::new); IntVar tot_dev = model.intVar("tot_dev", 0, IntVar.MAX_INT_BOUND); // Constraint posting // one plane per runway at a time: model.allDifferent(planes).post(); // for each plane 'i' for (int i = 0; i < N; i++) { // maintain earliness earliness[i].eq((planes[i].neg().add(LT[i][1])).max(0)).post(); // and tardiness tardiness[i].eq((planes[i].sub(LT[i][1])).max(0)).post(); // disjunctions: 'i' lands before 'j' or 'j' lands before 'i' for (int j = i + 1; j < N; j++) { Constraint iBeforej = model.arithm(planes[i], "<=", planes[j], "-", ST[i][j]); Constraint jBeforei = model.arithm(planes[j], "<=", planes[i], "-", ST[j][i]); model.addClausesBoolNot(iBeforej.reify(), jBeforei.reify()); // no need to post } } // prepare coefficients of the scalar product int[] cs = new int[N * 2]; for (int i = 0; i < N; i++) { cs[i] = PC[i][0]; cs[i + N] = PC[i][1]; } model.scalar(ArrayUtils.append(earliness, tardiness), cs, "=", tot_dev).post(); // Resolution process Solver solver = model.getSolver(); solver.plugMonitor((IMonitorSolution) () -> { for (int i = 0; i < N; i++) { System.out.printf("%s lands at %d (%d)\n", planes[i].getName(), planes[i].getValue(), planes[i].getValue() - LT[i][1]); } System.out.printf("Deviation cost: %d\n", tot_dev.getValue()); }); Map map = IntStream .range(0, N) .boxed() .collect(Collectors.toMap(i -> planes[i], i -> LT[i][1])); solver.setSearch(Search.intVarSearch( variables -> Arrays.stream(variables) .filter(v -> !v.isInstantiated()) .min((v1, v2) -> closest(v2, map) - closest(v1, map)) .orElse(null), var -> closest(var, map), DecisionOperatorFactory.makeIntEq(), planes )); solver.showShortStatistics(); solver.findOptimalSolution(tot_dev, false); } private static int closest(IntVar var, Map map) { int target = map.get(var); if (var.contains(target)) { return target; } else { int p = var.previousValue(target); int n = var.nextValue(target); return Math.abs(target - p) < Math.abs(n - target) ? p : n; } } public static void main(String[] args) { new AircraftLanding().modelAndSolve(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy