csls_api.cs 5.96 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
// Copyright 2010-2018 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using Google.OrTools.ConstraintSolver;

/**
 * Shows how to write a custom lns operator.
 */

public class OneVarLns : BaseLns
{
  public OneVarLns(IntVar[] vars) : base(vars) {}

  public override void InitFragments()
  {
    index_ = 0;
  }

  public override bool NextFragment()
  {
    int size = Size();
    if (index_ < size)
    {
      AppendToFragment(index_);
      ++index_;
      return true;
    }
    else
    {
      return false;
    }
  }

  private int index_;
}

class MoveOneVar : IntVarLocalSearchOperator {
 public MoveOneVar(IntVar[] variables) : base(variables)
  {
    variable_index_ = 0;
    move_up_ = false;
  }

  protected override bool MakeOneNeighbor()
  {
    long current_value = OldValue(variable_index_);
    if (move_up_)
    {
      SetValue(variable_index_, current_value  + 1);
      variable_index_ = (variable_index_ + 1) % Size();
    }
    else
    {
      SetValue(variable_index_, current_value  - 1);
    }
    move_up_ = !move_up_;
    return true;
  }

  // Index of the next variable to try to restore
  private long variable_index_;
  // Direction of the modification.
  private bool move_up_;
};

public class SumFilter : IntVarLocalSearchFilter {
  public SumFilter(IntVar[] vars) : base(vars)
  {
    sum_ = 0;
  }

  protected override void OnSynchronize(Assignment delta)
  {
    sum_ = 0;
    for (int index = 0; index < Size(); ++index)
    {
      sum_ += Value(index);
    }
  }

  public override bool Accept(Assignment delta, Assignment unused_deltadelta,
                              long unused_objective_min,
			      long unused_objective_max) {
    AssignmentIntContainer solution_delta = delta.IntVarContainer();
    int solution_delta_size = solution_delta.Size();

    for (int i = 0; i < solution_delta_size; ++i)
    {
      if (!solution_delta.Element(i).Activated())
      {
        return true;
      }
    }
    long new_sum = sum_;
    for (int index = 0; index < solution_delta_size; ++index)
    {
      int touched_var = Index(solution_delta.Element(index).Var());
      long old_value = Value(touched_var);
      long new_value = solution_delta.Element(index).Value();
      new_sum += new_value - old_value;
    }
    return new_sum < sum_;
  }

 private long sum_;
};

public class CsLsApi
{
  private static void BasicLns()
  {
    Console.WriteLine("BasicLns");
    Solver solver = new Solver("BasicLns");
    IntVar[] vars = solver.MakeIntVarArray(4, 0, 4, "vars");
    IntVar sum_var = vars.Sum().Var();
    OptimizeVar obj = sum_var.Minimize(1);
    DecisionBuilder db = solver.MakePhase(vars,
                                          Solver.CHOOSE_FIRST_UNBOUND,
                                          Solver.ASSIGN_MAX_VALUE);
    OneVarLns one_var_lns = new OneVarLns(vars);
    LocalSearchPhaseParameters ls_params =
        solver.MakeLocalSearchPhaseParameters(sum_var, one_var_lns, db);
    DecisionBuilder ls = solver.MakeLocalSearchPhase(vars, db, ls_params);
    SolutionCollector collector = solver.MakeLastSolutionCollector();
    collector.AddObjective(sum_var);
    SearchMonitor log = solver.MakeSearchLog(1000, obj);
    solver.Solve(ls, collector, obj, log);
    Console.WriteLine("Objective value = {0}", collector.ObjectiveValue(0));
  }

  private static void BasicLs()
  {
    Console.WriteLine("BasicLs");
    Solver solver = new Solver("BasicLs");
    IntVar[] vars = solver.MakeIntVarArray(4, 0, 4, "vars");
    IntVar sum_var = vars.Sum().Var();
    OptimizeVar obj = sum_var.Minimize(1);
    DecisionBuilder db = solver.MakePhase(vars,
                                          Solver.CHOOSE_FIRST_UNBOUND,
                                          Solver.ASSIGN_MAX_VALUE);
    MoveOneVar move_one_var = new MoveOneVar(vars);
    LocalSearchPhaseParameters ls_params =
        solver.MakeLocalSearchPhaseParameters(sum_var, move_one_var, db);
    DecisionBuilder ls = solver.MakeLocalSearchPhase(vars, db, ls_params);
    SolutionCollector collector = solver.MakeLastSolutionCollector();
    collector.AddObjective(sum_var);
    SearchMonitor log = solver.MakeSearchLog(1000, obj);
    solver.Solve(ls, collector, obj, log);
    Console.WriteLine("Objective value = {0}", collector.ObjectiveValue(0));
  }

  private static void BasicLsWithFilter()
  {
    Console.WriteLine("BasicLsWithFilter");
    Solver solver = new Solver("BasicLs");
    IntVar[] vars = solver.MakeIntVarArray(4, 0, 4, "vars");
    IntVar sum_var = vars.Sum().Var();
    OptimizeVar obj = sum_var.Minimize(1);
    DecisionBuilder db = solver.MakePhase(vars,
                                          Solver.CHOOSE_FIRST_UNBOUND,
                                          Solver.ASSIGN_MAX_VALUE);
    MoveOneVar move_one_var = new MoveOneVar(vars);
    SumFilter filter = new SumFilter(vars);
    IntVarLocalSearchFilter[] filters =
        new IntVarLocalSearchFilter[] { filter };
    LocalSearchPhaseParameters ls_params =
        solver.MakeLocalSearchPhaseParameters(sum_var, move_one_var, db,
						       null, filters);
    DecisionBuilder ls = solver.MakeLocalSearchPhase(vars, db, ls_params);
    SolutionCollector collector = solver.MakeLastSolutionCollector();
    collector.AddObjective(sum_var);
    SearchMonitor log = solver.MakeSearchLog(1000, obj);
    solver.Solve(ls, collector, obj, log);
    Console.WriteLine("Objective value = {0}", collector.ObjectiveValue(0));
  }


  public static void Main(String[] args)
  {
    BasicLns();
    BasicLs();
    BasicLsWithFilter();
  }
}