我决定实施一个简单版本的GA算法。我首先使用Qt设计器创建一个.ui文档,其中包含GUI的组件和布局。然后尝试将它与python连接,但是,当来到self.dis_speed.insert(a)时,窗口立即关闭。这是整个代码:
import sys
import random
import threading
import copy
from PyQt5 import QtCore, QtGui, uic, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton,QTextEdit,QAction, QLabel,QSpinBox,QLineEdit
from PyQt5.QtCore import pyqtSlot
qtCreatorFile = 'assignment1_gui.ui' # Enter file here.
class Ui(QtWidgets.QMainWindow):
size=0
fit_dict={}
individual=[]
def __init__(self,parent=None):
super(Ui,self).__init__(parent=parent)
s=uic.loadUi(qtCreatorFile, self)
self.show()
self.but_start.clicked.connect(self.start)
self.dis_speed=s.dis_speed
self.dis_fit=s.dis_fit
self.dis_speed.setReadOnly(True)
self.dis_fit.setReadOnly(True)
def init_ind(a):
indi = [[] for l in range(a)]
for i in range(0,a):
for j in range(0,28):
indi[i].append(chr(random.randint(32, 127)))
return indi
def evaluate_fit(target,a):
count=0
for i in range(0,len(target)):
if target[i]==a[i]:
count+=1
return count
return(28-Levenshtein.hamming(str(target),str(a)))
def mutate(a):
for i in range(0,len(a)):
if(random.random()<(1/len(a))):
a[i]=chr(random.randint(32, 127))
return a
def crossover(a,b):
c=list()
for i in range(0,len(a)):
if random.random()<0.5:
c.append(a[i])
else:
c.append(b[i])
return c
def ga_cross(self,individual,target):
ind=copy.deepcopy(Ui.individual)
speed=0
printf=0
while(1):
a=random.randint(0,Ui.size-1)
b=random.randint(0,Ui.size-1)
if Ui.fit_dict[a]>Ui.fit_dict[b]:
parent1=ind[a]
else:
parent1=ind[b]
a=random.randint(0,Ui.size-1)
b=random.randint(0,Ui.size-1)
if Ui.fit_dict[a]>Ui.fit_dict[b]:
parent2=ind[a]
else:
parent2=ind[b]
child=Ui.mutate(Ui.crossover(parent1,parent2))
a=random.randint(0,Ui.size-1)
b=random.randint(0,Ui.size-1)
if Ui.fit_dict[a]>Ui.fit_dict[b]:
ind[b]=child
Ui.fit_dict[b]=Ui.evaluate_fit(target,child)
else:
ind[a]=child
Ui.fit_dict[a]=Ui.evaluate_fit(target,child)
speed+=1
if child==target:
break
if printf%10==0:
res=max(Ui.fit_dict.items(), key=lambda x: x[1])
Ui.tex(str(speed),str(ind[res[0]]))
printf+=1
@pyqtSlot()
def tex(self,a,b):
self.dis_speed.end(False)
self.dis_speed.insert(a) #close immediately
self.dis_fit.end(False)
self.dis_fit.insert(b)
@pyqtSlot()
def start(self):
target=list('methinks it is like a weasel')
Ui.size=int(self.spin_size.value())
Ui.individual=Ui.init_ind(Ui.size)
s=range(0,Ui.size)
ss=[0 for i in range(0,Ui.size)]
Ui.fit_dict=dict(zip(s,ss))
for i in range(0,Ui.size):
Ui.fit_dict[i]=Ui.evaluate_fit(target,Ui.individual[i])
Ui.ga_cross(self,Ui.individual,target)
Ui.ga_nocross(self,Ui.individual,target)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = Ui()
window.show()
sys.exit(app.exec_())
以下页面是XML格式的.ui文档,可以直接复制。
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>957</width>
<height>717</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="lab_title">
<property name="geometry">
<rect>
<x>100</x>
<y>40</y>
<width>811</width>
<height>41</height>
</rect>
</property>
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>36</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Comparision between GA with&without crossover</string>
</property>
</widget>
<widget class="QSpinBox" name="spin_size">
<property name="geometry">
<rect>
<x>590</x>
<y>120</y>
<width>111</width>
<height>41</height>
</rect>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="displayIntegerBase">
<number>10</number>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>310</x>
<y>130</y>
<width>271</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Please select the size of population:</string>
</property>
</widget>
<widget class="QPushButton" name="but_start">
<property name="geometry">
<rect>
<x>380</x>
<y>190</y>
<width>191</width>
<height>71</height>
</rect>
</property>
<property name="font">
<font>
<family>Wingdings 2</family>
<pointsize>24</pointsize>
</font>
</property>
<property name="text">
<string>START!</string>
</property>
</widget>
<widget class="QLabel" name="lab_nocr">
<property name="geometry">
<rect>
<x>30</x>
<y>330</y>
<width>241</width>
<height>51</height>
</rect>
</property>
<property name="font">
<font>
<family>Trajan Pro</family>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Speed of no crossover:</string>
</property>
</widget>
<widget class="QLabel" name="lab_cr">
<property name="geometry">
<rect>
<x>590</x>
<y>330</y>
<width>211</width>
<height>51</height>
</rect>
</property>
<property name="font">
<font>
<family>Trajan Pro</family>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Speed of crossover:</string>
</property>
</widget>
<widget class="QLabel" name="lab_nfit">
<property name="geometry">
<rect>
<x>130</x>
<y>410</y>
<width>111</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<family>YuMincho</family>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Fittest Now:</string>
</property>
</widget>
<widget class="QLabel" name="lab_fit">
<property name="geometry">
<rect>
<x>690</x>
<y>410</y>
<width>111</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<family>YuMincho</family>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Fittest Now:</string>
</property>
</widget>
<widget class="QLineEdit" name="dis_nspeed">
<property name="geometry">
<rect>
<x>270</x>
<y>340</y>
<width>51</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="dis_nfit">
<property name="geometry">
<rect>
<x>20</x>
<y>440</y>
<width>341</width>
<height>41</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="dis_speed">
<property name="geometry">
<rect>
<x>800</x>
<y>340</y>
<width>41</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="dis_fit">
<property name="geometry">
<rect>
<x>600</x>
<y>440</y>
<width>291</width>
<height>41</height>
</rect>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>957</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>