* Bug #13420 fixed - mutation_ga_binary did not calculate properly multiple mutations. 91/14591/5
Michael BAUDIN [Fri, 30 May 2014 10:30:10 +0000 (12:30 +0200)]
Change-Id: I8d9e973fbf4dfda7b5f277b06a3c0921bd60c414

scilab/CHANGES_5.5.X
scilab/modules/genetic_algorithms/macros/mutation_ga_binary.sci
scilab/modules/genetic_algorithms/tests/nonreg_tests/bug_13420.dia.ref [new file with mode: 0644]
scilab/modules/genetic_algorithms/tests/nonreg_tests/bug_13420.tst [new file with mode: 0644]

index 7a9dfc3..2379659 100644 (file)
@@ -115,6 +115,8 @@ Scilab Bug Fixes
 * Bug #13418 fixed - Help page for crossover_ga_binary was unclear.
                      Also added mix to check the crossover positions.
 
+* Bug #13420 fixed - mutation_ga_binary did not calculate properly multiple mutations.
+
 * Bug #13424 fixed - crossover_ga_binary algorithm was not the classical point crossover one.
                      Also fixed the usage of binary length.
 
index 333c94e..1f6a927 100644 (file)
@@ -1,4 +1,6 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) Scilab Enterprises - 2014 - Pierre-Aime Agnel
+// Copyright (C) 2014 - Michael Baudin <michael.baudin@contrib.scilab.org>
 // Copyright (C) 2008 - Yann COLLETTE <yann.collette@renault.com>
 //
 // This file must be used under the terms of the CeCILL.
@@ -7,35 +9,30 @@
 // are also available at
 // http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
 
-function Mut_Indiv = mutation_ga_binary(Indiv,param)
-    if ~isdef("param","local") then
+function [Mut_Indiv, pos] = mutation_ga_binary(Indiv, param)
+    if ~isdef("param", "local") then
         param = [];
     end
     // We deal with some parameters to take into account the boundary of the domain and the neighborhood size
-    [BinLen,err]     = get_param(param,"binary_length",8);
-    [MultiMut,err]   = get_param(param,"multi_mut",%F);
-    [MultiMutNb,err] = get_param(param,"multi_mut_nb",2);
-
-    if ~MultiMut then
-        pos = ceil((length(Indiv)-1)*grand(1,1,"def"))+1;
-        Mut_Indiv = Indiv;
-        if part(Indiv,pos)=="0" then
-            Mut_Indiv = strcat([part(Indiv,1:pos-1) "1" part(Indiv,pos+1:length(Indiv))]);
-        end
-        if part(Indiv,pos)=="1" then
-            Mut_Indiv = strcat([part(Indiv,1:pos-1) "0" part(Indiv,pos+1:length(Indiv))]);
-        end
+    [BinLen, err]     = get_param(param, "binary_length", 8);
+    [MultiMut, err]   = get_param(param, "multi_mut", %F);
+    if MultiMut
+        [MultiMutNb, err] = get_param(param, "multi_mut_nb", 2);
     else
-        pos = ceil((length(Indiv)-1)*grand(MultiMutNb,1,"def"))+1;
-        pos = -unique(gsort(-pos));
-        Mut_Indiv = Indiv;
-        for i=1:length(pos)
-            if part(Mut_Indiv,pos(i))=="0" then
-                Mut_Indiv = strcat([part(Mut_Indiv,1:pos(i)-1) "1" part(Mut_Indiv,pos(i)+1:length(Mut_Indiv))]);
-            end
-            if part(Mut_Indiv,pos(i))=="1" then
-                Mut_Indiv = strcat([part(Mut_Indiv,1:pos(i)-1) "0" part(Mut_Indiv,pos(i)+1:length(Mut_Indiv))]);
-            end
+        MultiMutNb = 1;
+    end
+
+    dim = length(Indiv);
+    pos = grand(1, MultiMutNb, "uin", 1, dim);
+    pos = unique(pos);
+    Mut_Indiv = Indiv;
+    for i = 1:size(pos, '*');
+        Mut_Indiv = [part(Mut_Indiv, 1:pos(i) - 1), part(Mut_Indiv, pos(i)), part(Mut_Indiv, pos(i) + 1:dim)];
+        if Mut_Indiv(2) == "0"
+            Mut_Indiv(2) = "1";
+        else
+            Mut_Indiv(2) = "0";
         end
+        Mut_Indiv = strcat(Mut_Indiv);
     end
 endfunction
diff --git a/scilab/modules/genetic_algorithms/tests/nonreg_tests/bug_13420.dia.ref b/scilab/modules/genetic_algorithms/tests/nonreg_tests/bug_13420.dia.ref
new file mode 100644 (file)
index 0000000..734d20e
--- /dev/null
@@ -0,0 +1,26 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2014 - Scilab Enterprises - Pierre-Aime Agnel
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- Non-regression test for bug  -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/13420
+//
+// <-- Short Description -->
+// mutation_ga_binary did not properly write mutliple mutations
+//
+// <-- CLI SHELL MODE -->
+param = init_param("binary_length", 8, "multi_mut", %t, "multi_mut_nb", 6);
+for i = 1:100
+    A = "11100011";
+    [A_mut, pos] = mutation_ga_binary(A, param);
+    A = strsplit(A);
+    A_mut = strsplit(A_mut);
+    tst_mut = A(pos) <> A_mut(pos);
+    tst_notmut = A(setdiff(1:8, pos)) == A_mut(setdiff(1:8, pos));
+    assert_checktrue(and(tst_mut));
+    assert_checktrue(and(tst_notmut));
+end
diff --git a/scilab/modules/genetic_algorithms/tests/nonreg_tests/bug_13420.tst b/scilab/modules/genetic_algorithms/tests/nonreg_tests/bug_13420.tst
new file mode 100644 (file)
index 0000000..7187689
--- /dev/null
@@ -0,0 +1,31 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2014 - Scilab Enterprises - Pierre-Aime Agnel
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- Non-regression test for bug  -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/13420
+//
+// <-- Short Description -->
+// mutation_ga_binary did not properly write mutliple mutations
+//
+// <-- CLI SHELL MODE -->
+
+param = init_param("binary_length", 8, "multi_mut", %t, "multi_mut_nb", 6);
+
+for i = 1:100
+    A = "11100011";
+    [A_mut, pos] = mutation_ga_binary(A, param);
+
+    A = strsplit(A);
+    A_mut = strsplit(A_mut);
+
+    tst_mut = A(pos) <> A_mut(pos);
+    tst_notmut = A(setdiff(1:8, pos)) == A_mut(setdiff(1:8, pos));
+
+    assert_checktrue(and(tst_mut));
+    assert_checktrue(and(tst_notmut));
+end