আমার প্রথম চিন্তা ছিল
select
<best solution>
from
<all possible combinations>
"সেরা সমাধান" অংশটি প্রশ্নের মধ্যে সংজ্ঞায়িত করা হয় - সর্বাধিক বোঝা এবং সর্বনিম্ন বোঝা ট্রাকগুলির মধ্যে ক্ষুদ্রতম পার্থক্য। অন্য বিট - সমস্ত সংমিশ্রণ - আমাকে চিন্তার জন্য বিরতি দিয়েছে।
এমন একটি পরিস্থিতি বিবেচনা করুন যেখানে আমাদের কাছে তিনটি অর্ডার এ, বি এবং সি এবং তিনটি ট্রাক রয়েছে। সম্ভাবনা আছে
Truck 1 Truck 2 Truck 3
------- ------- -------
A B C
A C B
B A C
B C A
C A B
C B A
AB C -
AB - C
C AB -
- AB C
C - AB
- C AB
AC B -
AC - B
B AC -
- AC B
B - AC
- B AC
BC A -
BC - A
A BC -
- BC A
A - BC
- A BC
ABC - -
- ABC -
- - ABC
Table A: all permutations.
এর মধ্যে অনেকগুলি প্রতিসাম্যযুক্ত। উদাহরণস্বরূপ, প্রথম ছয়টি সারি পৃথকভাবে প্রতিটি অর্ডারে রাখা ট্রাকের মধ্যে পৃথক। যেহেতু ট্রাকগুলি ছত্রাকযোগ্য তাই এই ব্যবস্থাগুলি একই ফলাফল তৈরি করবে। আমি আপাতত এটিকে উপেক্ষা করব।
অনুমতি এবং সংমিশ্রণ উত্পাদন করার জন্য পরিচিত কোয়েরি রয়েছে। যাইহোক, এগুলি একটি বালতিতে ব্যবস্থা তৈরি করবে। এই সমস্যার জন্য আমার একাধিক বালতি জুড়ে ব্যবস্থা দরকার।
স্ট্যান্ডার্ড "সমস্ত সংমিশ্রণ" ক্যোয়ারী থেকে আউটপুটটি দেখছেন
;with Numbers as
(
select n = 1
union
select 2
union
select 3
)
select
a.n,
b.n,
c.n
from Numbers as a
cross join Numbers as b
cross join Numbers as c
order by 1, 2, 3;
n n n
--- --- ---
1 1 1
1 1 2
1 1 3
1 2 1
<snip>
3 2 3
3 3 1
3 3 2
3 3 3
Table B: cross join of three values.
আমি লক্ষনীয় ফলাফল সারণি উ হিসাবে একই প্যাটার্ন গঠিত প্রতিটি বিবেচনা congnitive লিপ করা হলে কলাম অর্ডার হতে 1 , মান বলতে যা ট্রাক রাখা করবে অর্ডার, এবং একটি সারি ট্রাক মধ্যে অর্ডারের ব্যবস্থা করতে হবে। কোয়েরিটি তখন হয়ে যায়
select
Arrangement = ROW_NUMBER() over(order by (select null)),
First_order_goes_in = a.TruckNumber,
Second_order_goes_in = b.TruckNumber,
Third_order_goes_in = c.TruckNumber
from Trucks a -- aka Numbers in Table B
cross join Trucks b
cross join Trucks c
Arrangement First_order_goes_in Second_order_goes_in Third_order_goes_in
----------- ------------------- -------------------- -------------------
1 1 1 1
2 1 1 2
3 1 1 3
4 1 2 1
<snip>
Query C: Orders in trucks.
উদাহরণস্বরূপ ডেটাতে চৌদ্দটি অর্ডার কভার করার জন্য এটি প্রসারিত করা এবং আমরা নামগুলি সহজ করে যাচ্ছি:
;with Trucks as
(
select *
from (values (1), (2), (3)) as T(TruckNumber)
)
select
arrangement = ROW_NUMBER() over(order by (select null)),
First = a.TruckNumber,
Second = b.TruckNumber,
Third = c.TruckNumber,
Fourth = d.TruckNumber,
Fifth = e.TruckNumber,
Sixth = f.TruckNumber,
Seventh = g.TruckNumber,
Eigth = h.TruckNumber,
Ninth = i.TruckNumber,
Tenth = j.TruckNumber,
Eleventh = k.TruckNumber,
Twelth = l.TruckNumber,
Thirteenth = m.TruckNumber,
Fourteenth = n.TruckNumber
into #Arrangements
from Trucks a
cross join Trucks b
cross join Trucks c
cross join Trucks d
cross join Trucks e
cross join Trucks f
cross join Trucks g
cross join Trucks h
cross join Trucks i
cross join Trucks j
cross join Trucks k
cross join Trucks l
cross join Trucks m
cross join Trucks n;
Query D: Orders spread over trucks.
আমি সুবিধার জন্য অস্থায়ী সারণিতে মধ্যবর্তী ফলাফল রাখা পছন্দ করি।
যদি ডেটা প্রথমে UNPIVOTED হয় তবে পরবর্তী পদক্ষেপগুলি আরও সহজ হবে।
select
Arrangement,
TruckNumber,
ItemNumber = case NewColumn
when 'First' then 1
when 'Second' then 2
when 'Third' then 3
when 'Fourth' then 4
when 'Fifth' then 5
when 'Sixth' then 6
when 'Seventh' then 7
when 'Eigth' then 8
when 'Ninth' then 9
when 'Tenth' then 10
when 'Eleventh' then 11
when 'Twelth' then 12
when 'Thirteenth' then 13
when 'Fourteenth' then 14
else -1
end
into #FilledTrucks
from #Arrangements
unpivot
(
TruckNumber
for NewColumn IN
(
First,
Second,
Third,
Fourth,
Fifth,
Sixth,
Seventh,
Eigth,
Ninth,
Tenth,
Eleventh,
Twelth,
Thirteenth,
Fourteenth
)
) as q;
Query E: Filled trucks, unpivoted.
অর্ডার সারণীতে যোগদানের মাধ্যমে ওজন প্রবর্তন করা যেতে পারে।
select
ft.arrangement,
ft.TruckNumber,
TruckWeight = sum(i.Size)
into #TruckWeights
from #FilledTrucks as ft
inner join #Order as i
on i.OrderId = ft.ItemNumber
group by
ft.arrangement,
ft.TruckNumber;
Query F: truck weights
সর্বাধিক-বোঝা এবং সর্বনিম্ন-বোঝা ট্রাকের মধ্যে সবচেয়ে কম পার্থক্য রয়েছে এমন ব্যবস্থা (গুলি) সন্ধানের মাধ্যমে প্রশ্নের উত্তর এখন দেওয়া যেতে পারে
select
Arrangement,
LightestTruck = MIN(TruckWeight),
HeaviestTruck = MAX(TruckWeight),
Delta = MAX(TruckWeight) - MIN(TruckWeight)
from #TruckWeights
group by
arrangement
order by
4 ASC;
Query G: most balanced arrangements
আলোচনা
এটি দিয়ে একটি দুর্দান্ত অনেক সমস্যা রয়েছে। প্রথমত এটি একটি নিষ্ঠুর শক্তি অ্যালগরিদম। ওয়ার্কিং টেবিলগুলিতে সারিগুলির সংখ্যা ট্রাক এবং অর্ডার সংখ্যায় তাত্পর্যপূর্ণ। # অ্যারেঞ্জমেন্টে সারি সংখ্যা (ট্রাকের সংখ্যা) trucks (অর্ডার সংখ্যা)। এটি ভাল স্কেল হবে না।
দ্বিতীয়টি হ'ল এসকিউএল কোয়েরিগুলির মধ্যে অর্ডার এম্বেড থাকা সংখ্যা রয়েছে। এর চারপাশের একমাত্র উপায় হ'ল ডায়নামিক এসকিউএল ব্যবহার করা, যার নিজস্ব সমস্যা রয়েছে। অর্ডারের সংখ্যা যদি হাজারে হয় তবে এমন সময় আসতে পারে যখন উত্পন্ন এসকিউএল খুব দীর্ঘ হয়ে যায়।
তৃতীয়টি হচ্ছে ব্যবস্থাগুলিতে অপ্রয়োজনীয়। এটি মধ্যবর্তী টেবিলগুলি প্রবাহিত করে রানটাইমকে ব্যাপকভাবে বৃদ্ধি করে।
চতুর্থত, # অ্যারেঞ্জমেন্টের অনেকগুলি সারি এক বা একাধিক ট্রাক খালি রেখে দেয়। এটি সম্ভবত সর্বোত্তম কনফিগারেশন হতে পারে না। এই সারিগুলি তৈরি করার পরে ফিল্টার করা সহজ হবে। কোডটি সহজ এবং ফোকাস রাখতে আমি তা না করার সিদ্ধান্ত নিয়েছি।
উপরের দিকে এটি নেতিবাচক ওজনগুলি পরিচালনা করে, আপনার উদ্যোগটি কি কখনও ভরা হিলিয়াম বালুনগুলি শিপিং শুরু করা উচিত!
থটস
যদি ট্রাক ও অর্ডারগুলির তালিকা থেকে সরাসরি # ফিল্ডট্রাকসকে জনবহুল করার কোনও উপায় থাকে তবে আমি মনে করি যে এই উদ্বেগগুলির মধ্যে সবচেয়ে খারাপটি পরিচালনাযোগ্য হবে। দুঃখের সাথে আমার অব্যবস্থাপনা সেই বাধাটিতে হোঁচট খেয়েছে। আমার আশা যে ভবিষ্যতের কিছু অবদানকারী আমাকে সরবরাহ করতে সক্ষম হতে পারে।
1 আপনি বলছেন যে কোনও অর্ডারের জন্য সমস্ত আইটেম একই ট্রাকে থাকতে হবে। এর অর্থ অ্যাসাইনমেন্টের পরমাণু হ'ল অর্ডার, অর্ডারডেটেল নয়। আমি আপনার পরীক্ষার ডেটা থেকে এইগুলি উত্পন্ন করেছি:
select
OrderId,
Size = sum(OrderDetailSize)
into #Order
from #OrderDetail
group by OrderId;
যদিও এতে আমরা 'অর্ডার' বা 'অর্ডারডেটেল' প্রশ্নে আইটেমগুলি লেবেল দিই না কেন, কোনও পার্থক্য নেই the