C# 遗传算法是否能够始终生成TSP类任务的精确解?

C# 遗传算法是否能够始终生成TSP类任务的精确解?,c#,language-agnostic,genetic-algorithm,traveling-salesman,C#,Language Agnostic,Genetic Algorithm,Traveling Salesman,我试图解决一个类似TSP的问题,我在这里问过: 看来我的问题很可能是NP难的。因此,我的选择是: 尝试每一种策略的算法 产生近似解的算法 由于我的n将很小,我认为采用第一种可能性是有意义的。然而,出于各种实际和个人原因,我更愿意将我的解决方案实现为遗传算法,而不是更传统的暴力解决方案(如Pham Trung在链接中的答案) 我的理由是,像所有的启发式算法一样,遗传算法检查问题可能解决方案的子集。这恰好是哪个子集取决于给定遗传算法的特定参数 我的问题:对于GA,这必须是一个严格子集吗?或者,是

我试图解决一个类似TSP的问题,我在这里问过:

看来我的问题很可能是NP难的。因此,我的选择是:

  • 尝试每一种策略的算法
  • 产生近似解的算法
由于我的
n
将很小,我认为采用第一种可能性是有意义的。然而,出于各种实际和个人原因,我更愿意将我的解决方案实现为遗传算法,而不是更传统的暴力解决方案(如Pham Trung在链接中的答案)

我的理由是,像所有的启发式算法一样,遗传算法检查问题可能解决方案的子集。这恰好是哪个子集取决于给定遗传算法的特定参数

我的问题:对于GA,这必须是一个严格子集吗?或者,是否有可能使用这样的参数设置遗传算法,从而检查每个可能的解,从而在非多项式时间内运行

如果答案是肯定的,您可以解释我如何确定实现这一目标的GA的确切参数,这将非常有用,例如:

  • 人口规模
  • 交配方法
  • 选择方法
  • 突变法
  • 交叉法
或者,如果不可能轻松地得出一组参数,这些参数将导致GA最终检查每个解决方案,并且永远不会重复检查同一个解决方案太多次,我将把这视为否定答案


我打算用C#实现这个功能,但是对于这个问题,请不要理会语言。如果有人知道某个库已经实现了我想要的功能,我会指出这一点。

您可以使用Djikstra算法和加权节点的递归实现。例如,你可以从一个基本的最短路径算法开始,比如

static void Main()
{
    var nodes = new List<string> { "X", "A", "B", "C", "D", "E" };
    var points = new List<Matrix>
    {
        new Matrix { Origin = "X", Destination = "A", Distance = 2 },
        new Matrix { Origin = "X", Destination = "B", Distance = 12 },
        new Matrix { Origin = "X", Destination = "C", Distance = 7 },
        new Matrix { Origin = "X", Destination = "D", Distance = 19 },
        new Matrix { Origin = "X", Destination = "E", Distance = 16 },
        new Matrix { Origin = "A", Destination = "B", Distance = 10 },
        new Matrix { Origin = "A", Destination = "C", Distance = 8 },
        new Matrix { Origin = "A", Destination = "D", Distance = 15 },
        new Matrix { Origin = "A", Destination = "E", Distance = 17 },
        new Matrix { Origin = "B", Destination = "A", Distance = 10 },
        new Matrix { Origin = "B", Destination = "C", Distance = 11 },
        new Matrix { Origin = "B", Destination = "D", Distance = 18 },
        new Matrix { Origin = "B", Destination = "E", Distance = 21 },
        new Matrix { Origin = "C", Destination = "A", Distance = 8 },
        new Matrix { Origin = "C", Destination = "B", Distance = 11 },
        new Matrix { Origin = "C", Destination = "D", Distance = 7 },
        new Matrix { Origin = "C", Destination = "E", Distance = 9 },
        new Matrix { Origin = "D", Destination = "A", Distance = 15 },
        new Matrix { Origin = "D", Destination = "B", Distance = 18 },
        new Matrix { Origin = "D", Destination = "C", Distance = 7 },
        new Matrix { Origin = "D", Destination = "E", Distance = 5 },
        new Matrix { Origin = "E", Destination = "A", Distance = 17 },
        new Matrix { Origin = "E", Destination = "B", Distance = 21 },
        new Matrix { Origin = "E", Destination = "C", Distance = 9 },
        new Matrix { Origin = "E", Destination = "D", Distance = 5 }
    };

    var sequences = allocateNodes(nodes[0], 
                                  nodes.Count, 
                                  points, 
                                  new Dictionary<int, string>());        
}

static Dictionary<int, string> allocateNodes(string current, 
                                             int nodes, 
                                             List<Matrix> points, 
                                             Dictionary<int, string> sequences)
{
    if (sequences.Count == nodes) return sequences;

    var nextNode = getNextNode(current, points);

    sequences.Add(sequences.Count + 1, nextNode);

    points.RemoveAll(x => x.Origin == current);
    points.RemoveAll(x => x.Destination == current);

    return points.Count == 0 
        ? sequences 
        : allocateNodes(nextNode, nodes, points, sequences);
}

static string getNextNode(string origin, IEnumerable<Matrix> points)
{
    var destinations = points.Where(x => x.Origin == origin);
    var shortestPath = destinations.Min(x => x.Distance);
    var destination = destinations.First(x => x.Distance == shortestPath);

    return destination.Destination;
}


class Matrix
{
    public string Origin { get; set; }
    public string Destination { get; set; }
    public int Distance { get; set; }
}
static void Main()
{
var节点=新列表{“X”、“A”、“B”、“C”、“D”、“E”};
变量点=新列表
{
新矩阵{Origin=“X”,Destination=“A”,Distance=2},
新矩阵{Origin=“X”,Destination=“B”,Distance=12},
新矩阵{Origin=“X”,Destination=“C”,Distance=7},
新矩阵{Origin=“X”,Destination=“D”,Distance=19},
新矩阵{Origin=“X”,Destination=“E”,距离=16},
新矩阵{Origin=“A”,Destination=“B”,距离=10},
新矩阵{Origin=“A”,Destination=“C”,Distance=8},
新矩阵{Origin=“A”,Destination=“D”,距离=15},
新矩阵{Origin=“A”,Destination=“E”,Distance=17},
新矩阵{Origin=“B”,Destination=“A”,距离=10},
新矩阵{Origin=“B”,Destination=“C”,Distance=11},
新矩阵{Origin=“B”,Destination=“D”,距离=18},
新矩阵{Origin=“B”,Destination=“E”,距离=21},
新矩阵{Origin=“C”,Destination=“A”,Distance=8},
新矩阵{Origin=“C”,Destination=“B”,Distance=11},
新矩阵{Origin=“C”,Destination=“D”,距离=7},
新矩阵{Origin=“C”,Destination=“E”,距离=9},
新矩阵{Origin=“D”,Destination=“A”,距离=15},
新矩阵{Origin=“D”,Destination=“B”,Distance=18},
新矩阵{Origin=“D”,Destination=“C”,距离=7},
新矩阵{Origin=“D”,Destination=“E”,距离=5},
新矩阵{Origin=“E”,Destination=“A”,Distance=17},
新矩阵{Origin=“E”,Destination=“B”,Distance=21},
新矩阵{Origin=“E”,Destination=“C”,距离=9},
新矩阵{Origin=“E”,Destination=“D”,距离=5}
};
变量序列=分配节点(节点[0],
节点数,
要点,,
新字典());
}
静态字典分配节点(字符串当前,
int节点,
列出要点,
字典序列)
{
if(sequences.Count==节点)返回序列;
var nextNode=getNextNode(当前,点);
sequences.Add(sequences.Count+1,nextNode);
points.RemoveAll(x=>x.Origin==当前);
points.RemoveAll(x=>x.Destination==当前);
返回点。计数==0
?序列
:分配节点(下一个节点、节点、点、序列);
}
静态字符串getNextNode(字符串原点,IEnumerable点)
{
var目的地=点,其中(x=>x.Origin==原点);
var shortestPath=destinations.Min(x=>x.Distance);
var destination=destinations.First(x=>x.Distance==最短路径);
返回目的地。目的地;
}
类矩阵
{
公共字符串源{get;set;}
公共字符串目标{get;set;}
公共整数距离{get;set;}
}

然后展开“下一个路径”的条件,以使用矩阵中的其他属性对具有最低或最高值的节点进行优先级排序。当然,这不是一个遗传算法,但它也不是一种蛮力的方法,可能是你想考虑的事情…

< P>这是不可能的。模拟退火已被证明能够找到全局最优解,但它需要对数退火曲线和无限时间。对于遗传算法,这样的证明是不存在的。

@500;我不相信这是重复的;在略过这个问题之后,它似乎并不涉及产生最佳解决方案,而是一个遗传算法通常期望产生的“足够好”的解决方案。而且,我已经知道典型的遗传算法是如何工作的,所以我不需要这方面的帮助。我也知道,通过玩wi