ฉันวิ่งข้ามคำถามนี้ขณะค้นคว้าปัญหาที่คล้ายกัน: การเติมของเหลวที่เหมาะสมเพื่อลดการแบ่งชั้น ดูเหมือนว่าโซลูชันของฉันจะสามารถใช้กับสถานการณ์ของคุณได้เช่นกัน
หากคุณต้องการผสมของเหลว A, B และ C ในสัดส่วน 30,20,10 (นั่นคือ 30 หน่วยของ A, 20 หน่วยของ B และ 10 หน่วยของ C) คุณจะจบลงด้วยการแบ่งชั้นถ้าคุณเพิ่มทั้งหมด A จากนั้น B ทั้งหมดและ C ทั้งหมดคุณควรผสมหน่วยที่เล็กลง ตัวอย่างเช่นทำการเพิ่มหน่วยเดียวในลำดับ [A, B, A, C, B, A] ที่จะป้องกันการแบ่งชั้นโดยสิ้นเชิง
วิธีที่ฉันพบว่าทำคือการถือเป็นการผสานโดยใช้ลำดับความสำคัญ ถ้าฉันสร้างโครงสร้างเพื่ออธิบายเพิ่มเติม:
MergeItem
Item, Count, Frequency, Priority
ความถี่ถูกแสดงเป็น "หนึ่งทุก N" ดังนั้น A ซึ่งถูกเพิ่มสามในหกครั้งมีความถี่ 2 (6/3)
และเริ่มต้นฮีปที่ประกอบด้วย:
(A, 3, 2, 2)
(B, 2, 3, 3)
(C, 1, 6, 6)
ตอนนี้ฉันลบรายการแรกออกจากฮีปและส่งออก จากนั้นลดจำนวนลง 1 และเพิ่มลำดับความสำคัญตามความถี่และเพิ่มกลับไปที่ฮีป ผลลัพธ์ที่ได้คือ:
(B, 2, 3, 0)
(A, 2, 2, 4)
(C, 1, 6, 6)
ถัดไปลบ B ออกจากฮีปเอาท์พุทและอัปเดตจากนั้นเพิ่มกลับไปที่ฮีป:
(A, 2, 2, 4)
(C, 1, 6, 6)
(B, 1, 3, 6)
ถ้าฉันทำแบบนั้นต่อฉันจะได้ส่วนผสมที่ต้องการ ฉันใช้เครื่องมือเปรียบเทียบที่กำหนดเองเพื่อให้แน่ใจว่าเมื่อมีการใส่รายการลำดับความสำคัญเท่ากันในฮีปรายการที่มีค่าความถี่สูงสุด (เช่นความถี่ที่น้อยที่สุด) จะได้รับคำสั่งก่อน
ฉันเขียนคำอธิบายปัญหาและวิธีแก้ไขปัญหาในบล็อกของฉันให้ครบถ้วนยิ่งขึ้นและแสดงรหัส C # ที่ใช้งานได้ซึ่งแสดงให้เห็น ดูรายการสม่ำเสมอกระจายในรายการ
อัปเดตหลังจากความคิดเห็น
ฉันคิดว่าปัญหาของฉันคล้ายกับปัญหาของ OP และดังนั้นวิธีแก้ไขปัญหาของฉันอาจเป็นประโยชน์ ฉันขอโทษที่ไม่กำหนดกรอบคำตอบของฉันเพิ่มเติมในแง่ของคำถามของ OP
การคัดค้านครั้งแรกที่โซลูชันของฉันใช้ A, B และ C มากกว่า 0, 1 และ 2 นั้นสามารถแก้ไขได้ง่าย มันเป็นเพียงเรื่องของการตั้งชื่อ ฉันคิดว่าง่ายกว่าและสับสนน้อยกว่าเมื่อคิดและพูดว่า "two A's" มากกว่า "two 1's" แต่สำหรับวัตถุประสงค์ของการสนทนานี้ฉันได้แก้ไขผลลัพธ์ของฉันด้านล่างเพื่อใช้ระบบการตั้งชื่อของ OP
แน่นอนปัญหาของฉันเกี่ยวกับแนวคิดของระยะทาง หากคุณต้องการ "กระจายสิ่งต่าง ๆ อย่างสม่ำเสมอ" ระยะทางก็จะบอกเป็นนัย แต่อีกครั้งมันเป็นความล้มเหลวของฉันที่ไม่เพียงพอแสดงว่าปัญหาของฉันคล้ายกับปัญหาของ OP
ฉันทดสอบสองสามตัวอย่างจากตัวอย่างที่ OP ให้ไว้ นั่นคือ:
[1,1,2,2,3,3] // which I converted to [0,0,1,1,2,2]
[0,0,0,0,1,1,1,2,2,3]
ในระบบการตั้งชื่อของฉันสิ่งเหล่านี้แสดงเป็น [2,2,2] และ [4,3,2,1] ตามลำดับ นั่นคือในตัวอย่างสุดท้าย "4 รายการประเภท 0, 3 รายการประเภท 1, 2 รายการประเภท 2 และ 1 รายการประเภท 3"
ฉันรันโปรแกรมทดสอบของฉัน (ตามที่อธิบายไว้ด้านล่าง) และโพสต์ผลลัพธ์ของฉัน ไม่มีข้อมูลจาก OP ฉันไม่สามารถพูดได้ว่าผลลัพธ์ของฉันคล้ายกับแย่กว่าหรือดีกว่าเขา ฉันไม่สามารถเปรียบเทียบผลลัพธ์ของฉันกับผลลัพธ์ของคนอื่นเพราะไม่มีใครโพสต์เลย
ผมสามารถพูดได้อย่างไรว่าอัลกอริทึมให้เป็นทางออกที่ดีของฉันมีปัญหาในการขจัดชนชั้นเมื่อผสมของเหลว และดูเหมือนว่าจะให้ทางออกที่สมเหตุสมผลในการแก้ไขปัญหาของ OP
สำหรับผลลัพธ์ที่แสดงด้านล่างฉันใช้อัลกอริทึมที่ฉันให้รายละเอียดในรายการบล็อกของฉันโดยมีการตั้งค่าลำดับความสำคัญเริ่มต้นเป็นFrequency/2
และตัวเปรียบเทียบฮีปที่ถูกปรับเปลี่ยนเพื่อให้เหมาะกับรายการที่ใช้บ่อยกว่า รหัสที่แก้ไขจะแสดงที่นี่พร้อมกับบรรทัดที่แก้ไขแสดงความคิดเห็น
private class HeapItem : IComparable<HeapItem>
{
public int ItemIndex { get; private set; }
public int Count { get; set; }
public double Frequency { get; private set; }
public double Priority { get; set; }
public HeapItem(int itemIndex, int count, int totalItems)
{
ItemIndex = itemIndex;
Count = count;
Frequency = (double)totalItems / Count;
// ** Modified the initial priority setting.
Priority = Frequency/2;
}
public int CompareTo(HeapItem other)
{
if (other == null) return 1;
var rslt = Priority.CompareTo(other.Priority);
if (rslt == 0)
{
// ** Modified to favor the more frequent item.
rslt = Frequency.CompareTo(other.Frequency);
}
return rslt;
}
}
ใช้โปรแกรมทดสอบของฉันกับตัวอย่างแรกของ OP ฉันจะได้รับ:
Counts: 2,2,2
Sequence: 1,0,2,1,0,2
Distances for item type 0: 3,3
Stddev = 0
Distances for item type 1: 3,3
Stddev = 0
Distances for item type 2: 3,3
Stddev = 0
อัลกอริทึมของฉันทำงานได้กับปัญหาเล็ก ๆ น้อย ๆ ของการนับทั้งหมดที่เท่ากัน
สำหรับปัญหาที่สองที่ OP โพสต์ฉันได้รับ:
Counts: 4,3,2,1
Sequence: 0,1,2,0,1,3,0,2,1,0
Distances for item type 0: 3,3,3,1
Stddev = 0.866025403784439
Distances for item type 1: 3,4,3
Stddev = 0.471404520791032
Distances for item type 2: 5,5
Stddev = 0
Distances for item type 3: 10
Stddev = 0
Standard dev: 0.866025403784439,0.471404520791032,0,0
ฉันไม่เห็นวิธีที่ชัดเจนในการปรับปรุง อาจถูกจัดเรียงใหม่เพื่อให้ระยะทางสำหรับรายการ 0 [2,3,2,3] หรือการจัดเรียงอื่นของ 2 และ 3 แต่จะเปลี่ยนความเบี่ยงเบนสำหรับรายการ 1 และ / หรือ 2 ฉันไม่รู้จริง ๆ ว่าอะไร "เหมาะสม" อยู่ในสถานการณ์นี้ มันจะดีกว่าหรือไม่ที่จะมีการเบี่ยงเบนมากขึ้นในรายการที่บ่อยขึ้นหรือในรายการที่น้อยกว่า?
ไม่มีปัญหาอื่น ๆ จาก OP ฉันใช้คำอธิบายของเขาเพื่อสร้างบางส่วนของตัวเอง เขาพูดในโพสต์ของเขา:
รายการทั่วไปมี ~ 50 รายการที่มีค่าแตกต่างกัน ~ 15 ในปริมาณที่แตกต่างกัน
ดังนั้นการทดสอบทั้งสองของฉันคือ:
[8,7,6,5,5,4,3,3,2,2,2,1,1,1,1] // 51 items, 15 types
[12,6,5,4,4,3,3,3,2,2,2,1,1] // 48 items, 13 types
และผลลัพธ์ของฉัน:
Counts: 8,7,6,5,5,4,3,3,2,2,2,1,1,1,1
Sequence: 0,1,2,3,4,5,7,6,0,1,2,8,9,10,4,3,0,1,5,2,0,1,3,4,6,7,14,11,13,12,0,2,5,1,0,3,4,2,8,10,9,1,0,7,6,5,3,4,2,1,0
Distances for item type 0: 8,8,4,10,4,8,8,1
Stddev = 2.82566363886433
Distances for item type 1: 8,8,4,12,8,8,3
Stddev = 2.76272565797339
Distances for item type 2: 8,9,12,6,11,5
Stddev = 2.5
Distances for item type 3: 12,7,13,11,8
Stddev = 2.31516738055804
Distances for item type 4: 10,9,13,11,8
Stddev = 1.72046505340853
Distances for item type 5: 13,14,13,11
Stddev = 1.08972473588517
Distances for item type 6: 17,20,14
Stddev = 2.44948974278318
Distances for item type 7: 19,18,14
Stddev = 2.16024689946929
Distances for item type 8: 27,24
Stddev = 1.5
Distances for item type 9: 28,23
Stddev = 2.5
Distances for item type 10: 26,25
Stddev = 0.5
Distances for item type 11: 51
Stddev = 0
Distances for item type 12: 51
Stddev = 0
Distances for item type 13: 51
Stddev = 0
Distances for item type 14: 51
Stddev = 0
และสำหรับตัวอย่างที่สอง:
Counts: 12,6,5,4,4,3,3,3,2,2,2,1,1
Sequence: 0,1,2,0,3,4,7,5,6,0,1,8,9,10,0,2,0,3,4,1,0,2,6,7,5,12,11,0,1,0,3,4,2,0,1,10,8,9,0,7,5,6,0,
4,3,2,1,0
Distances for item type 0: 3,6,5,2,4,7,2,4,5,4,5,1
Stddev = 1.68325082306035
Distances for item type 1: 9,9,9,6,12,3
Stddev = 2.82842712474619
Distances for item type 2: 13,6,11,13,5
Stddev = 3.44093010681705
Distances for item type 3: 13,13,14,8
Stddev = 2.34520787991171
Distances for item type 4: 13,13,12,10
Stddev = 1.22474487139159
Distances for item type 5: 17,16,15
Stddev = 0.816496580927726
Distances for item type 6: 14,19,15
Stddev = 2.16024689946929
Distances for item type 7: 17,16,15
Stddev = 0.816496580927726
Distances for item type 8: 25,23
Stddev = 1
Distances for item type 9: 25,23
Stddev = 1
Distances for item type 10: 22,26
Stddev = 2
Distances for item type 11: 48
Stddev = 0
Distances for item type 12: 48
Stddev = 0