您如何解决旅行商问题的这种变化?

时间:2014-11-04 22:15:22

标签: algorithm traveling-salesman

不得不为工作做这件事;我给出了一个近似解决方案,因为我无法弄清楚如何攻击它。我知道它是NP难的,但我很好奇你将如何解决以下问题:

考虑到100个地点和旅行推销员,将地点划分为五组,每组20个地点。每天的行程将从同一个中心位置开始。最大限度地减少销售人员的总行程距离。

3 个答案:

答案 0 :(得分:0)

以下是两种可能的方法:

  • 选择一个Heuristic for the TSP并对其进行修改,以便它需要访问100个城市中的20个城市。然后删除这些城市并从剩余城市中选择20个,然后重复,直到您从20个中选择20个。
  • 使用启发式将图表划分为5个区域。使用Held-Karp等算法解决每个区域的TSP问题。如果您需要更好的解决方案,可以使用5个区域的边界,每次重新运行Held-Karp。

有关Held-Karp算法,请参阅Optimized TSP Algorithms。它在O(n^2 2^n)时间内找到解决方案,因此可用于大于20的输入。

答案 1 :(得分:0)

这对我来说更像是 Vehicle Routing Problem。我认为您可以使用 Capacitated Vehicle Routing Problem (CVRP) 公式来表述您的问题。

例如,给每辆车的容量为 20,并让每个客户的需求为 1。求解 CVRP 将得到一个有 5 辆车的解决方案,每辆车由 20 个客户组成。这些车辆的路线将代表您不同日子的路线。

求解小实例可以通过 Gurobi 或 Cplex 等求解器以最佳方式完成。

答案 2 :(得分:0)

起点可以是 lost baggage 中的 Model Building

/*
Lost baggage distribution
Problem 27 in Model Building by H.P. Williams edition 5
*/

using CP;

execute
{
  cp.param.timelimit=20;
}

{string} cities=...;

tuple arc
{
  string origin;
  string destination;
}

{arc} allArcs={<o,d> | ordered o,d in cities};

int traveltime[allArcs]=...;

int allowedhorizon=...;

int n=card(cities);
int airport=1;
range visits=2..n;

int timeMatrix[i in 1..n][j in 1..n]=
  ((j!=1) && (i!=j))?((i<j)
  ?traveltime[<item(cities,i-1),item(cities,j-1)>]
  :traveltime[<item(cities,j-1),item(cities,i-1)>]):0;



// sequences of visits 
dvar int x[visits] in visits;

// Is that visit just after an airport visit ?
dvar boolean starts[visits];

// Delivery time to reach that position
dvar int+ deliveryTime[visits] in 0..allowedhorizon;

// how many vans do we use ?
dvar int+ nbVansUsed; 

// max delivery time
dvar int+ maxDeliverytime;

execute
{
  cp.addKPI(nbVansUsed,"how many vans ?");
  cp.addKPI(maxDeliverytime,"max delivery time");
}

minimize staticLex(nbVansUsed,maxDeliverytime);

subject to
{
  
// KPI definitions  
  nbVansUsed==sum(i in visits) starts[i];
  
  maxDeliverytime==max(i in visits) deliveryTime[i];
    
// all cities should be visited once  
  allDifferent(x);
  
// first we start at the airport  
  starts[2]==1;
 
  // compute delivery time
  forall(i in visits) 
     (starts[i]==1) => (deliveryTime[i]==timeMatrix[1][x[i]]);
  forall(i in visits:i!=2)
     (starts[i]!=1) => (deliveryTime[i]==deliveryTime[i-1]+timeMatrix[x[i-1]][x[i]]);
  
  
  
}

execute
{
  writeln("nb vans used : ",nbVansUsed);
  writeln("max delivery time : ",maxDeliverytime);
  writeln("delivery time : ",deliveryTime);
}

/*
which gives
nb vans used : 2
max delivery time : 100
delivery time :  [35 45 57 77 87 100 20 35 45 53 58 69 84 99]
*/