├── .gitignore ├── LICENSE ├── README.md ├── RQGA.py ├── QGA.py └── HGA.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | 61 | #Ipython Notebook 62 | .ipynb_checkpoints 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 ResearchCodesHub 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QuantumGeneticAlgorithms 2 | 3 | Genetic algorithms (GAs) are a class of evolutionary algorithms inspired by Darwinian natural selection. They are popular heuristic optimisation methods based on simulated genetic mechanisms, i.e. mutation, crossover, etc. and population dynamical processes such as reproduction, selection, etc. Over the last decade, the possibility to emulate a quantum computer (a computer using quantum-mechanical phenomena to perform operations on data) has led to a new class of GAs known under the name of ‘Quantum Genetic Algorithms’. In this repository we present three programs that illustrate different versions of quantum evolutionary algorithms: QGA, HGA and RQGA. 4 | 5 | Quantum Genetic Algorithm (QGA) is a QGA that can be used for the purposes of education and research. 6 | QGA is applied in a simple optimization problem: Let f(x)=abs(x-5/2+sin(x)) be a function that takes 7 | values in the range 0<=x<=15. Within this range f(x) has a maximum value at x=11 (binary value is equal to 1011). 8 | 9 | Hybrid Genetic Algorithm (HGA) is a GA that combines quantum operators (rotation, measure, quantum chromosomes, etc.) 10 | with classical genetic operators (crossover and mutation).It can be used for the purposes of education and research. 11 | HGA is applied in a simple optimization problem: Let f(x)=abs(x-5/2+sin(x)) be a function that takes values in the 12 | range 0<=x<=15. Within this range f(x) has a maximum value at x=11 (binary value is equal to 1011). 13 | 14 | Reduced Quantum Genetic Algorithm (RQGA) is a program in Python showing how to implement a 'true' quantum genetic algorithm 15 | based on a fitness quantum gate and Grover's search algorithm. It can be used for the purposes of education and research. 16 | RQGA is applied in a simple optimization problem: Let f(x)=abs(x-5/2+sin(x)) be a function that takes values in the range 17 | 0<=x<=15. Within this range f(x) has a maximum value at x=11 (binary value is equal to 1011). The program should be understood as a thinker toy, illustrating the ideas taken from the papers cited below. 18 | 19 | REFERENCES 20 | 21 | Udrescu, M.; Prodan, L.; Vladutiu, M. Implementing quantum genetic algorithms: a solution based on Grover’s algorithm. 22 | CF '06 Proceedings of the 3rd conference on Computing frontiers, Ischia, Italy, 3-5 May, 2006; pp. 71-82. 23 | 24 | Goswami, D.; Kumar, N. Quantum algorithm to solve a maze: converting the maze problem into a search problem. 25 | arXiv:1312.4116v1 [quant-ph]. 2013. 26 | 27 | Sofge, D.A. Prospective algorithms for quantum evolutionary computation. Proceedings of the Second Quantum Interaction 28 | Symposium (QI-2008), College Publications, Oxford, UK, 26-28 March, 2008. Available online: http://arxiv.org/ftp/arxiv/papers/0804/0804.1133.pdf 29 | 30 | Malossini, A.; Blanzieri, E.; Calarco, T. Quantum genetic optimization. IEEE Transactions on Evolutionary Computation. 31 | 2008, 12, 231-241. 32 | 33 | Ahuja, A.; Kapoor, S. A quantum algorithm for finding the maximum. arXiv:quant-ph/9911082v1. 1999. 34 | -------------------------------------------------------------------------------- /RQGA.py: -------------------------------------------------------------------------------- 1 | ######################################################### 2 | # # 3 | # REDUCED QUANTUM GENETIC ALGORITHM (25.05.2016) # 4 | # # 5 | # R. Lahoz-Beltra # 6 | # # 7 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND # 8 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # 9 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY # 10 | # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # 11 | # THE SOFWTARE CAN BE USED BY ANYONE SOLELY FOR THE # 12 | # PURPOSES OF RESEARCH AND EDUCATION. # 13 | # # 14 | ######################################################### 15 | import math 16 | import numpy as np 17 | 18 | ######################################################### 19 | # VARIABLES ALGORITHM AND PARAMETERS # 20 | ######################################################### 21 | n=4; 22 | fitness = np.empty([2**n]) 23 | cutoff=99; 24 | 25 | ######################################################### 26 | # CONVERTS A NON-SUPERPOSED BINARY STATE TO # 27 | # |psi> REGISTER IN SUPERPOSITION # 28 | ######################################################### 29 | def bin2dec(string_num): 30 | return str(int(string_num, 2)) 31 | 32 | def dec2vec(dec,n): 33 | vec=np.zeros((2**n,1)) 34 | vec[dec,0]=1; 35 | return vec 36 | 37 | def psi(string_num): 38 | dec=bin2dec(string_num) 39 | return dec2vec(dec,len(string_num)) 40 | 41 | ######################################################### 42 | # CREATES AN N-BIT HADAMARD MATRIX # 43 | ######################################################### 44 | def hadamard(n): 45 | r2=math.sqrt(2.0) 46 | H1=np.array([[1/r2,1/r2],[1/r2,-1/r2]]) 47 | if n==1: 48 | H=H1 49 | else: 50 | H=1; 51 | i=1; 52 | for i in range(1,n+1): 53 | H=np.kron(H,H1) 54 | return H 55 | 56 | ######################################################### 57 | # FITNESS QUANTUM GATE # 58 | ######################################################### 59 | def bin(i): 60 | if i == 0: 61 | return "0" 62 | s = '' 63 | while i: 64 | if i & 1 == 1: 65 | s = "1" + s 66 | else: 67 | s = "0" + s 68 | i >>= 1 69 | return s 70 | 71 | def Fitness_evaluation(): 72 | for i in range(0,2**n): 73 | fitness[i]=0 74 | 75 | ######################################################### 76 | # Define your problem in this section. For instance: # 77 | # # 78 | # Let f(x)=abs(x-5/2+sin(x)) be a function that takes # 79 | # values in the range 0<=x<=15. Within this range f(x) # 80 | # has a maximum value at x=11 (binary is equal to 1011) # 81 | ######################################################### 82 | for i in range(0,16): 83 | x=int(bin(i),2) 84 | # replaces the value of x in the function f(x) 85 | y=np.fabs((x-5)/(2+np.sin(x))) 86 | # the fitness value is calculated below: 87 | # (Note that in this example is multiplied 88 | # by a scale value, e.g. 100) 89 | fitness[i]=y*100 90 | 91 | ######################################################### 92 | # Best chromosome selection 93 | the_best_chrom=0; 94 | fitness_max=fitness[1]; 95 | for i in range(0,16): 96 | if fitness[i]>=fitness_max: 97 | fitness_max=fitness[i] 98 | the_best_chrom=i 99 | cutoff=the_best_chrom 100 | return cutoff 101 | 102 | ######################################################### 103 | # ORACLE:UNITARY F-CONDITIONAL INVERTER FOR N BITS INPUT# 104 | ######################################################### 105 | def U_Oracle(n): 106 | zero_mat=np.zeros((2**n,2**n)) 107 | i=0; 108 | for i in range(0,2**n): 109 | ########################### 110 | # Define here your oracle # 111 | ########################### 112 | if i==Fitness_evaluation(): 113 | O=1 114 | else: 115 | O=0 116 | # Inverter 117 | zero_mat[i,i]=(-1)**O 118 | return zero_mat 119 | 120 | ######################################################### 121 | # GROVER'S DIFFUSION OPERATOR # 122 | ######################################################### 123 | # Inversion about average 124 | def ia(n): 125 | ia_mat=2*np.ones(2**n)/(2**n) 126 | ia_mat=ia_mat-np.identity(2**n) 127 | return ia_mat 128 | 129 | ######################################################### 130 | # GROVER'S MAXIMUM ITERATIONS # 131 | ######################################################### 132 | def maxiter(n): 133 | max_iter=(np.pi/4)*math.sqrt(2**n) 134 | return max_iter 135 | 136 | ######################################################### 137 | # REDUCED QUANTUM GENETIC ALGORITHM # 138 | ######################################################### 139 | def RQGA(n, string_num): 140 | psi_=psi(string_num) 141 | H=hadamard(n) 142 | psi_=np.dot(H,psi_) 143 | print(psi_) 144 | print() 145 | iter=np.trunc(maxiter(n)) 146 | iter=int(round(iter)) 147 | for i in range (1,iter): 148 | U_O=U_Oracle(n) 149 | print(U_O) 150 | print() 151 | psi_=np.dot(U_O,psi_) 152 | print(psi_) 153 | print() 154 | D=ia(n) 155 | psi_=np.dot(D,psi_) 156 | print(psi_) 157 | 158 | ######################################################### 159 | # # 160 | # MAIN PROGRAM # 161 | # # 162 | ######################################################### 163 | print("REDUCED QUANTUM GENETIC ALGORITHM") 164 | input("Press Enter to continue...") 165 | RQGA(4,'0000'); 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /QGA.py: -------------------------------------------------------------------------------- 1 | ######################################################### 2 | # # 3 | # QUANTUM GENETIC ALGORITHM (24.05.2016) # 4 | # # 5 | # R. Lahoz-Beltra # 6 | # # 7 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND # 8 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # 9 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY # 10 | # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # 11 | # THE SOFWTARE CAN BE USED BY ANYONE SOLELY FOR THE # 12 | # PURPOSES OF EDUCATION AND RESEARCH. # 13 | # # 14 | ######################################################### 15 | import math 16 | import numpy as np 17 | import matplotlib.pyplot as plt 18 | 19 | ######################################################### 20 | # ALGORITHM PARAMETERS # 21 | ######################################################### 22 | N=50 # Define here the population size 23 | Genome=4 # Define here the chromosome length 24 | generation_max=450 # Define here the maximum number of 25 | # generations/iterations 26 | 27 | ######################################################### 28 | # VARIABLES ALGORITHM # 29 | ######################################################### 30 | popSize=N+1 31 | genomeLength=Genome+1 32 | top_bottom=3 33 | QuBitZero = np.array([[1],[0]]) 34 | QuBitOne = np.array([[0],[1]]) 35 | AlphaBeta = np.empty([top_bottom]) 36 | fitness = np.empty([popSize]) 37 | probability = np.empty([popSize]) 38 | # qpv: quantum chromosome (or population vector, QPV) 39 | qpv = np.empty([popSize, genomeLength, top_bottom]) 40 | nqpv = np.empty([popSize, genomeLength, top_bottom]) 41 | # chromosome: classical chromosome 42 | chromosome = np.empty([popSize, genomeLength],dtype=np.int) 43 | child1 = np.empty([popSize, genomeLength, top_bottom]) 44 | child2 = np.empty([popSize, genomeLength, top_bottom]) 45 | best_chrom = np.empty([generation_max]) 46 | 47 | # Initialization global variables 48 | theta=0; 49 | iteration=0; 50 | the_best_chrom=0; 51 | generation=0; 52 | 53 | ######################################################### 54 | # QUANTUM POPULATION INITIALIZATION # 55 | ######################################################### 56 | def Init_population(): 57 | # Hadamard gate 58 | r2=math.sqrt(2.0) 59 | h=np.array([[1/r2,1/r2],[1/r2,-1/r2]]) 60 | # Rotation Q-gate 61 | theta=0; 62 | rot =np.empty([2,2]) 63 | # Initial population array (individual x chromosome) 64 | i=1; j=1; 65 | for i in range(1,popSize): 66 | for j in range(1,genomeLength): 67 | theta=np.random.uniform(0,1)*90 68 | theta=math.radians(theta) 69 | rot[0,0]=math.cos(theta); rot[0,1]=-math.sin(theta); 70 | rot[1,0]=math.sin(theta); rot[1,1]=math.cos(theta); 71 | AlphaBeta[0]=rot[0,0]*(h[0][0]*QuBitZero[0])+rot[0,1]*(h[0][1]*QuBitZero[1]) 72 | AlphaBeta[1]=rot[1,0]*(h[1][0]*QuBitZero[0])+rot[1,1]*(h[1][1]*QuBitZero[1]) 73 | # alpha squared 74 | qpv[i,j,0]=np.around(2*pow(AlphaBeta[0],2),2) 75 | # beta squared 76 | qpv[i,j,1]=np.around(2*pow(AlphaBeta[1],2),2) 77 | 78 | ######################################################### 79 | # SHOW QUANTUM POPULATION # 80 | ######################################################### 81 | def Show_population(): 82 | i=1; j=1; 83 | for i in range(1,popSize): 84 | print() 85 | print() 86 | print("qpv = ",i," : ") 87 | print() 88 | for j in range(1,genomeLength): 89 | print(qpv[i, j, 0],end="") 90 | print(" ",end="") 91 | print() 92 | for j in range(1,genomeLength): 93 | print(qpv[i, j, 1],end="") 94 | print(" ",end="") 95 | print() 96 | 97 | ######################################################### 98 | # MAKE A MEASURE # 99 | ######################################################### 100 | # p_alpha: probability of finding qubit in alpha state 101 | def Measure(p_alpha): 102 | for i in range(1,popSize): 103 | print() 104 | for j in range(1,genomeLength): 105 | if p_alpha<=qpv[i, j, 0]: 106 | chromosome[i,j]=0 107 | else: 108 | chromosome[i,j]=1 109 | print(chromosome[i,j]," ",end="") 110 | print() 111 | print() 112 | 113 | ######################################################### 114 | # FITNESS EVALUATION # 115 | ######################################################### 116 | def Fitness_evaluation(generation): 117 | i=1; j=1; fitness_total=0; sum_sqr=0; 118 | fitness_average=0; variance=0; 119 | for i in range(1,popSize): 120 | fitness[i]=0 121 | 122 | ######################################################### 123 | # Define your problem in this section. For instance: # 124 | # # 125 | # Let f(x)=abs(x-5/2+sin(x)) be a function that takes # 126 | # values in the range 0<=x<=15. Within this range f(x) # 127 | # has a maximum value at x=11 (binary is equal to 1011) # 128 | ######################################################### 129 | for i in range(1,popSize): 130 | x=0; 131 | for j in range(1,genomeLength): 132 | # translate from binary to decimal value 133 | x=x+chromosome[i,j]*pow(2,genomeLength-j-1) 134 | # replaces the value of x in the function f(x) 135 | y= np.fabs((x-5)/(2+np.sin(x))) 136 | # the fitness value is calculated below: 137 | # (Note that in this example is multiplied 138 | # by a scale value, e.g. 100) 139 | fitness[i]=y*100 140 | ######################################################### 141 | 142 | print("fitness = ",i," ",fitness[i]) 143 | fitness_total=fitness_total+fitness[i] 144 | fitness_average=fitness_total/N 145 | i=1; 146 | while i<=N: 147 | sum_sqr=sum_sqr+pow(fitness[i]-fitness_average,2) 148 | i=i+1 149 | variance=sum_sqr/N 150 | if variance<=1.0e-4: 151 | variance=0.0 152 | # Best chromosome selection 153 | the_best_chrom=0; 154 | fitness_max=fitness[1]; 155 | for i in range(1,popSize): 156 | if fitness[i]>=fitness_max: 157 | fitness_max=fitness[i] 158 | the_best_chrom=i 159 | best_chrom[generation]=the_best_chrom 160 | # Statistical output 161 | f = open("output.dat","a") 162 | f.write(str(generation)+" "+str(fitness_average)+"\n") 163 | f.write(" \n") 164 | f.close() 165 | print("Population size = ",popSize - 1) 166 | print("mean fitness = ",fitness_average) 167 | print("variance = ",variance," Std. deviation = ",math.sqrt(variance)) 168 | print("fitness max = ",best_chrom[generation]) 169 | print("fitness sum = ",fitness_total) 170 | 171 | ######################################################### 172 | # QUANTUM ROTATION GATE # 173 | ######################################################### 174 | def rotation(): 175 | rot=np.empty([2,2]) 176 | # Lookup table of the rotation angle 177 | for i in range(1,popSize): 178 | for j in range(1,genomeLength): 179 | if fitness[i]=fitness_max: 158 | fitness_max=fitness[i] 159 | the_best_chrom=i 160 | best_chrom[generation]=the_best_chrom 161 | # Statistical output 162 | f = open("output.dat", "a") 163 | f.write(str(generation)+" "+str(fitness_average)+"\n") 164 | f.write(" \n") 165 | f.close() 166 | print("Population size = ", popSize - 1) 167 | print("mean fitness = ",fitness_average) 168 | print("variance = ",variance," Std. deviation = ",math.sqrt(variance)) 169 | print("fitness max = ",best_chrom[generation]) 170 | print("fitness sum = ",fitness_total) 171 | 172 | ######################################################### 173 | # QUANTUM ROTATION GATE # 174 | ######################################################### 175 | def rotation(): 176 | rot =np.empty([2,2]) 177 | # Lookup table of the rotation angle 178 | for i in range(1,popSize): 179 | for j in range(1,genomeLength): 180 | if fitness[i]