Моделирование задачи трёхмерной упаковки грузов в контейнеры

Автор:

Фетисова А.Д., ГБОУ Школа 460, 10 «Н»

Руководитель:

Крысанов В.О., ГБОУ Школа 460,

учитель математики, информатики

Актуальность

  • Большая практическая значимость для многих отраслей промышленности (транспортировка/хранение).
  •       -полная задача.
  • Подбор эффективного метода решения конкретной задачи с учётом необходимых ограничений.
\mathcal{NP}

Цели и задачи работы

Цель работы: разработка программы, которая решает задачу о трёхмерной упаковке.

 

Задачи работы:

1.  Исследование предметной области и составление математической модели.

2.  Выбор средств для разработки программы.
3.  Реализация алгоритма упаковки.
4.  Разработка пользовательского интерфейса.

Математические аспекты

Алгоритм:

x
y
z
C_i(l, w, h)
Top - Right - Front​
\{C_1, C_2, C_3, ..., C_n\}

Множество грузов:

Множество контейнеров:

\{S_1, S_2, ... S_m\}
S_i(l, w, h)

Требования:

1) каждый груз размещен только в одном контейнере:

(\exists C_i \in S_j )\Rightarrow C_i \notin S_k, \forall k \in [1, m], k \ne j.

Математические аспекты (2)

\tau
\tau_{i_1}
\tau_{i_2}
\tau_{i_1} + l_{i_1}
\tau_{i_2} + l_{i_2}

2) грузы не должны перекрывать друг друга:

\Rightarrow \begin{cases} \big(x_{i_2} < (x_{i_1} + l_{i_1})\big) \wedge \big(x_{i_1} < (x_{i_2} + l_{i_2})\big); \\ \big(y_{i_2} < (y_{i_1} + w_{i_1})\big) \wedge \big(y_{i_1} < (y_{i_2} + w_{i_2})\big); \\ \big(z_{i_2} < (z_{i_1} + h_{i_1})\big) \wedge \big(z_{i_1} < (z_{i_2} + h_{i_2})\big). \end{cases}
\tau

3) груз не должны выходить за границы контейнера:

0
\tau_{i_1}
\tau_{i_1} + l_{i_1}
B_\tau
\Rightarrow \begin{cases} \big(0 < x_{i_1} < B_x\big) \wedge \big(0 < x_{i_1} + l_{i_1} < B_x\big)\big); \\ \big(0 < y_{i_1} < B_y\big) \wedge \big(0 < y_{i_1} + l_{i_1} < B_y\big)\big); \\ \big(0 < z_{i_1} < B_z\big) \wedge \big(0 < z_{i_1} + l_{i_1} < B_z\big)\big). \end{cases}

Используемые программные cредства

Архитектура приложения

Пример кода на Ruby

# fit shimpent on a shimpent?
  def is_under_fits?(shimpent)
    if @shipments.empty?
      self.width  >= shimpent.width &&
      self.depth  >= shimpent.depth &&
      self.height >= shimpent.height
    else
      under_shipment = @shipments.last.last.last

      under_shipment.width >= shimpent.width  &&
      under_shipment.depth >= shimpent.depth  &&
      self.height - (under_shipment.p.z + under_shipment.height) >= shimpent.height
    end
  end
\begin{cases} \big(x_{i_2} < (x_{i_1} + l_{i_1})\big) \wedge \big(x_{i_1} < (x_{i_2} + l_{i_2})\big); \\ \big(y_{i_2} < (y_{i_1} + w_{i_1})\big) \wedge \big(y_{i_1} < (y_{i_2} + w_{i_2})\big); \\ \big(z_{i_2} < (z_{i_1} + h_{i_1})\big) \wedge \big(z_{i_1} < (z_{i_2} + h_{i_2})\big). \end{cases}

Условия «непересечения» грузов

JSON результат. Переход к рендеру

{
  "solution"=>[{
    "airplane_type"=>"tu204",
    "cargo_index"=>"1",
    "x_on_box"=>[0.0, 0.0, 0.0]
	},
    {"airplane_type"=>"tu204",
      "airplane_index"=>"2",
      "x_on_box"=>[0.0, 0.0, 2.0]
    }]
}
{"2":[[12,12,12],
      {"airplane_type":"tu204",
       "airplane_index":"2",
       "cargo_type":"cargo_type_name_2",
       "cargo_index":"1",
       "x_on_box":[0.0,0.0,0.0],
       "y_on_box":[2,2,2]
      },
      {"airplane_type":"tu204",
       "airplane_index":"2",
       "cargo_type":"cargo_type_name_1",
       "cargo_index":"0",
       "x_on_box":[0.0,0.0,2.0],
       "y_on_box":[1,1,2]
      }
     ]
}
\begin{cases} \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \end{cases}

Результат работы алгоритма

Пример работы three.js

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
  75, window.innerWidth / window.innerHeight, 0.1, 1000
);

const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

Пример создания пустой сцены без освещения

Пример работы three.js (2)

function aircraft_draw(cnv){
  ...
  	...
    // отрисовка самих грузов самолета:
    // координаты груза можно получить с помощью
    //  .y_on_box и .x_on_box в solution[i][j], которые вернут массывы [x, y, z]
    //  точки X и Y груза соответственно
    for (j = 1; j < solution[i].length; j++){
      var cargoGeometry = new THREE.BoxGeometry( solution[i][j].y_on_box[0],
                                                 solution[i][j].y_on_box[1],
                                                 solution[i][j].y_on_box[2]
                                               )
      var cargoMaterial = new THREE.MeshLambertMaterial(
                                          { color: Math.random() * lightColor } )
      var cargoCube     = new THREE.Mesh( cargoGeometry, cargoMaterial )
      scene.add( cargoCube );
      cargoCube.position.x = solution[i][j].x_on_box[0] + solution[i][j].y_on_box[0]/2
      cargoCube.position.y = solution[i][j].x_on_box[1] + solution[i][j].y_on_box[1]/2
      cargoCube.position.z = solution[i][j].x_on_box[2] + solution[i][j].y_on_box[2]/2
    }
  }
  render()
}

Интерактивная сцена с грузами

Интерфейс ввода данных

Форма для создания новых грузов

Форма для создания новых контейнеров

Интерфейс выходных данных

Интерфейс выходных данных (2)

Интерфейс списка задач

Пример работы программы

Пример работы программы

Заключение. Дальнейшее развитие

В результате выполнения работы было спроектировано и разработано приложение, полностью удовлетворяющее требованиям поставленных задач.

Made with Slides.com