Ошибка при использовании Tuple в CPLEX OPL для чтения данных из набора в кортеже - PullRequest
0 голосов
/ 24 марта 2020

У меня есть кортеж для чтения набора путей.

tuple Path {
int id;
string source;
string dest;
{string} pitblockSet;
{string} roadPoints; // not used
{string} dumpblockSet;
{string} others;
float dist;
};
{Path} Pbd= {} // a set read using into Pbd

Существует еще один кортеж blockType

tuple blockType {
    string id;
    int i;
    int j;
    int k;
 };

{blockType} PitBlocksType = ...; Это читается из Excel .. и данные выглядят так, как показано ниже

P1  1   1   2
P2  1   1   3
P3  1   1   4
P4  1   1   5
P5  1   1   6
P6  1   1   7
P7  1   1   8
P8  1   1   9
P9  1   1   10
P10 1   1   11

BlockBelow определяется следующим образом.

{blockType} BlockBelow[b1 in PitBlocksType] =
     {b | b in PitBlocksType: b1.i == b.i -1 &&
                        (b1.k  == b.k ) &&
                         (b1.j  == b.j) };

Я использую ограничения, такие как два ниже. Но я получаю ошибку. Я хочу иметь сумму BlockBelow для всех блоков в pitblockSet, как показано ниже. Но я делаю некоторую ошибку при доступе к pitblockSet в кортеже Pbd (типа Path)

forall( i in Pbd.pitblockSet,  t in TimePeriods) { 
       // blockabove exposed Pbd:
        sum(j in BlockBelow[i]) schedulePit[j.id][t] * totalVolume[j.id] <= 
        (sum(j in BlockBelow[i],r in TimePeriods : r <= t,d in DumpBlocks)(Xbdt[j.id][d][r])  
        + sum(j in BlockBelow[i],r in TimePeriods : r <= t, s in Stockpiles)(Xbst[j.id][s][r]/density[j.id])
        +sum(j in BlockBelow[i],r in TimePeriods : r <= t, m in Plants)(Xbmt[j.id][m][r]/density[j.id]))  ;      
        }        



 forall(d in Pbd.dumpblockSet, t in TimePeriods) {   
  //DumpblocksBelow
  sum( b in PitBlocks,j in OnBelowDump[d],  r in TimePeriods: r<=t)(Xbdt[b][j.id][r]*SwellFactor)
 - scheduleDump[d.id][t]* sum(j in OnBelowDump[d])(dumpVolume[j.id]) >= 0;
   }

Я получаю сообщение об ошибке: Ожидается тип кортежа, найдено {Path}.
Требуются предложения, пожалуйста о том, как получить доступ к pitblockSet или dumpblockSet в Pbd

1 Ответ

0 голосов
/ 24 марта 2020

Утверждение

forall( i in Pbd.pitblockSet,  t in TimePeriods) 

выглядит неправильно. Согласно вашему определению, Pbd - это набор путей, поэтому он не имеет свойства pitblockSet. Только элементы в этом наборе имеют это свойство.

Я не уверен, что вы пытаетесь сделать здесь. Если вы хотите, чтобы все пути пересекали определенный тип блока B, вы можете использовать:

forall (p in Pbd : `B` in p.pitblockSet)

Если вам нужен набор со всеми типами блоков, вы можете сформировать объединение по всем p.pitblockSet для всех пути.

РЕДАКТИРОВАТЬ после того, как вы дали некоторые пояснения в комментариях:

Насколько я понимаю, ваш blockType проиндексирован id. Если это так, то я предлагаю пометить это как ключ:

tuple blockType {
  key string id;
  int i;
  int j;
  int k;
}

Если вы это сделаете, то вы можете получить типы блоков и идентификаторы блоков под каждым путем следующим образом:

{blockType} BlockTypeBelowPath[p in Pbd] = union(b in p.pitblockSet) BlockBelow[<b>];
{string} BlockIDBelowPath[p in Pbd] = { b.id | b in BlockTypeBelowPath[p] };
execute {
  writeln("BlockTypeBelowPath: ", BlockTypeBelowPath);
  writeln("BlockIDBelowPath: ", BlockIDBelowPath);
}
...