【问题标题】:GLPK output formatsGLPK 输出格式
【发布时间】:2019-02-07 09:46:58
【问题描述】:

我是 GLPK 的新手,所以如果我遗漏了一些简单的东西,我提前道歉!

我有一个大型 LP,我通过 GLPK 为能源市场建模。我正在向 GLPK 运行以下命令行来处理它:

winglpk-4.65\glpk-4.65\w64\glpsol --lp problem.lp --data ExampleDataFile.dat --output results2.txt

当我打开生成的文本文件时,我可以看到输出,这一切看起来都很合理。我有一个大问题:每条记录都分成两行,因此很难清理文件。请参阅下面的摘录:

   No.   Row name   St   Activity     Lower bound   Upper bound    Marginal
------ ------------ -- ------------- ------------- ------------- -------------
     1 c_e_SpecifiedDemand(UTOPIA_CSV_ID_1990)_
                    NS             0             0             =         < eps
     2 c_e_SpecifiedDemand(UTOPIA_CSV_ID_1991)_
                    NS             0             0             =         < eps
     3 c_e_SpecifiedDemand(UTOPIA_CSV_ID_1992)_
                    NS             0             0             =         < eps
     4 c_e_SpecifiedDemand(UTOPIA_CSV_ID_1993)_
                    NS             0             0             =         < eps
     5 c_e_SpecifiedDemand(UTOPIA_CSV_ID_1994)_
                    NS             0             0             =         < eps
     6 c_e_SpecifiedDemand(UTOPIA_CSV_ID_1995)_
                    NS             0             0             =         < eps
     7 c_e_SpecifiedDemand(UTOPIA_CSV_ID_1996)_
                    NS             0             0             =         < eps
     8 c_e_SpecifiedDemand(UTOPIA_CSV_ID_1997)_
                    NS             0             0             =         < eps
     9 c_e_SpecifiedDemand(UTOPIA_CSV_ID_1998)_
                    NS             0             0             =         < eps
    10 c_e_SpecifiedDemand(UTOPIA_CSV_ID_1999)_
                    NS             0             0             =         < eps
    11 c_e_SpecifiedDemand(UTOPIA_CSV_ID_2000)_
                    NS             0             0             =         < eps
    12 c_e_SpecifiedDemand(UTOPIA_CSV_ID_2001)_
                    NS             0             0             =         < eps
    13 c_e_SpecifiedDemand(UTOPIA_CSV_ID_2002)_
                    NS             0             0             =         < eps
    14 c_e_SpecifiedDemand(UTOPIA_CSV_ID_2003)_
                    NS             0             0             =         < eps
    15 c_e_SpecifiedDemand(UTOPIA_CSV_ID_2004)_
                    NS             0             0             =         < eps

如果有任何建议,我将不胜感激:

  • 如何将输出文本文件中的每条记录放在一行中,或者
  • 关于如何清理/后处理现有文本文件输出的想法。

我确定我在这里遗漏了一些简单的东西,但目前输出的格式非常无用!

谢谢!

【问题讨论】:

  • 您愿意进入不同的建模环境吗?例如,Python 有许多包允许您在后端运行 GLPK,但它们提供了一种指定输入和解析输出的编程方式。
  • 理查德 - 感谢您的建议。如果您认为这是最好的解决方案,绝对愿意这样做。我做过一些 Python,但肯定不是专家。如果您能指出我正确的方向/告诉我需要阅读的内容,将不胜感激!
  • 您有可以发布或链接到的简单线性程序吗?我可以转换它,并且大概,您可以从中找出其余部分的方法。
  • 我创建的 LP 恐怕相当庞大 - 70 MB。链接是kuungana-my.sharepoint.com/:u:/g/personal/…(这将在 2 月 12 日结束)。这实际上是使用 Pyomo 生成的。请随时向我指出一个更简单的示例,然后我可以将其应用于我的庞大文件!谢谢。
  • 我希望您有一个数学公式,其中包含您要解决的问题的一些特征。

标签: linear-programming glpk


【解决方案1】:

我为 GLPK 输出文件编写了一个 Python 解析器。它不漂亮而且不保存(try-catch),但它正在工作(对于纯单纯形问题)。

你可以在输出文件上调用它:

outp = GLPKOutput('myoutputfile')
print(outp)
val1 = outp.getCol('mycolvar','Activity')
val2 = outp.getRow('myrowname','Upper_bound') # row names should be defined

类如下:

class GLPKOutput:

    def __init__(self,filename):
        
        self.rows    = {}
        self.columns = {}

        self.nRows     = 0
        self.nCols     = 0
        self.nNonZeros = 0
        self.Status    = ""
        self.Objective = ""
        
        self.rowHeaders = []
        self.rowIdx     = {}
        self.rowWidth   = []
        self.Rows       = []
        self.hRows      = {}
        self.colHeaders = []
        self.colIdx     = {}
        self.colWidth   = []
        self.Cols       = []
        self.hCols      = {}
        
        self.wcols = ['Activity','Lower_bound','Upper bound','Marginal']
        
        self.readFile(filename)
                
    # split columns with weird line break
    def smartSplit(self,line,type,job):
    
        ret = []
        
        line = line.rstrip()
           
        if type == 'ROWS': 
            cols = len(self.rowHeaders)
            idx  = self.rowWidth
        else:              
            cols = len(self.colHeaders)
            idx  = self.colWidth
        
        if job == 'full':
            start = 0
            for i in range(cols):
                stop   = start+idx[i]+1
                ret.append(line[start:stop].strip())
                start  = stop
                
        elif job == 'part1':
            entries = line.split()
            ret     = entries[0:2]
        
        elif job == 'part2':        
            start = 0
            for i in range(cols):
                stop   = start+idx[i]+1
                ret.append(line[start:stop].strip())
                start  = stop
            ret = ret[2:]
        
        # print()
        # print("SMART:",job,line.strip())
        # print("   TO:",ret)
        return ret
        
    def readFile(self,filename):
        fp = open(filename,"r")
        lines = fp.readlines()
        fp.close
        
        i   = 0
        pos = "HEAD"

        while pos == 'HEAD' and i<len(lines):
            entries = lines[i].split()
            
            if len(entries)>0:            
                if   entries[0] == 'Rows:':
                    self.nRows = int(entries[1])
                elif entries[0] == 'Columns:':
                    self.nCols = int(entries[1])
                elif entries[0] == 'Non-zeros:':
                    self.nNonZeros = int(entries[1])
                elif entries[0] == 'Status:':
                    self.Status = entries[1]
                elif entries[0] == 'Objective:':
                    self.Objective = float(entries[3]) #' '.join(entries[1:])
                elif re.search('Row name',lines[i]):
                    lines[i] = lines[i].replace('Row name','Row_name')
                    lines[i] = lines[i].replace('Lower bound','Lower_bound')
                    lines[i] = lines[i].replace('Upper bound','Upper_bound')
                    entries  = lines[i].split()
                    pos = 'ROWS'
                    self.rowHeaders = entries
                else:
                    pass 
            
            i+= 1
            
        # formatting of row width
        self.rowWidth = lines[i].split()
        for k in range(len(self.rowWidth)): self.rowWidth[k] = len(self.rowWidth[k])
        # print("Row Widths:",self.rowWidth)
        i+= 1
        
        READY = False
        FOUND = False
        while pos == 'ROWS' and i<len(lines):
            
            if  re.match('^\s*[0-9]+',lines[i]): # new line
                if len(lines[i].split())>2: # no linebrak
                    entries = self.smartSplit(lines[i],pos,'full')
                    READY   = True
                else: # line break
                    entries = self.smartSplit(lines[i],pos,'part1')
                    READY   = False
                    FOUND   = True
            else:
                if FOUND and not READY: # second part of line
                    entries += self.smartSplit(lines[i],pos,'part2')
                    READY    = True
                    FOUND    = False
            
            if READY:                        
            
                READY = False
                FOUND = False
                
                # print("ROW:",entries)
                                
                if   re.match('[0-9]+',entries[0]): # valid line with solution data
                    self.Rows.append(entries)   
                    self.hRows[entries[1]] = len(self.Rows)-1                          
                else:
                    print("wrong line format ...")
                    print(entries)
                    sys.exit()                   
                    
            elif re.search('Column name',lines[i]):
                lines[i] = lines[i].replace('Column name','Column_name')
                lines[i] = lines[i].replace('Lower bound','Lower_bound')
                lines[i] = lines[i].replace('Upper bound','Upper_bound')
                entries  = lines[i].split()
                pos = 'COLS'
                self.colHeaders = entries
            else:                    
                pass #print("NOTHING: ",lines[i])
                    
            i+= 1

        # formatting of row width
        self.colWidth = lines[i].split()
        for k in range(len(self.colWidth)): self.colWidth[k] = len(self.colWidth[k])
        # print("Col Widths:",self.colWidth)
        i+= 1

        READY = False
        FOUND = False        
        while pos == 'COLS' and i<len(lines):
            
            if  re.match('^\s*[0-9]+',lines[i]): # new line
                if len(lines[i].split())>2: # no linebreak
                    entries = self.smartSplit(lines[i],pos,'full')
                    READY   = True
                else: # linebreak
                    entries = self.smartSplit(lines[i],pos,'part1')
                    READY   = False
                    FOUND   = True
            else:
                if FOUND and not READY: # second part of line
                    entries += self.smartSplit(lines[i],pos,'part2')
                    READY    = True
                    FOUND    = False

            if READY:        
                
                READY = False
                FOUND = False
                
                # print("COL:",entries)            
                
                if   re.match('[0-9]+',entries[0]): # valid line with solution data
                    self.Cols.append(entries)                            
                    self.hCols[entries[1]] = len(self.Cols)-1    
                else:
                    print("wrong line format ...")
                    print(entries)
                    sys.exit()

            elif re.search('Karush-Kuhn-Tucker',lines[i]):
                pos = 'TAIL'                  
            else:
                pass #print("NOTHING: ",lines[i])                    
                
            i+= 1

        for i,e in enumerate(self.rowHeaders): self.rowIdx[e] = i
        for i,e in enumerate(self.colHeaders): self.colIdx[e] = i
        
    def getRow(self,name,attr):
        if name in self.hRows:
            if attr in self.rowIdx:
                try:                
                    val = float(self.Rows[self.hRows[name]][self.rowIdx[attr]])
                except:
                    val = self.Rows[self.hRows[name]][self.rowIdx[attr]]
                return val
        else:
            return -1

    def getCol(self,name,attr):
        if name in self.hCols: 
            if attr in self.colIdx:
                try:
                    val = float(self.Cols[self.hCols[name]][self.colIdx[attr]])
                except:
                    val = self.Cols[self.hCols[name]][self.colIdx[attr]]
                return val
        else:
            print("key error:",name,"not known ...")
            return -1

        
    def __str__(self):

        retString  = '\n'+"="*80+'\nSOLUTION\n'
        retString += "nRows:      "+str(self.nRows)+'/'+str(len(self.Rows))+'\n'
        retString += "nCols:      "+str(self.nCols)+'/'+str(len(self.Cols))+'\n'
        retString += "nNonZeros:  "+str(self.nNonZeros)+'\n'
        retString += "Status:     "+str(self.Status)+'\n'
        retString += "Objective:  "+str(self.Objective)+'\n\n'
                
        retString += ' '.join(self.rowHeaders)+'\n'
        for r in self.Rows: retString += ' # '.join(r)+' #\n'
        
        retString += '\n'
        retString += ' '.join(self.colHeaders)+'\n'
        for c in self.Cols: retString += ' # '.join(r)+' #\n'
        
        return retString

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 2015-04-22
    • 2018-04-17
    • 2011-12-06
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多