<commit_before>/*

This file is part of VROOM.

Copyright (c) 2015-2018, <NAME>.
All rights reserved (see LICENSE).

*/

#include "tsp.h"
#include "../../structures/vroom/input/input.h"

tsp::tsp(const input& input,
         std::vector<index_t> problem_indices,
         index_t vehicle_rank)
  : vrp(input),
    _vehicle_rank(vehicle_rank),
    _tsp_index_to_global(std::move(problem_indices)),
    _matrix(_input._matrix.get_sub_matrix(_tsp_index_to_global)),
    _symmetrized_matrix(_matrix.size()),
    _is_symmetric(true),
    _has_start(_input._vehicles[_vehicle_rank].has_start()),
    _has_end(_input._vehicles[_vehicle_rank].has_end()) {

  // Distances on the diagonal are never used except in the minimum
  // weight perfect matching (munkres call during the heuristic). This
  // makes sure no node will be matched with itself at that time.
  for (index_t i = 0; i < _matrix.size(); ++i) {
    _matrix[i][i] = INFINITE_COST;
  }

  if (_has_start) {
    // Use index in _matrix for start.
    auto search =
      std::find(_tsp_index_to_global.begin(),
                _tsp_index_to_global.end(),
                _input._vehicles[_vehicle_rank].start.get().index());
    assert(search != _tsp_index_to_global.end());
    _start = std::distance(_tsp_index_to_global.begin(), search);
    assert(_start < _matrix.size());
  }
  if (_has_end) {
    // Use index in _matrix for start.
    auto search = std::find(_tsp_index_to_global.begin(),
                            _tsp_index_to_global.end(),
                            _input._vehicles[_vehicle_rank].end.get().index());
    assert(search != _tsp_index_to_global.end());
    _end = std::distance(_tsp_index_to_global.begin(), search);
    assert(_end < _matrix.size());
  }

  _round_trip = _has_start and _has_end and (_start == _end);

  if (!_round_trip) {
    // Dealing with open tour cases. Exactly one of the following
    // happens.
    if (_has_start and !_has_end) {
      // Forcing first location as start, end location decided during
      // optimization.
      for (index_t i = 0; i < _matrix.size(); ++i) {
        if (i != _start) {
          _matrix[i][_start] = 0;
        }
      }
    }
    if (!_has_start and _has_end) {
      // Forcing last location as end, start location decided during
      // optimization.
      for (index_t j = 0; j < _matrix.size(); ++j) {
        if (j != _end) {
          _matrix[_end][j] = 0;
        }<commit_msg>Adjust determination of tsp::_start and tsp::_end.<commit_after>/*

This file is part of VROOM.

Copyright (c) 2015-2018, <NAME>.
All rights reserved (see LICENSE).

*/

#include "tsp.h"
#include "../../structures/vroom/input/input.h"

tsp::tsp(const input& input,
         std::vector<index_t> problem_indices,
         index_t vehicle_rank)
  : vrp(input),
    _vehicle_rank(vehicle_rank),
    _tsp_index_to_global(std::move(problem_indices)),
    _matrix(_input._matrix.get_sub_matrix(_tsp_index_to_global)),
    _symmetrized_matrix(_matrix.size()),
    _is_symmetric(true),
    _has_start(_input._vehicles[_vehicle_rank].has_start()),
    _has_end(_input._vehicles[_vehicle_rank].has_end()) {

  // Distances on the diagonal are never used except in the minimum
  // weight perfect matching (munkres call during the heuristic). This
  // makes sure no node will be matched with itself at that time.
  for (index_t i = 0; i < _matrix.size(); ++i) {
    _matrix[i][i] = INFINITE_COST;
  }

  if (_has_start) {
    // Use index in _matrix for start.
    bool start_found;
    for (index_t i = 0; i < _tsp_index_to_global.size(); ++i) {
      start_found = (_input._type_with_ids[i].type == TYPE::START) and
        (_tsp_index_to_global[i] == _input._vehicles[_vehicle_rank].start.get().index());
      if (start_found) {
        _start = i;
        break;
      }
    }
    assert(start_found);
  }
  if (_has_end) {
    // Use index in _matrix for end.
    bool end_found;
    for (index_t i = 0; i < _tsp_index_to_global.size(); ++i) {
      // Not checking for TYPE::END here because when start_index and
      // end_index are both provided and equal, then the end location
      // is not duplicated in input::_locations.
      end_found = (_input._type_with_ids[i].type != TYPE::JOB) and
        (_tsp_index_to_global[i] == _input._vehicles[_vehicle_rank].end.get().index());
      if (end_found) {
        _end = i;
        break;
      }
    }
    assert(end_found);
  }

  _round_trip = _has_start and _has_end and (_start == _end);

  if (!_round_trip) {
    // Dealing with open tour cases. Exactly one of the following
    // happens.
    if (_has_start and !_has_end) {
      // Forcing first location as start, end location decided during
      // optimization.
      for (index_t i = 0; i < _matrix.size(); ++i) {
        if (i != _start) {
          _matrix[i][_start] = 0;
        }
      }
    }
    if (!_has_start and _has_end) {
      // Forcing last location as end, start location decided during
      // optimization.
      for (index_t j = 0; j < _matrix.size(); ++j) {
        if (j != _end) {
          _matrix[_end][j] = 0;
        }
{'fraction_non_alphanumeric': 0.1304433111023931, 'fraction_numerical': 0.005492349941153394, 'mean_word_length': 2.7355311355311356, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3274609', 'n_tokens_mistral': 1760, 'n_tokens_neox': 1695, 'n_words': 423}