ประเมิน
ส่ง permutation ทุกตัวเข้า evaluator เดียวกัน ได้ fitness หนึ่งค่าหรือ Pareto selection score
ติดตามหนึ่ง generation ตั้งแต่ population ดิบ การเลือก elite การสร้างสถิติ relative order การสุ่มตำแหน่งทีละสมาชิก ไปจนถึงคำตอบรุ่นใหม่ พร้อม snapshot ตัวเลขที่ตรวจสอบย้อนกลับกับ Python implementation ได้
ส่ง permutation ทุกตัวเข้า evaluator เดียวกัน ได้ fitness หนึ่งค่าหรือ Pareto selection score
เรียงตามทิศทางของ objective แล้วเก็บ elite ตาม selection ratio
แปลง elite เป็น inverse positions แล้วคำนวณ exact-position และ signed-distance statistics
สุ่ม item และ locus ที่ยังว่าง โดยผสมหลักฐาน node กับ relative order
ประเมิน population ใหม่ เก็บ diagnostics และเรียน estimator รอบถัดไป
ตัวอย่าง minimization ขนาด n=6, population=5 และ selection ratio=40% จึงเลือก max(1, round(5×0.40)) = 2 ตัวแรกหลังเรียง fitness
[1, 4, 0, 3, 5, 2][1, 3, 5, 0, 4, 2][3, 1, 0, 5, 2, 4][1, 5, 3, 0, 2, 4][4, 0, 2, 1, 5, 3]order = argsort(fitness) # minimization
k = max(1, round(population × ratio/100))
selected = population[order[:k]] # P3, P1
argsort(fitness) น้อยไปมาก
argsort(fitness)[::-1] มากไปน้อย
permutation ตอบว่า “ตำแหน่ง p มี item ใด” แต่ estimator ต้องถามกลับว่า “item j อยู่ตำแหน่งใด” จึงสร้าง inverse array หนึ่งครั้ง แล้วอ่านทุกคู่ได้ O(1)
| Elite | Permutation | pos[0..5] |
|---|---|---|
| P3 | 1 5 3 0 2 4 | 3 0 4 2 5 1 |
| P1 | 1 3 5 0 4 2 | 3 0 5 1 4 2 |
positions[row, item] = locus
P3: pos(1)=0, pos(3)=2
P1: pos(1)=0, pos(3)=1
Δ(1,3) = pos(3)-pos(1)
P3 → +2
P1 → +1
นับว่า item j ปรากฏที่ locus p กี่ครั้ง เติม smoothing α ทุกช่อง แล้ว normalize แต่ละแถวให้รวมเป็น 1
N[j,p] = (count(j at p)+α)/(k+nα)
α=1, k=2
item 1 observed at p=0 twice
N[1] = [3,1,1,1,1,1] / 8ระยะมีเครื่องหมาย: บวกหมายถึง j อยู่หลัง i, ลบหมายถึง j อยู่ก่อน i จึงเก็บทั้งทิศและระยะในค่าเดียว
Δπ(i,j)=posπ(j)-posπ(i)
M[i,j]=mean Δ
L[i,j]=min Δ
U[i,j]=max Δ
S[i,j]=population SD of Δimplementation ใช้ population standard deviation (หารด้วย k) ไม่ใช่ sample SD (หารด้วย k−1) และกำหนด diagonal i=j เป็น count=0 เพราะระยะศูนย์ไม่ให้ข้อมูล
เลือก active roll จาก item ที่วางแล้ว ทุก reference i ทำนาย target_i = pos(i)+M[i,j] แล้วเฉลี่ย target ทั้งหมด ไม่สุ่ม Δ จากช่วง [L,U]
targets = [pos(i)+M[i,j]]
target = mean(targets)
scale = max(mean(S[i,j]),1)เลือก reference แบบ uniform หรือ confidence=1/SD แล้วสุ่ม integer Δ จาก Normal(M,S) ที่ตัดให้อยู่ใน [L,U] และห้ามศูนย์
i ~ reference policy
Δ ~ TruncNormal(M[i,j],S[i,j],L,U)
target = pos(i)+Δเก็บ H[i,j,d] จำนวน 2n−1 bins แล้วให้คะแนน free locus p จาก d=p−pos(i) จึงรักษา distribution หลายยอดได้ แต่ใช้หน่วยความจำ O(n³)
d = p-pos(i)
relative_score(p)=log H[i,j,d]
confidence(i)=1/entropy(H[i,j,:])| รุ่น | Reference | ข้อมูลระยะ | หน่วยความจำ | จุดแข็ง |
|---|---|---|---|---|
| ROSE | หลายตัวใน roll | M, S; average targets | O(n²) | ต้องการ consensus ที่นิ่ง |
| SR-ROSE | หนึ่งตัว | M, L, U, S; truncated draw | O(n²) | ต้องการ diversity โดยยัง compact |
| SH-ROSE | หนึ่งตัว | full empirical histogram | O(n³) | distribution มีหลายยอด |
สมมุติกำลังวาง item j=3, วาง reference i=1 ที่ locus 0 แล้ว และเหลือ free loci {1,2,4,5} จาก snapshot ก่อนหน้า SR-ROSE เรียน M=1.5, L=1, U=2, S=0.5
shuffle jobs ด้วย deterministic SplitMix64 seed เพื่อลดอคติจากเลข item
all, fixed หรือ random 1..max_roll
node(p)=log(max(N[3,p],ε))
ตัวอย่างสุ่มได้ Δ=2 จึง target=0+2=2
score=λ·node+(1−λ)·relative
คำนวณเฉพาะ free loci; ช่องที่ใช้แล้วไม่มีสิทธิ์ถูกสุ่ม
สะสม weight จนผ่าน random threshold แล้ว commit item ลง locus
เขียน result, pos(j), history และลบ locus ออกจาก free
free = [1, 2, 4, 5]| p | N[3,p] | node=log N | relative=−|p−2|/1 | mixed score | softmax P |
|---|---|---|---|---|---|
| 1 | .125 | −2.079 | −1 | −1.270 | 23.7% |
| 2 | .250 | −1.386 | 0 | −0.347 | 59.7% |
| 4 | .125 | −2.079 | −2 | −2.020 | 11.2% |
| 5 | .125 | −2.079 | −3 | −2.770 | 5.3% |
ตัวเลข probability ปัดเพื่อการสอน; implementation ลบ max(score) ก่อน exp เพื่อป้องกัน overflow และ fallback เป็น uniform เมื่อ weight ไม่ finite หรือผลรวมไม่เป็นบวก
ใช้ Box–Muller สร้าง normal draw ปัดเป็น integer และยอมรับเมื่ออยู่ใน [L,U] และไม่เป็นศูนย์ ทดลองสูงสุด 32 ครั้ง ถ้ายังไม่ได้จึงสุ่ม uniform จาก integer ที่ legal ในช่วง ไม่ใช่ขยายช่วงเอง
repeat at most 32 times:
z = BoxMuller(U₁,U₂)
Δ = round(M + S·z)
accept if L ≤ Δ ≤ U and Δ ≠ 0
fallback: uniform({L..U} \ {0})ตำแหน่งที่คงไว้กำหนดทั้ง item ที่ถูก reserve และ reference context ส่วนช่องที่เจาะเท่านั้นที่ sampler ของ ROSE เติมกลับ
child เทียบกับ parent ของตนเอง ถ้าไม่ดีกว่า จะคืน parent ก่อน fit generation ถัดไป จึงเป็น local elitism ที่ชัดเจน
survivor = child if f(child) < f(parent) # minimization
parent otherwise
# strict improvement: equal fitness does not replace the parent
สร้าง random permutations ด้วย seed เดียวกันแล้วได้ reproducible initial population
สถิติสร้างจาก elite ของ G0 เท่านั้น ไม่ใช่ population ทั้งหมด
สร้าง offspring ทั้งรุ่นจาก estimator ชุดเดียว ทำให้ลำดับ candidate ไม่แอบเปลี่ยน model
หลัง evaluate และ selection จึงแทน estimator พร้อมกันสำหรับ G2
| Parameter | ทำหน้าที่ | ผลเมื่อเพิ่ม |
|---|---|---|
selection_ratio | สัดส่วน survivor ที่ใช้ fit | model นุ่มและหลากหลายขึ้น แต่อาจเรียนช้าลง |
smoothing α | pseudocount ของ N และ H | ลด zero probability แต่เพิ่ม exploration |
node_weight λ | น้ำหนัก exact-position เทียบ relative | พึ่ง locus frequency มากขึ้น |
temperature T | หาร score ก่อน softmax | distribution แบนขึ้นและสุ่มมากขึ้น |
roll_mode / roll size | จำนวน reference ล่าสุดที่พิจารณา | บริบทกว้างขึ้น แต่ consensus อาจเฉลี่ยสัญญาณขัดกัน |
template_sample_ratio | เปอร์เซ็นต์ locus ที่เจาะและสร้างใหม่ | ก้าวไกลจาก parent มากขึ้น |
เก็บ N, M, L, U, S และ count เป็น n×n ไม่มี tensor ต่อสมาชิก elite
เพิ่ม H ขนาด n×n×(2n−1) ทั้ง counts และ probabilities
ทำ n commits และให้คะแนน free loci ที่ลดลงทีละหนึ่ง
| ชื่อเผยแพร่ | Python class | หน้าที่หลัก | Source |
|---|---|---|---|
| ROSE / ROSE-WT | ROSETemplateROSE | multi-reference mean + optional punched template | models/rose.py |
| SR-ROSE / SR-ROSE-WT | ROSESingleRefTemplateROSESingleRef | single-reference compact range sampling | models/rose.py |
| SH-ROSE / SH-ROSE-WT | ROSESingleRefHistogramTemplateROSESingleRefHistogram | single-reference empirical histogram | models/rose_histogram.py |
| ตัวประมาณแบบเร็ว | fit_rose_estimators_numba | สร้าง N, M, L, U, S, count จาก elite | models/rose_numba.py |
M[j,i] = −M[i,j]L[j,i] = −U[i,j]