Форум программистов, компьютерный форум, киберфорум
Алгоритмы
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.87/55: Рейтинг темы: голосов - 55, средняя оценка - 4.87
681 / 555 / 74
Регистрация: 20.09.2014
Сообщений: 3,638

Задача оптимального раскроя

17.07.2021, 13:10. Показов 10930. Ответов 30

Author24 — интернет-сервис помощи студентам
У меня возникла реальная задача - написать программу для станка раскроя ткани. Ткань в рулоне ширины W, рулон разматывают на стол длины H в несколько заходов. Нужно оптимальным образом нарезать ортогональными резами N прямоугольных кусков размером (wi, hi). Особенность ножа в том, что он не совсем аккуратно режет углы, т.е. каждый разрез делается с запасом на небольшое расстояние d=5...8 мм в начале реза и на расстояние d в конце реза. Поэтому между прямоугольниками по обоим сторонам делается зазор величиной d и в результате сетка из полосок ткани толщиной d выбрасывается.
Чтобы не мучаться с этим дополнительным усложнением (d) будем считать, что нож все-таки режет идеально и зазоры между кусками не делаются, а все размеры кусков увеличиваются на величину d, прогоняются через оптимизационный алгоритм, а затем несложным алгоритмом результат оптимальной раскройки преобразуется в раскрой с зазорами.

Итак, фактически прямоугольники wi, hi нужно уложить в неограниченное количество рюкзаков размерами W, H. При этом нужно минимизировать потери ткани. При этом у последнего "рюкзака" часть неразрезанной (неиспорченной разрезами) ткани, оставшейся с рулоном, не является потерей. Станок отрезает эту часть ткани поперек и она сматывается обратно в рулон.

Добавлено через 1 час 35 минут
Два варианта алгоритма:
1. прямоугольники можно поворачивать на 90 градусов
2. нельзя поворачивать (направленный рисунок на ткани)
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
17.07.2021, 13:10
Ответы с готовыми решениями:

Поиск оптимального раскроя
Здравствуйте, помогите пожалуйста с алгоритмом: Есть список точек на плоскости, представляющих замкнутый контур. Необходимо найти...

Задача оптимального подбора оборудования
Всем привет, на вашем форуме первый раз, сильно не пинайте, пожалуйста:) Есть задача сделать подборщик оптимальной конфигурации...

Задача оптимального раскроя: распил досок
Всем привет! Никак не могу разобраться с задачей. Требуются комплекты досок, каждый из которых состоит из 2 досок длиной 1,5 м и 5...

30
 Аватар для LegionK
393 / 263 / 193
Регистрация: 02.05.2017
Сообщений: 1,003
18.07.2021, 11:52
А можно картинкой? Ничего не понятно.
0
681 / 555 / 74
Регистрация: 20.09.2014
Сообщений: 3,638
18.07.2021, 13:11  [ТС]
Рисунок
Задача оптимального раскроя


Ткань отматывается из рулона ширины W и кладется на стол длины H. Нож режет с запасом на длину d, в связи с чем образуются полоски шириной d на выброс. Если длина или ширина двух кусков ткани совпадает, то можно сделать рез без зазора (см. рисунок). После разреза всех кусков ткани делается крайний рез (см. рисунок), рулон снова разматывается и выполняется следующий раскрой.

Варианты оптимизационной задачи:
1. Критерий оптимизации - минимальная площадь потерь ткани / критерий оптимизации Б - минимизация площади + минимизация количества резов (минимизация взвешенной функции двух переменных).
2. Перед размоткой рулона делается крайний рез / Не делается крайний рез.
3. Прямоугольники можно поворачивать / прямоугольники нельзя поворачивать.
0
681 / 555 / 74
Регистрация: 20.09.2014
Сообщений: 3,638
18.07.2021, 13:17  [ТС]
Цитата Сообщение от Mikhaylo Посмотреть сообщение
2. Перед размоткой рулона делается крайний рез / Не делается крайний рез.
В принципе, эти два варианта легко реализуются одним алгоритмом. Если крайний рез не делается, то это эквивалентно столу бесконечной длины.
0
 Аватар для LegionK
393 / 263 / 193
Регистрация: 02.05.2017
Сообщений: 1,003
18.07.2021, 17:14
Если честно, то я не представляю как это решать.
0
фрилансер
 Аватар для Алексей1153
6334 / 5473 / 1108
Регистрация: 11.10.2019
Сообщений: 14,567
18.07.2021, 17:20
Mikhaylo, можно попробовать генетический алгоритм. Хотя, может есть и аналитические способы раскроя
0
 Аватар для vlisp
1050 / 971 / 153
Регистрация: 10.08.2015
Сообщений: 5,261
18.07.2021, 22:15
Цитата Сообщение от LegionK Посмотреть сообщение
Если честно, то я не представляю как это решать.
никак не решать. просто купить программу для раскроя
0
 Аватар для vantfiles
1018 / 1907 / 177
Регистрация: 07.05.2013
Сообщений: 3,931
Записей в блоге: 12
19.07.2021, 12:55
В реальном производстве, как я понимаю, есть понятие карты раскроя. Ее можно составить один раз в любой бесплатной программе - таких имеется предостаточно. Например, по такой карте можно заранее распилить фанеру для изготовления шкафов - причем может оказаться так, что для оптимального распила понадобится несколько карт и небольшой склад заготовок.

Вопрос - зачем нужна собственная программа? Насколько я понимаю, ткань режется не просто так на платочки - а для шитья из нее готового изделия. Зачем нужно в оперативном режиме отрисовывать карты раскроя?

PS: задача NP-полная, строгого быстрого решения у нее нет - поэтому люди до сих пор на ее оптимизации кандидатские и докторские защищают.
0
681 / 555 / 74
Регистрация: 20.09.2014
Сообщений: 3,638
19.07.2021, 16:10  [ТС]
Мне нужно написать программу для станка.
В принципе можно рассмотреть алгоритмы полного перебора.

Исчерпывающе про мою задачу написано в википедии:
https://ru.m.wikipedia.org/wik... 0%BE%D1%8F

Думаю, надо рассмотреть метод ветвей и границ.
0
 Аватар для vantfiles
1018 / 1907 / 177
Регистрация: 07.05.2013
Сообщений: 3,931
Записей в блоге: 12
19.07.2021, 16:40
Цитата Сообщение от Mikhaylo Посмотреть сообщение
Думаю, надо рассмотреть метод ветвей и границ.
Вот еще можно посмотреть, мне показалось интересным:

Задача упаковки прямоугольников: точный алгоритм на базе матричного представления
https://cyberleninka.ru/articl... stavleniya

Добавлено через 4 минуты
Цитата Сообщение от Mikhaylo Посмотреть сообщение
В принципе можно рассмотреть алгоритмы полного перебора.
10! = 3628800
11! = 39916800
12! = 479001600

Не думаю...

Добавлено через 11 минут
Да, вот еще... Пример надуман, но все же:

Code Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
+----------------------------+
|                     |      |
|                     |      |
|---------------------|      |
|     |               |      |
|     |   +-----+     |      |
|     |   |     |     |      |
|     |   |     |     |      |
|     |   +-----+     |      |
|     |               |      |
|     |----------------------|
|     |                      |
|     |                      |
+----------------------------+
У внутреннего квадратика очень много вариантов расположиться - а это уже не факториалы...
0
681 / 555 / 74
Регистрация: 20.09.2014
Сообщений: 3,638
19.07.2021, 19:47  [ТС]
vantfiles,
Надо перебирать только характерные точки. В самом начале только две характерные точки - верхний и левый углы ткани (на рисунке).
В вашем случае квадратик может размещен в одной из четырех точек. Можно выбирать всегда верхнюю левую точку, так как без разницы.

Добавлено через 6 минут
Если я сейчас не ошибаюсь, каждый прямоугольник удаляет одну или в лучшем случае две характерные точки (занимает их место) и добавляет три или в лучшем случае две новые точки. То есть число характерных точек растет линейно.
0
 Аватар для vantfiles
1018 / 1907 / 177
Регистрация: 07.05.2013
Сообщений: 3,931
Записей в блоге: 12
20.07.2021, 09:12
Цитата Сообщение от vantfiles Посмотреть сообщение
для оптимального распила понадобится несколько карт
Нет комментариев... я волнуюсь... Вы поняли, что я имел в виду? Иногда бывает, что лучше подождать - и сделать одну карту вместо двух:

Code Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
+---------------+
|               |
|    в дело     |
|               |
-----------------
|    в отход    |
|               |
+---------------+
 
или
 
+---------------+
|               |
|  все в дело   |
|               |
-----------------
|   |   |   |   |
|   |   |   |   |
+---------------+
0
681 / 555 / 74
Регистрация: 20.09.2014
Сообщений: 3,638
20.07.2021, 09:34  [ТС]
Цитата Сообщение от vantfiles Посмотреть сообщение
Нет комментариев... я волнуюсь... Вы поняли, что я имел в виду? Иногда бывает, что лучше подождать - и сделать одну карту вместо двух:
На производстве задания раскроя могут поступать в реальном времени, да. Это пускай эксплуатанты сами решают, подождать или нет.
На самом деле потери ткани - это важно, но я видел горы этой ткани, которую выбрасывают. Так что надо помимо экономии потерь ткани, надо производительность станка обеспечить. Кстати, вторая задача - задача оптимальной траектории ножа, я еще не формулировал эту задачу, но она существует...
0
 Аватар для vantfiles
1018 / 1907 / 177
Регистрация: 07.05.2013
Сообщений: 3,931
Записей в блоге: 12
20.07.2021, 23:00
Цитата Сообщение от Mikhaylo Посмотреть сообщение
я еще не формулировал эту задачу, но она существует...
Вы и дальше будете кошке хвост по частям резать?
0
681 / 555 / 74
Регистрация: 20.09.2014
Сообщений: 3,638
21.07.2021, 04:54  [ТС]
vantfiles, это уже другая задача.
ЗАДАЧА #2. Пусть первый оптимизационный алгоритм выдал оптимальную раскладку (layout), которую мы видим на рисунке. Следует разработать алгоритм, который выдаст оптимальный маршрут ножа ЧПУ-станка. Есть особенности:
1. Нож не может резать в направлении слева направо (ось X), так как ткань с левой стороны не удерживается.
2. Справа ткань удерживается рулоном, поэтому, если выполнить некоторый рез по ширине рулона (ось Y), то впоследствии слева от этого реза резать ткань вдоль оси X уже не получится, ткань в этой части рулоном уже не будет удерживаться.
3. Резы по ширине рулона (ось Y) можно выполнять без ограничений.
Нужно минимизировать время. По оси X скорость перемещения равна Vx, по оси y - Vy.

Добавлено через 9 минут
Начальное положение ножа - в крайней левой точке стола (X=0) и в любом нужном положении по оси Y, т.е., пока ткань раскладывают на столе, нож уже будет готов.
Нож можно перемещать одновременно по обеим осям.
0
681 / 555 / 74
Регистрация: 20.09.2014
Сообщений: 3,638
14.08.2021, 16:13  [ТС]
Значит так. Я тут самостоятельно продвинулся. Изучил несколько монографий, статей и докторских диссертаций.
И эту статью на Хабре в первую очередь: https://habr.com/ru/post/136225/ (Про двумерную упаковку: offline алгоритмы)

В общем вывод такой: есть методы перебора, которые находят глобальный оптимум, но работают с экспоненциальной сложностью. Этот вариант отсеялся, так как такие алгоритмы работают порядка минут при количестве прямоугольников 15-20.

Есть еще алгоритмы на основе генетического алгоритма. Они ищут локальные оптимумы, и при этом тоже довольно тяжелые (порядка минут).

Остались эвристические алгоритмы (см. псевдокод в статье на Хабре, ссылка выше).

Я написал на Пайтоне.

Исходные условия:
Python Скопировано
1
2
3
4
5
6
7
8
9
10
# прямоугольники
R = [(1200, 500), (200, 1000), (400, 250), (1250, 600), (100, 100), (1000, 1000), (300, 200), (450, 250), (500, 500),
     (400, 250), (1000, 350), (1100, 600), (400, 900), (100, 100), (50, 150), (150, 100), (100, 100), (250, 1000),
    (50, 100), (50, 50), (50, 50), (50, 50), (70, 50), (100, 100)]
 
# прямоугольники (вариант 2)
R1 = [(1800, 800), (1750, 650), (1750, 650), (1800, 600), (1800, 600), (1000, 600), (1600, 950)]
 
W0 = 2000    # ширина полубесконечной полосы (упаковки)
H0 = 2500    # высота (длина) полосы
FFDH
Кликните здесь для просмотра всего текста
Python Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def FFDH(rectangles, W0):
    '''Стандартный алгоритм упаковки в полубесконечную полосу First Fit Decreasing High'''
    sorted_rectangles = sort_rectangles(rectangles)
    level_count = 1
    layout = [[((0.0, 0.0), sorted_rectangles[0])]]
    for rectangle in sorted_rectangles[1:]:
        current_x = 0.0
        packable = False
        for level in range(level_count):
            current_y = sum([lo[1][1] for lo in layout[level]])
            if current_y + rectangle[1] <= W0:
                best_level = level
                packable = True
                break
            current_x += layout[level][0][1][0]
        if not(packable):
            best_level = level_count
            level_count += 1
            layout.append([])
            current_y = 0.0
        layout[best_level].append(((current_x, current_y), rectangle))
    print(sorted_rectangles)
    print(round(calc_space_eff(layout, W0), 2))
    return layout


Python Скопировано
1
2
ffdh_layout = FFDH(R, W0)
draw_layout(ffdh_layout, H0, W0)
BFDH
Кликните здесь для просмотра всего текста
Python Скопировано
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
def BFDH(rectangles, W0):
    '''Стандартный алгоритм упаковки в полубесконечную полосу Best Fit Decreasing High'''
    sorted_rectangles = sort_rectangles(rectangles)
    level_count = 1
    layout = [[((0.0, 0.0), sorted_rectangles[0])]]
    for rectangle in sorted_rectangles[1:]:
        current_x = 0.0
        best_y = 0.0
        packable = False
        for level in range(level_count):
            current_y = sum([lo[1][1] for lo in layout[level]])
            if (current_y + rectangle[1] <= W0) and (current_y > best_y):
                best_x = current_x
                best_y = current_y
                best_level = level
                packable = True
            current_x += layout[level][0][1][0]
        if not(packable):
            best_level = level_count
            level_count += 1
            layout.append([])
            best_x = current_x
            best_y = 0.0
        layout[best_level].append(((best_x, best_y), rectangle))
    print(sorted_rectangles)
    print(round(calc_space_eff(layout, W0), 2))
    return layout


Python Скопировано
1
2
bfdh_layout = BFDH(R, W0)
draw_layout(bfdh_layout, H0, W0)
FCNR
Кликните здесь для просмотра всего текста
Python Скопировано
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
def FCNR(rectangles, W0):
    '''Cтандартный алгоритм упаковки в полубесконечную полосу Floor Ceiling No Rotating'''
    sorted_rectangles = sort_rectangles(rectangles)
    layout = [[((0.0, 0.0), sorted_rectangles[0], 'floor')]]
    level_count = len(layout)
    for rectangle in sorted_rectangles[1:]:
        current_x = 0.0
        best_y = 0.0
        packable = False
        for level in range(level_count):
            current_y = sum([lo[1][1] for lo in layout[level]])
            if (current_y + rectangle[1] <= W0) and (current_y > best_y):
                best_x = current_x
                best_y = current_y
                best_level = level
                packable = True
            current_x += layout[level][0][1][0]    
        if packable:
            layout[best_level].append(((best_x, best_y), rectangle, 'floor'))
        else:
            current_x = 0.0
            for level in range(level_count):
                current_y = sum([lo[1][1] for lo in layout[level]])
                current_y2 = 0.0
                for lo in layout[level][::-1]:
                    current_y -= lo[1][1]
                    if (lo[2] == 'ceil'):
                        current_y2 += lo[1][1]
                    if (current_y + current_y2 + rectangle[1] <= W0) and (lo[1][0] + rectangle[0] <= layout[level][0][1][0]) and (lo[2] == 'floor'):
                        best_x = current_x + layout[level][0][1][0] - rectangle[0]
                        best_y = W0 - current_y2 - rectangle[1]
                        packable = True
                        layout[level].append(((best_x, best_y), rectangle, 'ceil'))
                        break
                current_x += layout[level][0][1][0]
                if packable:
                    break
        if not(packable):
            best_level = level_count
            level_count += 1
            layout.append([])
            best_x = current_x
            best_y = 0.0
            layout[best_level].append(((best_x, best_y), rectangle, 'floor'))   
    print("Сортировка по высоте:\n", sorted_rectangles)
    print("\nКоэффициент использования (без учета узких полос):", round(calc_space_eff(layout, W0), 2))
    print("\nРаскладка:\n", layout)
    return layout


Python Скопировано
1
2
fcnr_layout = FCNR(R, W0)
draw_layout(fcnr_layout, H0, W0, order=True)
Python Скопировано
1
2
fcnr_layout3 = FCNR(R1, W0)
draw_layout(fcnr_layout3, H0, W0, order=True)
Вспомогательные функции:
1. Сортировка по высоте
Кликните здесь для просмотра всего текста
Python Скопировано
1
2
3
4
5
6
import numpy as np
def sort_rectangles(rectangles):
    '''Сортировка прямоугольников по высоте'''
    height_sorted_index = np.argsort([rectangle[0] for rectangle in rectangles])[::-1]
    sorted_rectangles = [rectangles[index] for index in height_sorted_index]
    return sorted_rectangles

2. Вычисление коэффициента эффективности использования ткани
Кликните здесь для просмотра всего текста
Python Скопировано
1
2
3
4
5
6
7
8
9
10
def calc_space_eff(layout, W0):
    '''Вычисление коэффициента эффективности использования площади упаковки'''
    rect_sq = 0.0
    Lmax = 0.0
    for level_lo in layout:
        for rect in level_lo:
            rect_sq += rect[1][0] * rect[1][1]
            if rect[0][0] + rect[1][0] > Lmax:
                Lmax = rect[0][0] + rect[1][0]
    return rect_sq / (W0 * Lmax)

3. Визуализация
Кликните здесь для просмотра всего текста
Python Скопировано
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
from tkinter import *
def draw_layout(layout, H0, W0, region=True, cutting=True, text=True, order=False):
    '''Отрисовка упаковки и раскладки'''
    window = Tk()
    w_width = window.winfo_screenwidth()-100
    w_height = window.winfo_screenheight()-100
    scale = 0.9*w_height/W0
    canvas = Canvas(window, width=w_width, height=w_height)
    canvas.pack()
    d = 20.0
    delta = 10.0
    canvas.create_rectangle(scale*d, scale*d, scale*(H0+d), scale*(W0+d))
    for level in layout[::-1]:
        floor_n = 0
        for rect in level:
            if len(rect) > 2:
                if rect[2] == 'floor':
                    floor_n += 1
            else:
                floor_n = len(level)
        for i, rect in enumerate(level):
            if region:
                canvas.create_rectangle(scale*(rect[0][0] + d),
                                        scale*(rect[0][1] + d),
                                        scale*(rect[0][0] + rect[1][0] + d),
                                        scale*(rect[0][1] + rect[1][1] + d),
                                        fill="light grey")
            if cutting:
                canvas.create_line(scale*(rect[0][0] + d),
                                   scale*(rect[0][1] + d - delta),
                                   scale*(rect[0][0] + d),
                                   scale*(rect[0][1] + rect[1][1] + d))
                canvas.create_line(scale*(rect[0][0] + d - delta),
                                   scale*(rect[0][1] + d),
                                   scale*(rect[0][0] + rect[1][0] + d),
                                   scale*(rect[0][1] + d))
                canvas.create_line(scale*(rect[0][0] + rect[1][0] + d - delta),
                                   scale*(rect[0][1] + d - delta),
                                   scale*(rect[0][0] + rect[1][0] + d - delta),
                                   scale*(rect[0][1] + rect[1][1] + d))
                canvas.create_line(scale*(rect[0][0] + d - delta),
                                   scale*(rect[0][1] + rect[1][1] + d - delta),
                                   scale*(rect[0][0] + rect[1][0] + d),
                                   scale*(rect[0][1] + rect[1][1] + d - delta))
            if text:
                canvas.create_text(scale*(rect[0][0] + d + 10.0),
                                   scale*(rect[0][1] + d + 5.0),
                                   text=str(i) + '; ' + str(rect),
                                   anchor='nw')
            if order:
                if rect[2] == 'floor':
                    canvas.create_text(scale*(rect[0][0] + 0.5*rect[1][0] + d),
                                        scale*(rect[0][1] + rect[1][1] + d),
                                        text=str(2*(floor_n - i) - 1),
                                        anchor='s',
                                        fill="red")
                    canvas.create_text(scale*(rect[0][0] + 0.5*rect[1][0] + d),
                                        scale*(rect[0][1] + d),
                                        text=str(2*(floor_n - i)),
                                        anchor='n',
                                        fill="red")
                    canvas.create_text(scale*(rect[0][0] + d),
                                        scale*(rect[0][1] + 0.5*rect[1][1] + d),
                                        text=str(2*floor_n + 1),
                                        anchor='w',
                                        fill="red")
                    canvas.create_text(scale*(rect[0][0] + rect[1][0] + d),
                                        scale*(rect[0][1] + 0.5*rect[1][1] + d),
                                        text=str(3*floor_n - i + 1),
                                        anchor='e',
                                        fill="red")
                else:
                    canvas.create_text(scale*(rect[0][0] + 0.5*rect[1][0] + d),
                                       scale*(rect[0][1] + rect[1][1] + d),
                                       text=str(2*(3*floor_n - i) + 3),
                                       anchor='s',
                                       fill="red")
                    canvas.create_text(scale*(rect[0][0] + 0.5*rect[1][0] + d),
                                       scale*(rect[0][1] + d),
                                       text=str(2*(3*floor_n - i) + 2),
                                       anchor='n',
                                       fill="red")
                    canvas.create_text(scale*(rect[0][0] + d),
                                       scale*(rect[0][1] + 0.5*rect[1][1] + d),
                                       text=str(2*len(level) + i + 2),
                                       anchor='w',
                                       fill="red")
                    canvas.create_text(scale*(rect[0][0] + rect[1][0] + d),
                                       scale*(rect[0][1] + 0.5*rect[1][1] + d),
                                       text=str(3*len(level) + 2),
                                       anchor='e',
                                       fill="red")
    window.mainloop()
    return
0
6173 / 939 / 310
Регистрация: 25.02.2011
Сообщений: 1,373
Записей в блоге: 1
11.01.2022, 09:26
Mikhaylo, Можете ответить, какая у Вас эффективность раскроя для первого набора данных (% заполнения или длина полосы)?
Реализовано вращение элементов?
Реализован гильотинный раскрой (от края до края)?

PS: Реализовывал схожую задачу, решение выкладывал на excelworld (прямую ссылку не даю, т.к. запрещено правилами текущего форума)
Можно найти по фразе: "Двумерный раскрой / Двумерная упаковка, 2DSP"

С текущим набором данных алгоритм справляется не очень хорошо (на мой взгляд), нужно менять подход к решению
Выкладываю то, что получилось раскроить своим алгоритмом.
Если убрать мелкие детали, то раскрой производится очень быстро, а уже мелкие детали раскраиваем из остатков
Вложения
Тип файла: xlsx 2DSP раскрой.xlsx (37.8 Кб, 34 просмотров)
0
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
11.01.2022, 10:38
Цитата Сообщение от Mikhaylo Посмотреть сообщение
написал на Пайтоне.
Не представляю как вообще может прийти в голову идея пилить перебор на интерпретируемом языке(питон). Перебирают на GPU.
0
6173 / 939 / 310
Регистрация: 25.02.2011
Сообщений: 1,373
Записей в блоге: 1
11.01.2022, 11:03
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Не представляю как вообще может прийти в голову идея пилить перебор на интерпретируемом языке(питон).
У ТС реализован "жадный алгоритм", он достаточно быстрый на любом языке, перебора там нет (если за основу взяты алгоритмы с habr)
0
681 / 555 / 74
Регистрация: 20.09.2014
Сообщений: 3,638
13.01.2022, 06:48  [ТС]
Цитата Сообщение от m-ch Посмотреть сообщение
Mikhaylo, Можете ответить, какая у Вас эффективность раскроя для первого набора данных (% заполнения или длина полосы)?
Реализовано вращение элементов?
Реализован гильотинный раскрой (от края до края)?
Проект близится к завершению. Реализован только модифицированный алгоритм FCNR, хотя еще планировал алгоритм блочной упаковки. Оперативной памяти не хватает (специфика железа).
1. Эффективность 75-95%, это сильно зависит от ширины ткани и конкретных изделий.
2. У нас для FCNR достаточно повернуть все изделия по длинной стороне вдоль полосы.
3. Гильотинный принцип реза не требуется, так как у нас ткань.

Представьте себе, режем шторы на окна. Практика показывает, что у нас изделия делятся условно на три группы размеров: большие, средние и маленькие. Изделия часто по несколько штук одинаковые, поэтому обычно укладка происходит достаточно ровно, но все же бывают случаи, когда жадность укладки мешает реализовать очевидную оптимальную укладку. В этом случае можно заморочаться - убрать часть изделий из укладки и тогда вроде получается. Но это потери времени, потеря производительности.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.01.2022, 06:48
Помогаю со студенческими работами здесь

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

Задача раскроя прямоугольников
Приветствую. Имеется задача упаковки прямоугольников на плоскости. На вход программе подается список прямоугольников, после чего они...

Задача выбора варианта раскроя
На заготовительный участок мебельной фабрики поступили листы фанеры размером 152х152 см. Необходимо разрезать их на заготовки по 105х31,...

Задача раскроя с учетом комплектации
Зравствуйте, Решаю задачу следующего содержания: Завод заключил договор на поставку комплектов стержней длиной 18, 23 и 32 см....

Задача раскроя, максимизировать количество целевых прямоугольников
Задача раскроя. Конкретнее: есть прямоугольник заданных размеров а так же размеры различных прямоугольников которые нужно вырезать....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Работа с объемным DOM в javascript
Htext 04.04.2025
Сегодня прочитал статью тут о расходах памяти в JS, ее утечках и т. п. И вот что вспомнил из своей недавней практики. Может, кому пригодится. Хотя, в той статье об этом тоже есть. Дело в том, что я. . .
Оптимизация производительности Node.js с помощью кластеризации
run.dev 04.04.2025
Масштабирование приложений для обработки тысяч и миллионов запросов — обыденная задача для многих команд. Node. js, благодаря своей асинхронной событийно-ориентированной архитектуре, стал популярной. . .
Управление зависимостями в Python с Poetry
py-thonny 04.04.2025
Стандартный инструмент для установки пакетов в Python - pip - прекрасно справляется с базовыми сценариями: установил пакет командой pip install и используешь его. Но что произойдёт, когда разные. . .
Мониторинг с Prometheus в PHP
Jason-Webb 04.04.2025
Prometheus выделяется среди других систем мониторинга своим подходом к сбору и хранению метрик. В отличие от New Relic, который использует агентный подход и отправляет данные во внешнее хранилище,. . .
Пакет Context в Golang: Управление потоками и ресурсами
golander 04.04.2025
Работа с горутинами в Go часто напоминает управление непослушными детьми - они разбегаются кто куда, делают что хотят и не всегда завершаются вовремя. К счастью, в Go 1. 7 появился пакет context,. . .
Контейнеризация React приложений с Docker
Reangularity 03.04.2025
Контейнеризация позволяет упаковать приложение со всеми его зависимостями в автономный контейнер, который можно запустить на любой платформе с установленным Docker. Это существенно упрощает процессы. . .
Свой попап в SwiftUI
mobDevWorks 03.04.2025
SwiftUI, как декларативный фреймворк от Apple, предоставляет множество инструментов для создания пользовательских интерфейсов. В нашем распоряжении есть такие API как alerts, popovers, action sheets. . .
Антипаттерны микросервисной архитектуры
ArchitectMsa 03.04.2025
Хорошо спроектированная микросервисная система может выдержать испытание временем, оставаясь гибкой, масштабируемой и устойчивой к большинству проблем. Такая архитектура обладает высоким уровнем. . .
std::mutex в C++: Советы и примеры использования
bytestream 03.04.2025
std::mutex - это механизм взаимного исключения, который гарантирует, что критический участок кода выполняется только одним потоком в каждый момент времени. Это простое, но могущественное средство. . .
Не удержался от оценки концепции двигателя Стирлинга.
Hrethgir 03.04.2025
Сколько не пытался - она выдавала правильные схемы, причём случайно рисовала горячие области в середине, холодные по краям, трубки с краёв в низ и магнит в соединяющей, но при этой выдавала описание. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
Выделить код Копировать код Сохранить код Нормальный размер Увеличенный размер