mapbox / mapbox/node-or-tools

Problem when providing pair of pickup and delivery indices

Đang mở
#63 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Ngôn ngữ chính
C++
Star
155
Fork
47
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

Hey,

There is this issue where providing a pair of pickup and delivery indices would lead to this error message: Unable to find a solution

Expected Behavior

It should return a valid route order based on cost array.

Current Behavior

Returns Unable to find a solution

Steps to Reproduce

  1. Copy node-or-tools/test/vrp.js file content to a new file
  2. Remove all assertions
  3. Add a pair of pickup and delivery indices in searchOpts.
   pickups: [4, 7],
   deliveries: [7, 10]

Context (Environment)

I have a pair of pickup and delivery indices and I want to visit one or more stops before visiting others.

This is my code snippet. You could see that if we remove the pickup and delivery indices, the code will work but after adding aforementioned indices, it returns Unable to find a solution

module.exports = () => {
  const ortools = require('node_or_tools')
  var locations = [
    [0, 0], [0, 1], [0, 2], [0, 3],
    [1, 0], [1, 1], [1, 2], [1, 3],
    [2, 0], [2, 1], [2, 2], [2, 3],
    [3, 0], [3, 1], [3, 2], [3, 3]]

  var depot = 0

  function manhattanDistance(lhs, rhs) {
    return Math.abs(lhs[0] - rhs[0]) + Math.abs(lhs[1] - rhs[1])
  }

  var costMatrix = new Array(locations.length)

  for (var from = 0; from < locations.length; ++from) {
    costMatrix[from] = new Array(locations.length)

    for (var to = 0; to < locations.length; ++to) {
      costMatrix[from][to] = manhattanDistance(locations[from], locations[to])
    }
  }

  var dayStarts = Hours(0)
  var dayEnds = Hours(3)


  var seed = 2147483650

  function ParkMillerRNG(seed) {
    var modulus = 2147483647
    var multiplier = 48271
    var increment = 0
    var state = seed

    return function() {
      state = (multiplier * state + increment) % modulus
      return state / modulus
    }
  }

  var rand = ParkMillerRNG(seed)


  function Seconds(v) {
    return v
  }

  function Minutes(v) {
    return Seconds(v * 60)
  }

  function Hours(v) {
    return Minutes(v * 60)
  }


  var durationMatrix = new Array(locations.length)

  for (var from = 0; from < locations.length; ++from) {
    durationMatrix[from] = new Array(locations.length)

    for (var to = 0; to < locations.length; ++to) {
      var serviceTime = Minutes(3)
      var travelTime = Minutes(costMatrix[from][to])

      durationMatrix[from][to] = serviceTime + travelTime
    }
  }


  var timeWindows = new Array(locations.length)

  for (var at = 0; at < locations.length; ++at) {
    if (at === depot) {
      timeWindows[at] = [dayStarts, dayEnds]
      continue
    }

    var earliest = dayStarts
    var latest = dayEnds - Hours(1)

    var start = rand() * (latest - earliest) + earliest
    var stop = rand() * (latest - start) + start

    timeWindows[at] = [start, stop]
  }


  var demandMatrix = new Array(locations.length)

  for (var from = 0; from < locations.length; ++from) {
    demandMatrix[from] = new Array(locations.length)

    for (var to = 0; to < locations.length; ++to) {
      if (from === depot)
        demandMatrix[from][to] = 0
      else
        demandMatrix[from][to] = 1
    }
  }


  var solverOpts = {
    numNodes: locations.length,
    costs: costMatrix,
    durations: durationMatrix,
    timeWindows: timeWindows,
    demands: demandMatrix
  }

  var VRP = new ortools.VRP(solverOpts)

  var numVehicles = 10
  var timeHorizon = dayEnds - dayStarts
  var vehicleCapacity = 10

// Dummy lock to let vehicle 0 go to location 2 and 3 first - to test route locks
  var routeLocks = new Array(numVehicles)

  for (var vehicle = 0; vehicle < numVehicles; ++vehicle) {
    if (vehicle === 0)
      routeLocks[vehicle] = [2, 3]
    else
      routeLocks[vehicle] = []
  }

  var searchOpts = {
    computeTimeLimit: 1000,
    numVehicles: numVehicles,
    depotNode: depot,
    timeHorizon: timeHorizon,
    vehicleCapacity: vehicleCapacity,
    routeLocks: routeLocks,
    pickups: [4, 7],
    deliveries: [7, 10]
  }

  VRP.Solve(searchOpts, function(err, solution) {


    console.log('**********************')
    console.log(err,solution)
    console.log('**********************')
    function used(v) {
      return v.length == 0 ? 0 : 1
    }

    function addition(l, r) {
      return l + r
    }

    var numVehiclesUsed = solution.routes.map(used).reduce(addition, 0)


    function checkRoute(v) {
      var depotInRoute = v.find(function(u) {
        return u == depot
      })
    }

    function checkTimeWindows(v) {
      v.forEach(function(u) {
      })
    }

    solution.routes.forEach(checkRoute)
    solution.times.forEach(checkTimeWindows)

  })

}

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu với node-or-tools/test/vrp.js, tái hiện lỗi bằng cách sử dụng các pickups, deliveries, routeLocks và time windows được示示, rồi lần theo điểm vào VRP.Solve đến binding. So sánh trường hợp lỗi với cùng ví dụ đó nhưng không có các chỉ mục pickup và delivery. Được coi là hoàn thành khi ví dụ trả về thứ tự tuyến hợp lệ mà không báo "Unable to find a solution".

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
cpp, javascript, node.js
Lĩnh vực
backend
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
35/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.