#Copyright 2015. Aitch_K all rights reserved.
#CIST, Korea University

import random


########################################################
# - 유전자를 초기화해주는 함수
# - mChromo에 6자리로 구성된 임의의 유전자를 생성하고
#   생성된 유전자를 mChromoGrp에 저장 
# - mChromo는 임의로 생성된 각각의 염색체
# - mChromoGrp는 chromo 염색체의 그룹
########################################################
def init(mChromo, mChromoGrp):
	for i in range(chromoNum):
		mChromo = list()
		for j in range(6):
			mChromo.append(random.randrange(0, 2))
		mChromoGrp.append(mChromo)
	print mChromoGrp

	return mChromo, mChromoGrp	


########################################################
# - 본 함수는 너무 낮은 Value를 출력하는 유전자를 제거하는 함수
#   여기서 Value가 낮다는 것은 유전자가 좋지 못하다는 것을 의미
# - 본 소스는 Val의 합이 80이하일 경우 염색체를 0으로 초기화
# - 이후 Random함수를 이용해 새로운 유전자를 생성
########################################################
def lowerValChecker(mChromoGrp, mChromoSumV, mChromoSumW):
	for i in range(chromoNum):
		mChromoSumV.append(0)
		mChromoSumW.append(0)
		for j in range(6):
			mChromoSumV[i] += (v[j][mChromoGrp[i][j]])
			
	for i in range(chromoNum):
		if mChromoSumV[i] < MIN_VAL:
			mChromoSumV[i] = 0
			mChromoSumW[i] = 0

	return mChromoGrp, mChromoSumV, mChromoSumW



########################################################
# - 본 함수는 한계 Weight를 넘어가게 만드는 유전자를 제거하는 함수
# - 기본적으로 Knapsack Problem에서는 가방이 감당할 수 있는 최고 무게를 제한함
# - 본 소스에서는 Wei의 합이 120이tkd일 경우 염색체를 0으로 초기화
# - 이후 Random함수를 이용해 새로운 유전자를 생성
########################################################
def overWeiChecker(mChromoGrp, mChromoSumV, mChromoSumW):
	optWei = 0 
	for i in range(chromoNum):
		for j in range(6):
			mChromoSumW[i] += (w[j][mChromoGrp[i][j]])

	for i in range(chromoNum):
		if mChromoSumW[i] > MAX_WEI:
			mChromoSumV[i] = 0
			mChromoSumW[i] = 0

		if mChromoSumW[i] > chromoSumW[optWei]:
			optWei = i
	
	print "vList: " + str(mChromoSumV)
	print "vMax: " + str(mChromoSumV[optWei])
	print "wList: " + str(mChromoSumW)
	print "wOpt: " + str(mChromoSumW[optWei])

	return mChromoGrp, mChromoSumV, mChromoSumW


########################################################
# - 본 함수는 적당한 유전자들을 대상으로 진화를 수행하는 함수
# - 위에서 언급된 “적당한”은 너무 낮은 Val를 출력하지 않으며, 한계 Wei를 초과하지 않는 것을 의미
# - 적당하지 않아 0으로 초기화된 유전자들은 본 함수를 통해 새롭게 재생성됨
# - 유전자의 진화는 살아남은 유전자들을 대상으로 첫 번째 유전자의 3자리, 두 번째 유전자의 3자리를 결합하여 수행
#   ex) [ 0 | 0 | 1 | 0 | 1 | 0 ] + [ 0 | 1 | 0 | 1 | 0 | 0 ]
#       = [ 0 | 0 | 1 |] + [| 1 | 0 | 0 ]
########################################################
def evolutionFunc(mChromoGrp, mChromoSumV, mChromoSumW, mNewGenRsv, mNewGen):
	for i in range(len(mChromoSumV)):
		mNewGenRsv.append(0)
		mNewGenRsv[i] = list()
		if mChromoSumV[i] != 0:
			for j in range(6):
				mNewGenRsv[i].append(mChromoGrp[i][j])
		else:
			for j in range(6):
				mNewGenRsv[i].append(random.randrange(0, 2))
		
	for i in range(len(mChromoSumV)):
		mNewGen.append(mNewGenRsv[i][0:3]+mNewGenRsv[(i+1)%chromoNum][3:6])

	mChromoGrp = mNewGen

	return mChromoGrp, mChromoSumV, mChromoSumW, mNewGenRsv, mNewGen



### main routine #################################################################
chromoNum = 20
MAX_WEI = 120
MIN_VAL = 80
GENERATION = 50

v = [[0, 20], [0, 30], [0, 66], [0, 40], [0, 66], [0, 80]]
w = [[0, 10], [0, 20], [0, 30], [0, 40], [0, 50], [0, 70]]

chromo = list()
chromoGrp = list()

chromo, chromoGrp = init(chromo, chromoGrp)

for i in range(GENERATION):
	print "=============================================================="
	print "Gen " + str(i+1) 
	chromoSumV = list()
	chromoSumW = list()

	newGenRsv = list()
	newGen = list()

	print "v = [20, 30, 66, 40, 66, 80]"
	print "w = [10, 20, 30, 40, 50, 70]"

	chromoGrp, chromoSumV, chromoSumW = lowerValChecker(chromoGrp, chromoSumV, chromoSumW)
	chromoGrp, chromoSumV, chromoSumW = overWeiChecker(chromoGrp, chromoSumV, chromoSumW)
	chromoGrp, chromoSumV, chromoSumW, newGenRsv, newGen = evolutionFunc(chromoGrp, chromoSumV, chromoSumW, newGenRsv, newGen)
	
	print "==============================================================\n"

'Implementation' 카테고리의 다른 글

[Network] Network node size estimation  (0) 2017.07.04
Posted by Hugh_K
l