图论---Hamilton圈

用lingo求解hamilton圈

hamilton圈:

包含的每个顶点的轨叫做Hamilton(哈密顿)轨;闭的Hamilton轨叫做Hamilton圈或圈;含Hamilton圈的图叫做Hamilton图。

直观地讲,Hamilton图就是从一顶点出发每顶点恰通过一次能回到出发点的那种图,即不重复地行遍所有的顶点再回到出发点。

分析:hamilton圈要每个点不重复的经过,因此要确定他,只需要确定选那几条边即可,假设有n个点的图,首先用flod算法算出任意两点的最短距离,此时可得到一个完全图。这时我们只需确定n条边即可。如果群举的话只需在 的2倍选出n条边,这时我们列出约束条件,用lingo求解:

一条边选不选我们用0-1变量标记(1表示选,0表示不选)

这时我们根据hamliton圈的特点(任意一个顶点的出度和入度都为1)列出约束条件


图论---Hamilton圈_第1张图片

此时我们列出着两个条件,但不能确定是负这两个条件一定能得到hamilton圈,我们可以举反例试试能不能推翻它,

这时发现:若一共有6个人,3个一首尾相连,即有两个圈,此时他不是hamilton圈,因此我们还要增加条件,

让他只能形成一个圈,其实一个圈和多个圈的不同就是:构成这个圈的边的数量不同,因此增加条件:

先随便写一点:

从一点k1(编号)出发,就可以确定下一个点k2,(因为出度为1),依次类推,k3,k4,....kn,k1;

xk1k2+xk2k3+xk3k4+ ......xkn-1kn+xknk1  =   n;

现在的问题是我们不知道(k1随便选),k2,k3,k4,....kn是什么,而使问题变的复杂,现在的解决方案(目前)好的方法是:
编号,假设选1号点为初始点,记为u(1)=1;与1号点相连的点假设为3,此时记u(3) = 2,那么1号点就与除三号点的其他点就不能够再相连,u(j)(j = 2,4,5,6,,,,n),此时u(j)什么不给赋值,参看下列公式:

图论---Hamilton圈_第2张图片

但用lingo求解的话1式有分段函数,若用lingo处理会出现错误或速率降低,总而言之不适合lingo求解,我们需要处理一下,而且将等号装换为不等号,因为等号的要求太高,这样能加快速度吧更适合写程序。

编号之差最小为-(n-1);

lingo程序:

model:
sets:
  city / 1.. 53/: u;
  link( city, city):
       dist,  ! 距离矩阵;
          x;
endsets   
   n = @size( city);
data:   !距离矩阵,它并不需要是对称的;
 
dist =@ole('E:\完全图.xls','DIST');//保证数据要对
!随机产生,这里可改为你要解决的问题的数据;
enddata
  !目标函数;
  min = @sum( link: dist * x);
 //link为一个集合,x为真正的变量。
  @FOR( city( K):
    !进入城市K;
    @sum( city( I)| I #ne# K: x( I, K)) = 1;
 
    !离开城市K;
    @sum( city( J)| J #ne# K: x( K, J)) = 1;
  );
 
  !保证不出现子圈;
  @for(city(I)|I #gt# 1:
    @for( city( J)| J#gt#1 #and# I #ne# J:
      u(I)-u(J)+n*x(I,J)<=n-1);
  );
  
  !限制u的范围以加速模型的求解,保证所加限制并不排除掉TSP问题的最优解;
  @for(city(I) | I #gt# 1: u(I)<=n-2 );
  !定义X为0\1变量;
  @for( link: @bin( x));
end


你可能感兴趣的:(2015数学建模)