首先我想说的是,我知道种子的真随机性以及如何根据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});
}
}
答案 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.Vertices
和graph.Nodes
的引用,如果有Solution
修改了集合中的一个项目,则修改所有解决方案。
要解决此问题,您需要对这两个列表进行深层复制。您没有显示Vertex
或Node
是什么,但是如果他们只是正在做的课
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;
}
}