随机数不创建随机结果

时间:2016-03-08 16:49:10

标签: c# random

首先我想说的是,我知道种子的真随机性以及如何根据Environment.TickCount创建新的Random()的不同主题。 尽管如此,我无法弄清楚我的问题是什么。 我正在尝试创建一个包含100个图形的图,用于图形着色遗传算法。 每个群体由设定的边数和设定的节点数组成。每个节点都有一个索引号和一个随机的初始颜色。 那个初始颜色是我想要的随机颜色。颜色的介于1到10之间。 但是每个人口看起来都一样,相同的节点都有相同的颜色。 我可能可能错过了一些简单但我无法理解的东西。 任何帮助将不胜感激。

CreatePopulation.cs

class CreatePopulation
{

    private static Solution CreateRandomSolution(Graph graph, int colorsCount)
    {
        Solution solution = new Solution(graph, colorsCount);
        for (int node = 0; node < graph.Nodes.Count; node++)
        {
            solution.assignColor(node, Program.RandomNumber(1, 10));
        }

        return solution;
    }

    public static List<Solution> CreateRandomPopulation(Graph graph, int populationSize)
    {
        List<Solution> list = new List<Solution>();
        for (int i = 0; i < populationSize; i++)
        {
            list.Add(CreateRandomSolution(graph, 10));
        }
            return list;
    }

}

Solution.cs持有未来实施健身方法和算法所需的其他方法

  class Solution
{
    private int colorsCount;
    private List<Vertex> edges;
    private List<Node> nodes;

    private Solution(List<Vertex> edges, List<Node> nodes, int colorsCount)
    {
        this.colorsCount = colorsCount;
        this.edges = edges;
        this.nodes = nodes;
    }

    public Solution(Graph graph, int colorsCount)
    {
        edges = graph.Vertices;
        this.colorsCount = colorsCount;
        this.nodes = graph.Nodes;
    }

    public void assignColor(int index, int color)
    {
        nodes[index].color = color;
    }

}

具有主要功能的Program.cs

 class Program
{
    public static readonly Random Random = new Random();

    private static double MutationRate = 0.05;

    private static double CrossoverRate = 0.7;

    private static int Colors = 10;

    private static int GenerationCount = 100;

    private static int PopulationSize = 100;

    private static readonly object syncLock = new object();

    public static int RandomNumber(int min, int max)
    {
        lock (syncLock)
        {
            return Random.Next(min, max);
        }
    }

    static void Main(string[] args)
    {
        var graph = new Graph(@"C:\Users\Pawel\Desktop\lab1\GraphColoring-branch\bin\Debug\geom20.col");
        var initPopulation = CreatePopulation.CreateRandomPopulation(graph, PopulationSize);
        Console.ReadLine();
    }


}

Node.cs

namespace Graph
{
    class Node
    {
        public int number { get; set; }
        public int color { get; set; }

        public Node(int number)
        {
            this.number = number;
        }
        public Node() { }
    }
}

更新 改变了我在Solution.cs中创建新List的方式,但想知道它是否可以以更好的方式完成。

 public Solution(Graph graph, int colorsCount)
    {
        this.edges = graph.Vertices;
        this.colorsCount = colorsCount;
        this.nodes = new List<Node>(graph.Nodes.Count);
        for (int i = 0; i < graph.Nodes.Count; i++)
        {
            this.nodes.Add(new Node{color = graph.Nodes[i].color, number = graph.Nodes[i].number});
        }
    }

1 个答案:

答案 0 :(得分:2)

问题是,Solution个对象中的每一个都在List<Vertex>List<Node>的同一个实例中运行。所以Random工作正常,真正的问题是你在生成下一个解决方案时会覆盖以前解决方案的值。

我看到你使用的唯一构造函数是

Solution solution = new Solution(graph, colorsCount);

在那里你做

public Solution(Graph graph, int colorsCount)
{
    edges = graph.Vertices;
    this.colorsCount = colorsCount;
    this.nodes = graph.Nodes;
}

这只是复制graph.Verticesgraph.Nodes的引用,如果有Solution修改了集合中的一个项目,则修改所有解决方案。

要解决此问题,您需要对这两个列表进行深层复制。您没有显示VertexNode是什么,但是如果他们只是正在做的课

public Solution(Graph graph, int colorsCount)
{
    edges = graph.Vertices.ToList();
    this.colorsCount = colorsCount;
    this.nodes = graph.Nodes.ToList();
}

是不够的,因为它只会创建列表的浅表副本,您对nodes[index].color = color;的调用仍会修改所有其他图形中的节点,因为尽管列表现在是单独的引用,但是列表仍然在Solution个对象之间共享。你需要类似的东西

class Solution
{
    private int colorsCount;
    private List<Vertex> edges;
    private List<Node> nodes;

    private Solution(List<Vertex> edges, List<Node> nodes, int colorsCount)
    {
        this.colorsCount = colorsCount;
        this.edges = edges;
        this.nodes = nodes.Select(old => old.Clone()).ToList();
    }

    public Solution(Graph graph, int colorsCount)
    {
        edges = graph.Vertices;
        this.colorsCount = colorsCount;
        this.nodes = graph.Nodes.Select(old => old.Clone()).ToList();
    }

    public void assignColor(int index, int color)
    {
        nodes[index].color = color;
    }

}


class Node
{
    public int number { get; set; }
    public int color { get; set; }

    public Node(int number)
    {
        this.number = number;
    }
    public Node() { }

    public Node Clone()
    {
        var newNode = new Node();
        newNode.number = this.number;
        newNode.color = this.color;
        return newNode;
    }
}