오더번호 규격 오더길이 만들개수 작업자
A 2 100 10
B 1 30 1
C 1 40 4
D 3 80 6
E 1 50 7
F 3 100 15
위의 자료를 가지고 작업자(홍길동,강감찬....)를 배정 할려고 합니다.
배정하는 원칙은
첫번째, 작업자별로 오더의 길이의 합이 비슷하도록 하여 나누어야 하며,
두번째, 작업난이도를 분류하여 작업자별로 비슷하게 배분되어야 합니다.
해당 오더의 작업난이도는
1. 규격(1~3 / 클수록 작업이 어려움)
2. 오더길이/만들개수 = 제품의길이 (제품의 길이가 짧을수록 작업이 어려움)
위 두가지를 고려합니다.
규격에 따른 작업 난이도는 1~3까지 정해져 있고, 제품의 길이는 오더길이와 만들개수로 정해집니다.
설명이 제대로 전달되었는지 모르겠네요..
물론 최종적 디테일한 부분은 응용프로그램으로 구현이 되겠지만
최적화된 기본 쿼리가 언뜻 생각이 나지 않네요
고수분들의 조언을 구해 봅니다.
더운 여름, 건강하게 보내시길...
Comment 2
-
이재학_302349
2016.07.20 15:58
-
민경진영아빠
2016.07.21 15:48
정말 감사합니다.^^
유사도 개념을 이용하여 시뮬레이션하면 최적화 할 수 있습니다.
유클리디안 거리를 이용하면 되구요.
질문의 예제로 3명에게 작업을 할당한다면 다음과 같이 최적화할 수 있겠네요.
--데이터 만들기
;with temp(오더번호, 규격, 오더길이, 만들개수)
as
(
select 'A', 2, 100, 10 union all
select 'B', 1, 30 , 1 union all
select 'C', 1, 40 , 4 union all
select 'D', 3, 80 , 6 union all
select 'E', 1, 50 , 7 union all
select 'F', 3, 100, 15
)
select * into #temp
from temp
select N'홍길동' name into #worker union all
select N'강감찬' union all
select N'이순신'
--simulation
set nocount on
if object_id('tempdb.dbo.#result') is not null
drop table #result
create table #result(
오더번호 nvarchar(200)
, 규격 int
, 오더길이 int
, 만들개수 int
, 작업자 nvarchar(200)
)
declare
@i int
, @dist float
, @min_dist float
set @i = 1
while(@i <= 100)
begin
if object_id('tempdb.dbo.#rand') is not null
drop table #rand
select
a.오더번호
, a.규격
, a.오더길이
, a.만들개수
, b.작업자
, b.num
into #rand
from (select *, row_number() over(order by newid()) - 1 num from #temp) a
inner join (
select
name 작업자
, row_number() over(order by newid()) - 1 num
, count(*) over() cnt
from #worker
) b
on a.num % b.cnt = b.num
declare
@v1 float
, @v2 float
, @v3 float
select
@v1 = sum(규격)
, @v2 = sum(오더길이)
, @v3 = sum(만들개수)
from #rand
where num = 0
select @dist = sqrt(sum(n))
from (
select
power(@v1 - sum(규격), 2) + power(@v2 - sum(오더길이), 2) + power(@v3 - sum(만들개수), 2) n
from #rand
where num <> 0
group by
num
) t
if @i = 1
begin
insert #result
select
오더번호
, 규격
, 오더길이
, 만들개수
, 작업자
from #rand
set @min_dist = @dist
end else
begin
if @min_dist > @dist
begin
truncate table #result
insert #result
select
오더번호
, 규격
, 오더길이
, 만들개수
, 작업자
from #rand
set @min_dist = @dist
end
end
--print @i
set @i = @i + 1
end
print @min_dist
select
오더번호
, 규격
, 오더길이 * 1.0 / 만들개수 [오더길이/만들개수]
, 작업자
from #result
order by 작업자
결과
오더번호 규격 오더길이/만들개수 작업자
E 1 7.142857142857 강감찬
D 3 13.333333333333 강감찬
A 2 10.000000000000 이순신
C 1 10.000000000000 이순신
B 1 30.000000000000 홍길동
F 3 6.666666666666 홍길동