Whow, das hat mir schonmal sehr viel weiter geholfen.
Ich speicher mir jetzt eine Datei im "CPLEX LP Format" um dann mit der glpsol.exe die Lösung zu berechnen.
Die zu optimierenden Werte hab ich jetzt Ny/x genannt, wobei y die Zeile (=Person) und x die Spalte (=Disziplin) ist. Die Variablen können jeweils 1 (=dabei) oder 0 (=nicht dabei) haben.
So sieht das speichern dann in Delphi aus:
Delphi-Quellcode:
procedure SaveLP(filename: String;RowCount,ColCount:Integer);
var
sList: TStringList;
s:String;
Row: Integer;
Col: Integer;
begin
sList:=TStringList.Create;
//Berechnung der Zeit
sList.Add('Minimize');
for Row := 0 to RowCount - 1 do
begin
if Row>0 then
s:=' + '
else
s:='value: ';
for Col := 0 to ColCount - 1 do
s:=s+' '+TimeToSecStr(LPList[Row][Col])+' N'+Inttostr(Row)+'/'+Inttostr(Col)+' +';
sList.Add(Copy(s,1,length(s)-1));
end;
sList.Add('subject to');
//Anzahl Starts pro Disziplin
for Col := 0 to ColCount - 1 do
begin
s:='ns'+Inttostr(col)+': ';
for Row := 0 to RowCount - 1 do
begin
s:=s+' N'+Inttostr(Row)+'/'+Inttostr(Col)+' +'
end;
s:=Copy(s,1,length(s)-1);
s:=s+' = '+Inttostr(RowList.HeaderRow.NumStarts[Col]);
sList.Add(s);
end;
//Starts pro Person
for row := 0 to RowCount - 1 do
begin
s:='np'+Inttostr(row)+': ';
for col := 0 to ColCount - 1 do
begin
s:=s+' N'+Inttostr(Row)+'/'+Inttostr(Col)+' +';
end;
s:=Copy(s,1,length(s)-1);
s:=s+' <='+Inttostr(RowList.Settings.FNumPersonStarts);
sList.Add(s);
end;
sList.Add('Bounds');
for row := 0 to RowCount - 1 do
for col := 0 to ColCount - 1 do
sList.Add(' N'+Inttostr(Row)+'/'+Inttostr(Col)+' <=1');
sList.Add('Integer');
for row := 0 to RowCount - 1 do
for col := 0 to ColCount - 1 do
sList.Add(' N'+Inttostr(Row)+'/'+Inttostr(Col));
sList.SaveToFile(filename);
sList.Free;
end;
Falls sich irgendwer den Code aufmerksam (naja, Kommentare lesen reicht eigentlich) durchgelesen hat, wird merken, dass die Beschränkung auf die Gesamtzahl noch fehlt, was auch noch mein Problem ist.
Bei dem Format kann man ja nur Faktor * Variable + nächster Faktor * ... rechnen, womit sich das meines Wissens nicht machen lässt.
Hat irgendwer nen Tipp?
Jakob