2016-09-30 66 views
-1

我正在通过线性规划来制定运输问题。主要是我在网上搜索它,发现一个code which is written in Java。但是,我必须用Python编写整个东西。我将它转换成Python。我不认为自己擅长Java,但是不会用Python。我试图转换一下。一切都很好,但我不知道如何转换下面的代码片段,它处理Java的LinkedLists和Stream函数。Java,Python - 如何将Java FlatMap转换为Python LinkedList

static LinkedList<Shipment> matrixToList() { 
    return stream(matrix) 
      .flatMap(row -> stream(row)) 
      .filter(s -> s != null) 
      .collect(toCollection(LinkedList::new)); 
} 

如果您有兴趣寻找到我如何转换上面链接的Java代码,在这里你可以看到下面的Shipment类是我的(不完整)的Python代码:

import sys 

class TransportationProblem: 

    demand = list() 
    supply = list() 
    costs = list(list()) 
    matrix = list(list()) 

    def __init__(self): 
     pass 

    class Shipment: 
     costPerUnit = 0.0 
     quantity = 0.0 
     r = 0 
     c = 0 

     def __init__(self, quantity, costPerUnit, r, c): 
      self.quantity = quantity 
      self.costPerUnit = costPerUnit 
      self.r = r 
      self.c = c 

    def init(self, f_name= ""): 
     try: 
      with open(f_name) as f: 
       val = [int(x) for x in f.readline().strip().split(' ')] 
       numSources, numDestinations = val[0], val[1] 
       src = list() 
       dst = list() 

       val = [int(x) for x in f.readline().strip().split(' ')] 
       for i in range(0,numSources): 
        src.append(val[i]) 

       val = [int(x) for x in f.readline().strip().split(' ')] 
       for i in range(0, numDestinations): 
        dst.append(val[i]) 

       totalSrc = sum(src) 
       totalDst = sum(dst) 

       if totalSrc > totalDst: 
        dst.append(totalSrc - totalDst) 
       elif totalDst > totalSrc: 
        src.append(totalDst - totalSrc) 

       self.supply = src 
       self.demand = dst 

       self.costs = [[0 for j in range(len(dst))] for i in range(len(src))] 
       self.matrix = [[self.Shipment() for j in range(len(dst))] for i in range(len(src))] 

       for i in range(0,len(src)): 
        val = [int(x) for x in f.readline().strip().split(' ')] 
        for j in range(0, len(dst)): 
         self.costs[i][j] = val[j] 

       print self.costs 
     except IOError: 
      print "Error: can\'t find file or read data" 

    def northWestCornerRule(self): 
     northwest = 0 
     for r in range(0, len(self.supply)): 
      for c in range(northwest, len(self.demand)): 
       quantity = min(self.supply[r], self.demand[c]) 
       if quantity > 0: 
        self.matrix[r][c] = self.Shipment(quantity=quantity, costPerUnit=self.costs[r][c], r=r, c=c) 
        self.supply[r] = self.supply[r] - quantity 
        self.demand[c] = self.demand[c] - quantity 
        if self.supply[r] == 0: 
         northwest = c 
         break 

    def steppingStone(self): 
     maxReduction = 0 
     move = [] 
     leaving = self.Shipment() 

     self.fixDegenerateCase() 
     for r in range(0,len(self.supply)): 
      for c in range(0,len(self.demand)): 
       if self.matrix[r][c] != None: 
        pass 

       trail = self.Shipment(quantity=0, costPerUnit=self.costs[r][c], r=r, c=c) 
       path = self.geClosedPath(trail) 

       reduction = 0 
       lowestQuantity = sys.maxint 
       leavingCandidate = None 

       plus = True 
       for s in path: 
        if plus == True: 
         reduction = reduction + s.costPerUnit 
        else: 
         reduction = reduction - s.costPerUnit 
         if s.quantity < lowestQuantity: 
          leavingCandidate = s 
          lowestQuantity = s.quantity 
        plus = not plus 
       if reduction < maxReduction: 
        move = path 
        leaving = leavingCandidate 
        maxReduction = reduction 

     if move != None: 
      q = leaving.quantity 
      plus = True 
      for s in move: 
       s.quantity = s.quantity + q if plus else s.quantity - q 
       self.matrix[s.r][s.c] = None if s.quantity == 0 else s 
       plus = not plus 
      self.steppingStone() 

    def fixDegenerateCase(self): 
     pass 

    def getClosedPath(self): 
     pass 

    def matrixToList(self): 
     pass 

回答

1

我们可以将其分解成几个步骤。您从一个matrix变量开始,这是一些可迭代的,其中包含Shipment类型的迭代。

要流式传输对象意味着您要对流中的每个元素执行操作。

在流上的A map表示您将每个对象(比如说类型为A)转换为某种类型B。 A flatMap是当map产生Stream<B>时使用的特例。 flatMap可让您将这些流连接成单个流。

说每个A映射到3个对象{A1, A2} -> {{B11, B12, B13}, {B21, B22, B23}}

flatMap流将使这一一个流{A1, A2} -> {B11, B12, B13, B21, B22, B23}

在这种情况下一个matrix产生row对象流。每个row被映射到Shipment的流中,并且flatMap被用于连接它们。

最后filter被用于去除空出货量(即值为空)和collect方法被调用来的Shipment流变换为List

不流重塑这种看起来像波纹管:

static LinkedList<Shipment> matrixToList() { 
    LinkedList<Shipment> result = new LinkedList<>(); 
    for (List<Shipment> row : matrix) { 
     for (Shipment shipment : row) { 
      if (shipment != null) { 
       result.add(shipment); 
      } 
     } 
    } 
    return result; 
}