奇怪!遗传算法中,经过if(null!=bestChromo)判断后,bestChromo和上一代群体都发生了突变

EvilsBlood 2018-01-11 05:11:13
在我写遗传算法中,出现了最优个体bestChromo的适应度总是变小,找了很久的bug,对bestChromo.fit添加监视,发现在经过 if (null != bestChromo)后,bestChromo和上一代群体都发生了突变,但并不是每次经过 if (null != bestChromo)语句都会发生突变,求问是什么原因,还有没有别的因素会导致这样的现象
...全文
671 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuzuning 2018-01-12
  • 打赏
  • 举报
回复
bestChromo = (GAChromosome)m_thisGeneration[0]; m_nextGeneration.Insert(0, bestChromo); 你这摆弄的不都是同一个对象吗?
EvilsBlood 2018-01-12
  • 打赏
  • 举报
回复
好的,非常感谢,我调试试试,有问题就回来继续问,非常感谢
xuzuning 2018-01-12
  • 打赏
  • 举报
回复
使用了随机数的程序,使调试变得很困难,但你可以先固定随机数发生器的种子,从而固定住程序的流程
xuzuning 2018-01-12
  • 打赏
  • 举报
回复
引用 16 楼 weixin_40430379 的回复:
可是突变不是发生在对 bestChorom 进行了修改的时候, 看起来这个突变挺随机的,我上一次发现的突变是在if(null!=bestChromo)之后,但并不是每一次if(null!=bestChromo)都会变,删了if(null!=bestChromo)之后还是不对,
我只看到你的代码片段,当然不知道问题可能出在哪里,但是将 bestChromo 从队列中取出,加工后又当作新对象加入到队列中,这个做法肯定是不可取的 基因突变本来就是随机的,但这是业务上的事情,与编写代码本身没有直接关系
正怒月神 2018-01-12
  • 打赏
  • 举报
回复
引用 24 楼 weixin_40430379 的回复:
不是那一段代码没执行,是bestchromo这个对象的成员变量的值突然就改变了,在if(bestchromo!=null)之后, 调试起来好困难啊,循环10次可能会突然改变
那你的问题就是刚才说的,引用类型的问题。 至于你为何不能添加this.MemberwiseClone()方法,只能看你整个的class和继承类了。
EvilsBlood 2018-01-12
  • 打赏
  • 举报
回复
引用 23 楼 hanjun0612 的回复:
[quote=引用 21 楼 weixin_40430379 的回复:] 几乎不会进入else判断,我还没学多线程和单线程,我这个应该是单线程吧
既然不是多线程,那你完全可以调试查看。 我不是太理解你说的突变到底是哪一段代码没执行。[/quote] 不是那一段代码没执行,是bestchromo这个对象的成员变量的值突然就改变了,在if(bestchromo!=null)之后, 调试起来好困难啊,循环10次可能会突然改变
正怒月神 2018-01-12
  • 打赏
  • 举报
回复
引用 21 楼 weixin_40430379 的回复:
几乎不会进入else判断,我还没学多线程和单线程,我这个应该是单线程吧
既然不是多线程,那你完全可以调试查看。 我不是太理解你说的突变到底是哪一段代码没执行。
EvilsBlood 2018-01-12
  • 打赏
  • 举报
回复

还是不行呢
EvilsBlood 2018-01-12
  • 打赏
  • 举报
回复
引用 18 楼 hanjun0612 的回复:
其实,我本来以为你这个是并发的问题。 但是从头到尾,你只字未提多线程。 所以我不能确定,你指的 看起来这个突变挺随机的,我上一次发现的突变是在if(null!=bestChromo)之后,但并不是每一次if(null!=bestChromo)都会变,删了if(null!=bestChromo)之后还是不对 到底是不是指有时进入else的判断
几乎不会进入else判断,我还没学多线程和单线程,我这个应该是单线程吧
正怒月神 2018-01-12
  • 打赏
  • 举报
回复
引用 19 楼 weixin_40430379 的回复:
[quote=引用 13 楼 hanjun0612 的回复:] m_nextGeneration.Insert(0, bestChromo); 你每次新增完,然后改变bestChromo, 那么m_nextGeneration中的bestChromo都会变成当前bestChromo。这是引用类型。 在GAChromosome 类中 增加 public GAChromosome MemberwiseClone() { return (GAChromosome)this.MemberwiseClone(); } 然后 bestChromo = (GAChromosome)m_thisGeneration[0]; 改为 GAChromosome bestChromo =((GAChromosome)m_thisGeneration[0]).MemberwiseClone;
有错误 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 CS1540 无法通过“GAChromosome”类型的限定符访问受保护的成员“object.MemberwiseClone()”;限定符必须是“GA”类型(或者从该类型派生) [/quote] 方法名改一下 public GAChromosome MyClone() { return (GAChromosome)this.MemberwiseClone(); }
EvilsBlood 2018-01-12
  • 打赏
  • 举报
回复
引用 13 楼 hanjun0612 的回复:
m_nextGeneration.Insert(0, bestChromo); 你每次新增完,然后改变bestChromo, 那么m_nextGeneration中的bestChromo都会变成当前bestChromo。这是引用类型。 在GAChromosome 类中 增加 public GAChromosome MemberwiseClone() { return (GAChromosome)this.MemberwiseClone(); } 然后 bestChromo = (GAChromosome)m_thisGeneration[0]; 改为 GAChromosome bestChromo =((GAChromosome)m_thisGeneration[0]).MemberwiseClone;
有错误 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 CS1540 无法通过“GAChromosome”类型的限定符访问受保护的成员“object.MemberwiseClone()”;限定符必须是“GA”类型(或者从该类型派生)
正怒月神 2018-01-12
  • 打赏
  • 举报
回复
其实,我本来以为你这个是并发的问题。 但是从头到尾,你只字未提多线程。 所以我不能确定,你指的 看起来这个突变挺随机的,我上一次发现的突变是在if(null!=bestChromo)之后,但并不是每一次if(null!=bestChromo)都会变,删了if(null!=bestChromo)之后还是不对 到底是不是指有时进入else的判断
正怒月神 2018-01-12
  • 打赏
  • 举报
回复
引用 16 楼 weixin_40430379 的回复:
[quote=引用 9 楼 xuzuning 的回复:] 你对 bestChorom 进行了修改,那么这个修改就会表现到 m_thisGeneration 中的每一个 bestChorom 因为对象是引用传递的 下一代虽然继承了上代的属性,但仍是一个独立的个体 其实你只要将 GAChromosome 的定义,由 class 改成 struct 就可以了
可是突变不是发生在对 bestChorom 进行了修改的时候, 看起来这个突变挺随机的,我上一次发现的突变是在if(null!=bestChromo)之后,但并不是每一次if(null!=bestChromo)都会变,删了if(null!=bestChromo)之后还是不对,[/quote] 你的意思是,并不会每次都进入if(null!=bestChromo)? 那么就是进入了 else { System.Windows.Forms.MessageBox.Show("bestChrom==null"); } 是这样吗
正怒月神 2018-01-12
  • 打赏
  • 举报
回复
你运行一下就知道了
public class User
        {
            public int id { get; set; }
            public virtual string name { get; set; }
            public virtual string buyer { get; set; }
            public virtual string idArr { get; set; }
            public virtual DateTime expiredTime { get; set; }

            public User MyClone()
            {
                return (User)this.MemberwiseClone();
            }
        }

        static void Main(string[] args)
        {
            //浅拷贝
            User u = new User() { id = 1 };
            User u1 = u;
            Console.WriteLine("before:"+u.id);
            u1.id = 2;
            Console.WriteLine("after:"+u.id);

            Console.WriteLine("-------------------");

            //深拷贝
            u = new User() { id = 1 };
            User u2 = u.MyClone();
            Console.WriteLine("before:" + u.id);
            u1.id = 2;
            Console.WriteLine("after:" + u.id);
            Console.WriteLine("after:" + u1.id);

            Console.ReadLine();
        }
xuzuning 2018-01-12
  • 打赏
  • 举报
回复
只要 fit 属性不是引用类型就可以
EvilsBlood 2018-01-12
  • 打赏
  • 举报
回复
引用 9 楼 xuzuning 的回复:
你对 bestChorom 进行了修改,那么这个修改就会表现到 m_thisGeneration 中的每一个 bestChorom 因为对象是引用传递的 下一代虽然继承了上代的属性,但仍是一个独立的个体 其实你只要将 GAChromosome 的定义,由 class 改成 struct 就可以了
可是突变不是发生在对 bestChorom 进行了修改的时候, 看起来这个突变挺随机的,我上一次发现的突变是在if(null!=bestChromo)之后,但并不是每一次if(null!=bestChromo)都会变,删了if(null!=bestChromo)之后还是不对,
正怒月神 2018-01-12
  • 打赏
  • 举报
回复
m_nextGeneration.Insert(0, bestChromo); 你每次新增完,然后改变bestChromo, 那么m_nextGeneration中的bestChromo都会变成当前bestChromo。这是引用类型。 在GAChromosome 类中 增加 public GAChromosome MemberwiseClone() { return (GAChromosome)this.MemberwiseClone(); } 然后 bestChromo = (GAChromosome)m_thisGeneration[0]; 改为 GAChromosome bestChromo =((GAChromosome)m_thisGeneration[0]).MemberwiseClone;
EvilsBlood 2018-01-12
  • 打赏
  • 举报
回复
引用 8 楼 Allblus 的回复:
这是在研究啥啊?
遗传算法
EvilsBlood 2018-01-12
  • 打赏
  • 举报
回复
引用 7 楼 hanjun0612 的回复:
但并不是每次经过 if (null != bestChromo)语句都会发生突变。 你指的突变是哪一块代码
bestChromo和m_thisGeneration中的成员变量发生了突变,(bestChromo是类GAChromosome 的对象,用来存储每一代群体中的最优个体,m_thisGeneration是arraylist数组,存储GAChromosome 的对象,表示上一个群体)
EvilsBlood 2018-01-12
  • 打赏
  • 举报
回复
引用 9 楼 xuzuning 的回复:
你对 bestChorom 进行了修改,那么这个修改就会表现到 m_thisGeneration 中的每一个 bestChorom 因为对象是引用传递的 下一代虽然继承了上代的属性,但仍是一个独立的个体 其实你只要将 GAChromosome 的定义,由 class 改成 struct 就可以了
那我如果是修改了 m_thisGeneration,bestChorom也会变吗? 有没有其它办法?感觉从class改成struct比较难呃。 把 bestChromo = (GAChromosome)m_thisGeneration[0]; 改成 bestChromo.fit= (GAChromosome)m_thisGeneration[0].fit,不直接在对象之间使用等号,在成员变量之间使用等号可以吗?
加载更多回复(8)

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧