ขอความช่วยเหลือ เขียนโปรแกรมจัดตารางเบรค

  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.
  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.

ตอนนี้ผมกำลังเขียน macro ใน Excel เป็นโปรแกรมจัดตารางเบรคอัตโนมัต โดยคนใช้เพียงแค่ระบุจำนวนคนที่เข้าทำงานแต่ละกะ
แล้วโปรแกรมจะจัดออกมาเป็นช่วงเวลาว่ารอบนี้เบรคกี่โมงบ้าง รายละเอียดย่อยๆก็คือ
-กะเริ่มต้นคือ 8:30 ต่อไปทุกๆครึ่งชม.จนถึง 15:30 โดยจำนวนคนในกะแต่ละวันอาจจะไม่เท่ากัน
-ทุกคนทำงาน 8 ชั่วโมงครึ่ง(รวมเวลาเบรค) ก็คือ กะ 8:30 เลิก 17:00 และกะสุดท้าย 15:30 เลิก 24:00
-แต่ละคนจะมีเบรค 3 ครั้ง เบรคแรก 15 นาที เบรคที่2 1 ชม. เบรคสุดท้าย 15 นาที

เงื่อนไขในการจัดตารางเบรคมี 2 อย่าง
- การจัดต้องคำนึงถึงจำนวนคนที่ทำในช่วงเวลานั้นๆด้วย โดยจะดูจากจำนวนคนที่ทำงานทั้งหมด - จำนวนคนเบรคในเวลานั้น
และจำนวนคนทำนั้นต้องเพิ่มขึ้นเรื่อยๆตั้งแต่ 8:30 จนไปสูงสุดที่เวลา 15:30 (อาจมีขึ้นลงเล็กน้อยได้บ้าง แต่โดยรวมแล้วต้องเพิ่มขึ้น)
และคงที่ไปเรื่อยๆ(ขึ้นลงเล็กน้อยได้) แล้วเริ่มลดลงตั้งแต่ 17:00
- ช่วงเวลาที่เบรคควรจะเหมาะสมกับคนที่เบรค เพื่อให้ไม่ทำงานเหนื่อยเกินไปด้วย

อธิบายเพิ่มเติม ดูรูปด้านล่างประกอบนะครับ
-ข้อมูลที่เป็น Input จะมีแค่จำนวนคนที่เข้าในแต่ละเวลา ก็คือช่อง In เท่านั้น(โดยจำนวนคนแต่ละวันไม่เท่ากัน)
-เข้า 8:30 เลิกงาน 17:00 เข้า 9:30 เลิก 17:30 ...........
-ข้อมูลที่ต้องการจากโปรแกรมก็คือด้านขวาจะมีบอกเวลาเข้า เวลาเบรคและช่องสำหรับลงชื่อ สร้างขึ้นมาอัตโนมัติ
-ส่วนที่จะมองเป็นหลักตามเงื่อนไขแรกก็คือช่อง AutoIn(จำนวนคนที่ Login ทำงานเวลานั้น) ซึ่งได้มาจาก ManP(จำนวนคนที่เข้ามาทำงานแล้วเวลานั้น) ลบกับ Break(คนที่เบรคในเวลานั้น) โดยตามเงื่อนไขคือจะเพิ่มจำนวนขึ้นเรื่อยๆตั้งแต่เริ่มจนมาสูงสุดที่ประมาณ 15:30 และเริ่มลดลงตั้งแต่ 17:00(รอบ 8:30 เลิกงาน)

http://images.temppic.com/21-01-2007/images_ads/165_1169353731.jpg

ส่วนที่เป็นโจทย์ก็คือทำยังไงให้โปรแกรมจัดเวลาได้เข้ากับเงื่อนไขทั้ง 2 อย่างได้ โดยมีแค่ข้อมูลจำนวนคนเข้า

ปัญหาที่ผมพบก็คือเมื่อพยายามจัดให้ตามเงื่อนไขแรก(AutoIn ขึ้นลงถูกต้อง)เงื่อนไขที่2ในเรื่องของเวลาที่แต่ละคนเบรคก็จะได้ออกมาไม่ดี หรือถ้าพยายามทำให้พร้อมกันทั้ง 2 เงื่อนไข จะกลายเป็นว่าเวลาได้ออกมาไม่ครบ
จะมีเงื่อนไขย่อยๆอย่างเช่น
-เวลาเบรคที่ 2 ก็จะขึ้นอยู่กับเบรคแรกที่ได้ไป
-เวลาเบรคที่จัดแต่ละรอบก็ควรจะกระจายไปถ้าหากมีคนน้อย

ไฟล์ตัวอย่างนะครับ http://download.yousendit.com/FA467DE06B5FE78F

ขอบคุณล่วงหน้าสำหรับทุกคนที่เข้ามาอ่านนะครับ

เนื่องจาก file มัน expire แล้ว
เลยอาศัยข้อมูลในรูป jpg
แล้วทดลองเขียนโปรแกรมโดยใช้หลักการ genetic algorithm
ทดลองดูได้ผลประมาณนี้
(ไม่ได้ตรวจสอบความถูกต้องนะ แค่เห็นไกล้เคียงก็พอใจแล้ว)

number คือ จำนวนคน ณ ขณะนั้น (ไม่นับพวก break)
valid คือจำนวนคน ที่ลบ พวก break แล้ว
จะเห็นว่าได้ constraint ที่มากขึ้นเรื่อยๆ จน 15:00 แล้วคงที่
แล้วเริ่มลดลงเมื่อ 17:30

time = 08:30:00, number = 8, valid = 8
time = 08:45:00, number = 8, valid = 8
time = 09:00:00, number = 13, valid = 13
time = 09:15:00, number = 13, valid = 13
time = 09:30:00, number = 17, valid = 17
time = 09:45:00, number = 17, valid = 17
time = 10:00:00, number = 20, valid = 19
time = 10:15:00, number = 20, valid = 18
time = 10:30:00, number = 23, valid = 20
time = 10:45:00, number = 23, valid = 16
time = 11:00:00, number = 26, valid = 25
time = 11:15:00, number = 26, valid = 25
time = 11:30:00, number = 29, valid = 25
time = 11:45:00, number = 29, valid = 27
time = 12:00:00, number = 33, valid = 27
time = 12:15:00, number = 33, valid = 28
time = 12:30:00, number = 35, valid = 30
time = 12:45:00, number = 35, valid = 28
time = 13:00:00, number = 35, valid = 27
time = 13:15:00, number = 35, valid = 30
time = 13:30:00, number = 37, valid = 30
time = 13:45:00, number = 37, valid = 28
time = 14:00:00, number = 39, valid = 33
time = 14:15:00, number = 39, valid = 32
time = 14:30:00, number = 41, valid = 34
time = 14:45:00, number = 41, valid = 38
time = 15:00:00, number = 44, valid = 38
time = 15:15:00, number = 44, valid = 38
time = 15:30:00, number = 44, valid = 39
time = 15:45:00, number = 44, valid = 40
time = 16:00:00, number = 44, valid = 39
time = 16:15:00, number = 44, valid = 41
time = 16:30:00, number = 44, valid = 41
time = 16:45:00, number = 44, valid = 40
time = 17:00:00, number = 44, valid = 40
time = 17:15:00, number = 44, valid = 38
time = 17:30:00, number = 36, valid = 32
time = 17:45:00, number = 36, valid = 30
time = 18:00:00, number = 31, valid = 28
time = 18:15:00, number = 31, valid = 29
time = 18:30:00, number = 27, valid = 25
time = 18:45:00, number = 27, valid = 24
time = 19:00:00, number = 24, valid = 24
time = 19:15:00, number = 24, valid = 21
time = 19:30:00, number = 21, valid = 18
time = 19:45:00, number = 21, valid = 17
time = 20:00:00, number = 18, valid = 17
time = 20:15:00, number = 18, valid = 18
time = 20:30:00, number = 15, valid = 14
time = 20:45:00, number = 15, valid = 15
time = 21:00:00, number = 11, valid = 10
time = 21:15:00, number = 11, valid = 10
time = 21:30:00, number = 9, valid = 9
time = 21:45:00, number = 9, valid = 9
time = 22:00:00, number = 9, valid = 9
time = 22:15:00, number = 9, valid = 9
time = 22:30:00, number = 7, valid = 7
time = 22:45:00, number = 7, valid = 7
time = 23:00:00, number = 5, valid = 5
time = 23:15:00, number = 5, valid = 5
time = 23:30:00, number = 3, valid = 3
time = 23:45:00, number = 3, valid = 3
time = 00:00:00, number = 0, valid = 0

ข้อมูลการ break ของแต่ละคน ประมาณนี้

start:08:30:00, break1:11:15:00, break2:13:30:00, break3:15:15:00
start:08:30:00, break1:10:30:00, break2:12:30:00, break3:14:00:00
start:08:30:00, break1:10:30:00, break2:12:00:00, break3:13:30:00
start:08:30:00, break1:10:30:00, break2:13:15:00, break3:15:15:00
start:08:30:00, break1:10:15:00, break2:12:15:00, break3:13:45:00
start:08:30:00, break1:10:15:00, break2:11:45:00, break3:13:45:00
start:08:30:00, break1:10:45:00, break2:12:15:00, break3:14:30:00
start:08:30:00, break1:10:00:00, break2:12:00:00, break3:13:45:00
start:09:00:00, break1:11:00:00, break2:13:30:00, break3:15:15:00
start:09:00:00, break1:10:45:00, break2:12:45:00, break3:14:15:00
start:09:00:00, break1:10:45:00, break2:12:00:00, break3:13:30:00
start:09:00:00, break1:10:45:00, break2:13:15:00, break3:14:45:00
start:09:00:00, break1:10:45:00, break2:12:45:00, break3:14:30:00
start:09:30:00, break1:11:30:00, break2:12:45:00, break3:15:00:00
start:09:30:00, break1:10:45:00, break2:12:45:00, break3:14:30:00
start:09:30:00, break1:10:45:00, break2:13:00:00, break3:14:30:00
start:09:30:00, break1:12:00:00, break2:14:00:00, break3:16:15:00
start:10:00:00, break1:11:45:00, break2:13:45:00, break3:15:30:00
start:10:00:00, break1:11:30:00, break2:12:30:00, break3:14:00:00
start:10:00:00, break1:11:30:00, break2:13:30:00, break3:15:30:00
start:10:30:00, break1:11:30:00, break2:13:00:00, break3:14:30:00
start:10:30:00, break1:12:00:00, break2:14:45:00, break3:16:30:00
start:10:30:00, break1:12:45:00, break2:15:00:00, break3:16:45:00
start:11:00:00, break1:13:00:00, break2:14:45:00, break3:17:00:00
start:11:00:00, break1:12:30:00, break2:14:00:00, break3:16:15:00
start:11:00:00, break1:13:15:00, break2:15:30:00, break3:17:15:00
start:11:30:00, break1:14:15:00, break2:16:30:00, break3:18:45:00
start:11:30:00, break1:13:00:00, break2:14:15:00, break3:16:30:00
start:11:30:00, break1:13:45:00, break2:15:30:00, break3:17:45:00
start:12:00:00, break1:14:30:00, break2:17:00:00, break3:18:45:00
start:12:00:00, break1:14:15:00, break2:15:45:00, break3:17:15:00
start:12:00:00, break1:14:15:00, break2:16:45:00, break3:18:45:00
start:12:00:00, break1:13:45:00, break2:15:30:00, break3:17:45:00
start:12:30:00, break1:14:00:00, break2:16:00:00, break3:18:00:00
start:12:30:00, break1:15:00:00, break2:17:00:00, break3:19:15:00
start:13:30:00, break1:15:15:00, break2:17:30:00, break3:19:30:00
start:13:30:00, break1:15:00:00, break2:17:30:00, break3:19:45:00
start:14:00:00, break1:16:00:00, break2:18:15:00, break3:20:00:00
start:14:00:00, break1:15:15:00, break2:17:45:00, break3:19:45:00
start:14:30:00, break1:16:00:00, break2:17:15:00, break3:19:15:00
start:14:30:00, break1:16:00:00, break2:17:45:00, break3:19:45:00
start:15:00:00, break1:17:15:00, break2:19:15:00, break3:21:15:00
start:15:00:00, break1:17:30:00, break2:19:30:00, break3:21:00:00
start:15:00:00, break1:16:45:00, break2:18:15:00, break3:20:30:00

ส่วนวิธี จะค่อยๆอธิบายนะ

library ที่ใช้คือ pygene
จริงๆอยากใช้ ruby แต่ ruby ไม่มี Genetic algorithm library ดีๆเลย

sugree's picture

เอ้ย กดนาทีเดียวกัน อืมกำลังหา python ga พอดีเลย

อันที่ 3 ยังเป็นวุ้นอยู่เลยครับ
ส่วน 2 อันแรก ปริมาณเอกสารไกล้เคียงกัน
ดูจำนวน code แล้ว อันแรก น่าจะภาษีดีกว่านะครับ

ในการใช้ GA สิ่งแรกที่เราต้องนิยามก็คือ Gene
เปรียบเทียบกับสิ่งมีชีวิตอย่างเราแล้ว gene แต่ละตัวจะเป็นตัวกำหนด
คุณสมบัติต่างๆของเรา (เช่น gene ตัวนี้กำหนดสีผิว)

ใน pygene มี class สำหรับให้เราเลือกใช้สร้าง gene หลายแบบเชียว
เช่น IntGene, FloatGene
แต่สำหรับ โจทย์นี้ ผมเลือกสร้าง Gene เอง
โดยเลือก gene หนึ่งตัวแทนคนหนึ่งคน
ซื่อภายใน gene จะมีข้อมูล 3 ตัวคือ
ช่วงเวลา break ครั้งที่ 1, ครั้งที่ 2, ครั้งที่ 3

เริ่มด้วยการสร้าง class เพื่อ represent ข้อมูล คนหนึ่งคนก่อน
(ขออภัยในความเยิ่นเย้อของ python, เพราะพึ่งหัดเขียน)

class Break:
    def __init__(self, br1, br2, br3):
        self.values = [br1,br2,br3]
 
    def plus(self, index, value):
        self.values[index] += value
 
    def __repr__(self):
        return "(br1 = %d, br2 = %d, br3 = %d)" % (self.br1(), self.br2(), self.br2())
 
    def br1(self):
        return self.values[0]
 
    def br2(self):
        return self.values[1]
 
    def br3(self):
        return self.values[2]
 
    def br(self):
        return self.values

เสร็จแล้วก็ implement gene ขึ้นมา
โดย method ที่สำคัญที่ต้อง override ก็คือ
__add__ -> จะเกิดอะไรขึ้น ถ้าจับ gene 2 ตัวมาผสมกัน
ในที่นี้ลองใช้วิธีหาค่าเฉลี่ย
mutate -> ในการสืบทอดของแต่ละรุ่น จะเกิดการกลายพันธ์
ของเรากำหนดให้มีการกลายพันธ์ที่ เวลาที่ break เลื่อนขึ้นหรือลดลง 1 unit (15 นาที)
random -> รู้สึกจะใช้ตอนที่เริ่มสร้าง gene ครั้งแรก

class BreakGene(BaseGene):
 
    def __add__(self, other):
        ret = Break((self.br1() + other.br1())/2, 
                    (self.br2() + other.br2())/2,
                    (self.br3() + other.br3())/2)
        return ret
 
    def mutate(self):
        x = int(uniform(1,3))
        if uniform(-1,1) > 0:
            y = 1
        else:
            y = -1
 
        self.value.plus(x-1, y)
 
 
    def randomValue(self):
         br1 = int(uniform(6,10))
         br2 = int(uniform(6,10))
         br3 = int(uniform(6,10))
         return Break(br1, br2, br3)
 
    def __repr__(self):
        return self.value.__repr__()

พอมี gene แล้ว ก็ต้องมี Organism
หรือโครงสร้างที่เกิดจากการรวมตัวของ gene

ในโจทย์นี้ Organism ก็คือผลลัพท์ของการจัดตารางของคนทั้งหมดรวมกัน
สมมติมีคน 43 คน
Organism นี้ก็จะมี 43 gene

Organism นี้จะถูกใจเราหรือไม่ เราก็จะดูที่ Fitness function
ค่านี้คือค่าที่บอกว่า Organism นั้นๆดีพอที่จะอยู่รอดต่อไปในรุ่นหน้าหรือไม่
ถ้าไม่ดีพอ ก็จะตายไป แต่ถ้าดีพอ ก็อาจจะไปจับคุ่กับอีก organize หนึ่ง
แล้วเกิดลูกที่มีคุณสมบัติดีขึ้น

ใน pygene Fitness function ที่เข้าไกล้ 0
จะถือเป็นเป็น Organism ในอุดมคติ

เริ่มด้วยการกำหนด ตารางเข้าทำงาน
แต่ละ element แทนคนหนึ่งคน
ตัวเลขแสดงเวลาที่เข้างาน
0 -> 8:30,1 -> 8:15,...

inList = [0,0,0,0,0,0,0,0,
          2,2,2,2,2,
          4,4,4,4,
          6,6,6,
          8,8,8,
          10,10,10,
          12,12,12,
          14,14,14,14,
          16,16,
          20,20,
          22,22,
          24,24,
          26,26,26]

สร้าง genome โดยใช้ inList เป็นข้อมูล
ตัว genome ใน pygene นั้นกำหนดให้ใช้ dict
ก็เลยต้องตั้งชื่อให้ด้วย

def createGenome():
    ret = {}
    count = 0
    for i in range(len(inList)):
        ret["t%02d" % count] = BreakGene
        count += 1
    return ret

จากนั้นก็นิยาม Organism

class BreakOrganize(Organism):
    genome = createGenome()
 
    def fitness(self):
        return self.calculateCrit1() + self.calculateCrit2() + self.calculateInvalid()

ประเด็นต่างๆ ส่วนใหญ่จะอยุ่ที่ fitness function อย่างเดียว
อย่างในที่นี้มี fitness creteria อยุ่ 3 แบบก็คือ


ในคน 1 คน ช่วงเวลาการ break ของแต่ละ break ควรห่างกันประมาณ 2 ชั่วโมง
(15 นาที่เท่ากับ 1 unit, 2 ชั่วโมง เท่ากับ 8 unit)

    def calculateCrit1(self):
        s = 0
        for gene in self.genes.values():
            s = (8 - gene.value.br1()) ** 2
            s += (8 - gene.value.br2()) ** 2
            s += (8 - gene.value.br3()) ** 2
        return s



รวมๆแล้ว ช่วงเวลา break กับทำงาน ร่วมกันแล้วต้องไม่เกิน 9 ชั่วโมง,
ตัวเลขต้องไม่เท่ากับ 0 หรือติดลบ

    def calculateInvalid(self):
        for gene in self.genes.values():
            if gene.value.br1() + gene.value.br2() + gene.value.br3() + 5 > 36 :
                return 100000
            if gene.value.br1() < 1 or gene.value.br2() < 1 or  gene.value.br3() < 1 :
                return 200000
        return 0



จำนวนคนที่ active ในช่วงเวลาหนึ่งๆ ต้องค่อยๆเพิ่มขึ้น
จนถึง 15:30 แล้วคงที่ จากนั้นก็ค่อยๆลดลงเมื่อถึงเวลา 17:xx
ตรงนี้เราใช้วิธีสร้าง graph ขึ้นมา แล้วเปรียบเทียบค่าว่า
พฤติกรรม organism เราสอดคล้องกับ graph นี้ไหม

    def calculateCrit2(self):
        tables = self.makeTables()
        maxValue = 0
        for i in range(0, maxBegin):
            maxValue += tables[i][0]
 
        diff = 0
        for i in range(0, 63):
            diff += self.calcDiff(i, maxValue, tables[i][1])
 
        return diff
 
    def calcDiff(self, index, maxValue, value):        
        if index < maxBegin:
            return (((float(maxValue)/float(maxBegin)) * index) - value ) ** 2
        elif index >= maxBegin and index <= maxEnd:
            return (maxValue - value) ** 2
        else:
            return ((maxValue - (float(maxValue)/float(63-maxEnd) * (63 - index))) - value) ** 2
 
 
    def makeTables(self):
        ret = []
        for i in range(0,indexEnd):
            ret.append([0,0])
        for name, gene in self.genes.items():
            start = inList[int(name[1:])]
            for i in range(start, start+36):
                ret[i][0] += 1
                if gene.value.valid(start, i):
                    ret[i][1] += 1
        return ret

เมื่อมี gene แล้ว มี organism แล้ว
สุดท้ายก็มี Population ที่ประกอบด้วย organism หลายๆตัว

class BreakPopulation(Population):
    species = BreakOrganize
    initPopulation = 20
    childCull = 5
    childCount =  50

เวลา run ก็ประมาณนี้

b = BreakPopulation()
for i in range(4):
    b.gen()

ทดลองแค่ 4 รุ่นพอ (เยอะๆแล้วเจ๊ง มั่วหมดเลย)

Note: จริงๆผมก็ไม่รู้หรอกว่า theory ของ GA จริงๆเป็นอย่างไร
ขอใช้คำของคุณ Dome
"program โดยใช้สัญชาตญาน"
มั่วไปเรื่อยๆ

freeman's picture

สุดยอดเลยครับ คุณ pphetra เช้านี้ผมนั่งค้นเรื่อง GA ทั้งช่วงเช้าเลย พอจะเข้าใจบ้างนิดหน่อย และไปเจอ อีกเรื่องหนึ่งคือ ant colony รู้สึกเค้าจะลองเอามาใช้แก้ปัญหา Traveling Salesman Problem เหมือนกัน พอจะให้ความรู้เพิ่มเติม (ถ้าเขียนโปรแกรมให้ดูได้ด้วยก็ดีอะ):-)

sugree's picture
  • สมมติว่าตำแหน่งของมดคือคำตอบ
  • มดมีฟีโรโมน และจะทิ้งกลิ่นซึ่งจางลงตามกาลเวลา
  • มดที่อยู่ใกล้ๆ จะได้กลิ่นและอยากเดินทางเดียวกัน
  • คำตอบดี กลิ่นก็แรงและนาน
  • ปล่อยให้มันเดินไปเรื่อยๆ

อืม ผมเข้าใจมดน้อยกว่าอนุภาคและพันธุกรรมนะ particle swarm จะโอเคกว่า…

sugree's picture

ใส่ crossover กับ ตาย ซักนิดน่าจะดีขึ้น หวังพึ่ง X-Men มากๆ จะกลายเป็น Doom

sugree's picture

โอ้ว ผมลืมไปเลยว่าใช้ GA ช่วยได้
ใช้ lib สำเร็จรูปรึเปล่าครับ หรือว่าเขียนสด

freeman's picture

ผมยังไม่เข้าใจเรื่อง GA เลยครับ พออธิบายคร่าวไ้ด้มั้ยครับ หรือว่า เราเปิดห้องเกี่ยวกับ algorithm พวกนี้มาแลกเปลี่ยนคุยกัน ดีอะป่าวอะ
เซียนอย่างคุณ pphetra น่าจะช่วยได้ หุหุ

sugree's picture

เรื่องของเรื่องคือ

  • ปัญหานี้เราไม่รู้วิธีแบ่ง และก็ไม่รู้ว่าจะหาวิธีแบ่งยังไง
  • ตอนนี้รู้แค่อินพุท กับรู้ว่าผลการแบ่งมันดีไม่ดียังไง

จริงๆ แล้วมันเหมาะกับ GA มาก เพราะมันสนแค่ผลลัพธ์ และต้องการฟังก์ชั่นเพื่อประเมินความถูกต้องของผลลัพธ์ นอกนั้นก็มั่วแบบมีหลักการ เพื่อให้ลู่เข้าเร็วนิดนึง

veer's picture

โอ้ สุดยอดเลยครับ ผมคงต้องเวลาอ่านอีกซักระยะถึงจะเข้าถึง ยังไงก็ขอบคุณคุณ pphetra มากครับ รวมถึงคนอื่นที่ช่วยตอบด้วยครับ

ว่าแต่ GA แบบนี้ใน VB.net มีมั้ยนะ ลองหาใน google เจอแต่ ebook -_-"

GA lib ใน vb ไม่น่าจะมีนะ
แต่ GA มันไม่ค่อยโหดมาก น่าจะ implement ขึ้นมาเองได้

ต้องกลับไปอ่าน GA โดยด่วน

โลกมันวิ่งแซงผมไปไกลแล้วนะนี่...

sugree's picture

เจอเพิ่มเติมจาก Google Code

http://code.google.com/p/pgap/ Python
http://code.google.com/p/noein/ C#

คงต้องหาหนังสือ GA มาอ่านบ้างแล้ว ใครพอมี ebook ให้โหลดบ้างมั้ยครับ ยังไงจะลองพยายามทำดูครับ ขอบคุณมากๆ

นั่งทำความเข้าใจอยู่นาน พอจะมองภาพออกแล้วนอกจากส่วนที่เป็นฟังก์ชั่นที่ 3 ที่เป็นการเทียบกราฟน่ะครับ การสร้างกราฟขึ้นมาแล้วเปรียบเทียบนี้ใช้วิธีเทียบกันอย่างไรครับ
พอเข้าใจในทางแนวคิด แต่เวลานำลงมาเขียนในโปรแกรมจะเขียนเป็นรูปแบบอย่างไรครับ ช่วยชี้แนะด้วย

เริ่มด้วยเรากำหนด graph จำนวนคน ในอุดมคติ ณ ช่วงเวลาใดๆขึ้นมาก่อน

break-graph

จากนั้น เราก็นำ organism ของเรามา คำนวณว่า
ถ้าเวลา break ออกมาแบบนั้นๆแล้ว
จำนวนคน ณ ช่วงเวลาต่างๆของเราเป็นอย่างไร

ในแต่ละช่วงเวลา
นำค่าที่ได้ - ค่าที่อยากให้เป็น ยกกำลัง 2 (เพื่อไม่ให้เป็นเลขลบ)

ผลรวมก็คือ fitness value
(ถ้าตรงเป๊ะตามที่อยากให้เป็น ก็จะได้ fitness เป็น 0)

function maketable ที่เห็น ก็คือการแปลงรูป gene ให้ออกมาในรูปตาราง

| เวลา | จำนวนคน | จำนวนที่ available (ไม่ break) |

เพื่อที่จะได้เอาไปเปรียบเทียบ graph

พึ่งจะรู้ว่ามี GA แล้วก็ algorithm อื่นๆ อีกเต็มเลย วิ่งไม่ทันแล้ว T^T

Ruby on new Rails(user) >.<

มาถามเพิ่มเติมใหม่ จริงๆแล้วผมเขียน python ไม่เป็น เลยจะถามว่า
def mutate(self):
x = int(uniform(1,3))
if uniform(-1,1) > 0:
y = 1
else:
y = -1

uniform(1,3)
uniform(-1,1)
นี่หมายถึงอะไรเหรอครับ เป็นการสุ่มค่าหรือเปล่าครับ

sugree's picture

เมธอดนี้เอาไว้กลายพันธุ์เพื่อสร้าง Mutant นี่แหละ X-Men ถ้าโชคดีก็ได้ Magneto แต่ถ้าโชคร้ายอาจจะกลายเป็น Rogue

    def mutate(self):
        x = int(uniform(1,3))
        if uniform(-1,1) > 0:
            y = 1
        else:
            y = -1
 
        self.value.plus(x-1, y)

ดูกันชัดๆ มันไม่ได้ทำอะไรมาก ก่อนอื่นก็ x คือช่วงเวลาที่ต้องการเปลี่ยนแปลง 1 คือช่วงก่อนเบรคแรก 2 คือช่วงหลักเบรคแรก 3 คือหลังเบรคที่สอง

ต่อมาก็ มั่วว่าจะ ลด -1 หรือเพิ่ม 1 โดยที่มีโอกาส 50% เนื่องจาก uniform(-1,1) จะให้ค่าเป็นเลขจำนวนจริงในช่วง -1 ถึง 1 พอได้ค่า x y ก็เอาไปใช้เรียก plus() เพื่อเอาค่า y ไปเปลี่ียนในเบรคที่กำหนด

บางทีก็รุ้สึกทึ่งกับ GA
ตรงที่มันเป็นเรื่องของ random แท้ๆเลย

อืม ขอบคุณมากครับ คงต้องแกะโคด ไปทำGAเอง รวมทั้งเขียนโปรแกรมให้เสร็จในสัปดาห์หน้า ตายแน่ๆงานปกติก็ต้องทำ T__T

ย้าย Codenone

ประกาศย้าย Codenone ไปใช้ Forum ของ Blognone แทนครับ ตามไปตั้งกระทู้ต่อได้ที่ Codenone Forum (รายละเอียดอ่านจากกระทู้ ย้าย Codenone ไปรวมกับ Blognone)

กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น