GLPK using variables in constraints - glpk

I'm trying to write a constraint but I get this error :
Main.mod:25: operand preceding < has invalid type
Context: ...es : sum { ta in Task_Names } Time_Source [ ti , ma , ta ] <MathProg model processing error
>Exit code: 1 Time: 0.241
this is the code :
set Tasks dimen 4;
set endTimes := setof{(t,s,e,d) in Tasks}e;
set Task_Names := setof{(t,s,e,d) in Tasks}t;
set Machines dimen 2;
set Machine_Names := setof{(m,a) in Machines}m;
set Task_Machines dimen 3;
param lastTime := max{t in endTimes}(t);
set time_slots := 1..lastTime;
var Start_Time{ti in time_slots,ta in Task_Names},binary;
var Time_Source{ti in time_slots,ma in Machine_Names,ta in Task_Names},integer;
s.t. c1{ti in time_slots,ma in Machine_Names,ta in Task_Names,(ta,ma,co) in Task_Machines}:Time_Source[ti,ma,ta] = co*Start_Time[ti,ta];
s.t. c2{ti in time_slots,(t,s,e,d) in Tasks : ti>=s and ti<=e and ti<=e-d}:Start_Time[ti,t]=1;
s.t. c3{ti in time_slots,(t,s,e,d) in Tasks : ti<s or ti>e or ti>e-d}:Start_Time[ti,t]=0;
s.t. c4{ti in time_slots,ma in Machine_Names,(ma,num) in Machines: sum{ta in Task_Names} Time_Source[ti,ma,ta]<num};
solve;
display:Start_Time;
display:Time_Source;
display:Machine_Names;
display:Task_Machines;
data;
set Tasks :=
(T1,3,20,1)
(T2,3,30,5)
(T3,12,40,10);
set Machines :=
(M1,2)
(M2,3)
(M3,2)
(M4,1);
set Task_Machines :=
(T1,M1,1)
(T1,M2,1)
(T2,M1,2)
(T3,M4,5);
end;
the error is for the "C4" constraint. My question is in "c4" how can I use a variable in its conditions?
how can I solve this error?

It looks to me as if there are only two minor typos in c4 (position of }, using <= instead of <):
s.t. c4{ ti in time_slots,
ma in Machine_Names,
(ma,num) in Machines}:
sum{ta in Task_Names} Time_Source[ti,ma,ta] <= num;
I copied the whole fixed example into a in-browser MathProg editor (with included GLPK.js solver).

Related

How to count number of occurrences of a character in an array in Pascal

I have to script a pascal code that rations into calculation the frequency of a character's appearance in the code and displays it through the output mode
Input P2 changes:
Second Attempt at the coding phase
I tried revisioning the code.I added the output variable writeln('input array of characters'); & writeln('Number of Occurrences',k);, which should help me output how many times did the S character appear overall in the code, plus utilised the for & if commands to have the final values showcased based on the conditions, if the frequency is 1 then count in S, still getting errors, take a look at the Input P2 & Output P2
Input P1
function Count(t, s: String): Integer;
var
Offset, P: Integer;
begin
Result := 0;
Offset := 1;
P := PosEx(t, s, Offset);
while P > 0 do
begin
Inc(Result);
P := PosEx(t, s, P + 1);
end;
end;
Output P2
Target OS: Linux for x86-64
Compiling main.pas
main.pas(5,3) Error: Identifier not found "Result"
main.pas(7,8) Error: Identifier not found "PosEx"
main.pas(8,3) Error: Identifier not found "unsigned"
main.pas(8,12) Fatal: Syntax error, ";" expected but "identifier N" found
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
-------------------------------------------------------------------
Input P2
program p1
var S:string
i:integer
begin
writeln('input array of characters');
k:=O;
for i:=1 to length (S) do
if (S[i])='m') and (S[i+1]='a') then k:=k+1;
writeln('Number of Occurrences',k);
Readln;
end.
Output P2
Compiling main.pas
main.pas(2,1) Fatal: Syntax error, ";" expected but "VAR" found
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
The errors you see in the first block:
Identifier not found "Result"
Standard Pascal doesn't recognize the pseudovariable Result. In some Pascal implementations (like e.g. Delphi) it can be used to assign a value to the function result. The Pascal you are using needs to have the result of a function assigned to the name of the function. For example:
function Whatever(): integer;
begin
Whatever := 234;
end;
Identifier not found "PosEx"
Not all Pascal implementations include the PosEx() function. You need to use Pos() instead. But, the standard implementation of Pos() doesn't include the "search start position" that PosEx has. Therefore you need to ditch Pos() and do as you do in "Input P2", that is traverse the text character per character and count the occurances as you go.
Identifier not found "unsigned"
Seems you have removed that unknown identifier.
The error you see in the second block:
In Output P2 the error message should be clear. You are missing a semicolon where one is needed. Actually you are missing three of them.
You are also missing the line that reads user input: ReadLn(S);.
Finally, to calculate both upper and lower case characters you can use an extra string variable, say SU: string to which you assign SU := UpperCase(S) after reading user input, and then use that string to count the occurances.
I think this is more like what you want to do:
function Count(t, s: String): Integer;
var
Offset,Res, P: Integer;
begin
Res := 0
Offset := 1;
repeat
P := Pos(t, s, Offset);
if p>0 then
Inc(Res);
Offset := P+1
untl P = 0;
Count := Res;
end;
Now, if you don't have Pos, you can implement it:
Function Pos(const t,s:string; const Start:integer):Integer;
Var
LS, LT, {Length}
IxS, IxT, {Index)
R: Integer; {Result}
begin
R := 0;
{use only one of the two following lines of code}
{if your compiler has length}
LS := length(S); LT := Length(T);
{If it does not}
LS := Ord(s[0]); LT := Ord(T[0]);
if (LS <= LT) {if target is larger than search string, it's not there}
and (Start<=LT) and {same if starting position beyond size of S}
(Start+LT <-LS) then {same if search would go beyond size of S}
begin {Otherwise, start the search}
ixT := 1;
ixS := Start;
repeat
Inc(R); {or R:= R+1; if INC not available }
If (S[ixS] <> T[ixT]) then
R := 0 {they don't match, we're done}
else
begin {Move to next char}
Inc(ixS);
Inc(ixT);
end;
until (R=0) or (ixT>LT); {if search failed or end of target, done}
Pos := R;
end;

glpk issue when using a variable to limit a sumation

I am having some issues when trying to define the following constraint:
s.t. accumulative_times{i in JOBS}: actimes[i] = sum{j in PLACES,k in JOBS : j <= placing[i] } t[k,j]*time[k];
with the following definitions:
param n >=0;
set JOBS := 1..n;
set PLACES := 1..n;
param d{PLACES};
param time{JOBS};
var t{i in PLACES,j in JOBS} binary;
var delay{i in JOBS} integer;
var placing{i in JOBS} integer;
var actimes{i in JOBS} integer;
s.t. constraint1{i in PLACES} :sum{j in JOBS} t[i,j] =1;
s.t. constraint2{j in JOBS} :sum{i in PLACES} t[i,j] =1;
s.t. place_cons{i in JOBS}: placing[i] = sum{j in PLACES} j*t[j,i];
s.t. accumulative_times{i in JOBS}: actimes[i] = sum{j in PLACES,k in JOBS : j <= placing[i] } t[k,j]*time[k];
I am trying to calculate the total time a task will wait until be conclude.
Someone know what I am doin'g wrong or some other way to define this constraint?
GLPK can only solve linear problems. Therefore the coefficients of the LP cannot depend on a variable.
Instead of your integer variable placing you could use an array of binary variables that indicates job i is waiting in period j.
Or you use binaries indicating that job i is processed in period j and further non-integer variables depending on these binaries.

expected type "..." defined at ....... error in Ada

I have such a Karatsuba algorithm implementation I have written in ADA.
procedure Karatsuba (Factor_1, Factor_2 : in Number; Product : out Number) is
m : Integer;
m2 : Integer;
low1 : Number := (0,1);
high1 : Number := (0,1);
low2 : Number := (0,1);
high2 : Number := (0,1);
z0 : Index;
z1 : Index;
z2 : Index;
x : Integer;
y : Integer;
hc1 : Index;
hc2 : Index;
begin
low1 := (others => 0);
high1 := (others => 0);
low2 := (others => 0);
high2 := (others => 0);
if Factor_1'Length = 1 or Factor_2'Length = 1 then
Standard(Factor_1, Factor_2,Product);
end if;
-- calculates the size of the numbers
m := Integer'Max(Factor_1'Length, Factor_2'Length);
m2 := m / 2;
-- split the digit sequences about the middle
for Factor_1_Index in Factor_1'Range loop
x := x + 1;
if x <= m2 then
low1(Factor_1_Index) := Factor_1(Factor_1_Index);
else
high1(hc1) := Factor_1(Factor_1_Index);
hc1 := hc1 + 1;
end if;
end loop;
for Factor_2_Index in Factor_2'Range loop
y := y + 1;
if y <= m2 then
low2(Factor_2_Index) := Factor_2(Factor_2_Index);
else
high2(hc2) := Factor_2(Factor_2_Index);
hc2 := hc2 + 1;
end if;
end loop;
-- 3 calls made to numbers approximately half the size
z0 := Karatsuba(low1, low2, Product);
z1 := Karatsuba((low1 + high1), (low2 + high2), Product);
z2 := Karatsuba(high1, high2, Product);
Product := (z2*10**(2*m2))+((z1-z2-z0)*10**(m2))+(z0);
end Karatsuba;
On the last 4 lines before "end Karatsuba" line, I get the error "expected type 'Index' defined at ...". The errors I'm receiving are, respectively,
expected type "Index" defined at ....
found package or procedure name
there is no applicable operator "+" for type "Number" defined at ......
This is another class that I have assigned some variables:
package ITI8590.Natural_Number_Multiplication is
type Digit is range 0 .. 1;
type Index is new Positive;
type Number is array (Index range <>) of Digit;
for Digit'Size use 1;
procedure Standard(Factor_1, Factor_2 : in Number; Product : out Number);
procedure Karatsuba(Factor_1, Factor_2 : in Number; Product : out Number);
end ITI8590.Natural_Number_Multiplication;
Now why I get this error? I couldn't solve it, and I'm stuck in it. Could you help me?
Thanks,
Karatsuba is a procedure, so at the end instead of
z0 := Karatsuba(low1, low2, Product);
z1 := Karatsuba((low1 + high1), (low2 + high2), Product);
z2 := Karatsuba(high1, high2, Product);
it should probably read
Karatsuba(low1, low2, z0);
Karatsuba((low1 + high1), (low2 + high2), z1);
Karatsuba(high1, high2, z2);
which requires you to declare z0, z1, z2 as Number rather than Index. Note, Product is an out parameter to the procedure, so all your code achieved was to overwrite it twice with intermediate results (3 times, counting the call to Standard above).
But then you have a problem: the compiler says
yusuf.ada:25:12: unconstrained subtype not allowed (need initialization)
yusuf.ada:25:12: provide initial value or explicit array bounds
which is calling for something related to the way you have declared low1 etc:
low1 : Number := (0,1);
high1 : Number := (0,1);
low2 : Number := (0,1);
high2 : Number := (0,1);
The trouble with this approach is that you’ve now constrained the bounds of the variables: low1 is fixed to have 2 elements (set to values that you then overwrite), and can’t be expanded. I don’t know how the algorithm is supposed to work, but this seems unlikely to be right; for a start, what happens if the inputs have more than 2 digits?
One approach that might work is to use the number of digits in the input parameters:
Max_Digits : constant Positive := Factor_1’Length + Factor_2’length;
pragma Assert (Product’Length >= Max_Digits, “possible overflow”);
low1 : Number (1 .. Max_Digits) := (others => 0);
etc.
And, as ajb has commented, you’ll need to define operators +, -, *, ** between Numbers and Integers as needed, particularly in the expression (z2*10**(2*m2))+((z1-z2-z0)*10**(m2))+(z0) in the last line of the procedure.

How do you get the square root in Ada?

So I have been given an assignment to read in a file put the numbers into two matrices, multiply the matrices, and finally put the output into a .txt file.
I have never used Ada before and I figured it would be a good challenge. I am stuck in trying to determine the bounds for the two separate arrays.
This is what I currently have:
currentSpread := I;
g := Ada.Numerics.Generic_Complex_Elementary_Functions.Sqrt(I);
while J < g loop
if(I mod J = 0) THEN
if(currentSpread > ((I/J - J)/2)) THEN
currentSpread := ((I/J - J)/2);
arrayBounds := J;
end if;
end if;
J := J + 1;
end loop;
The problem I am having is with the sqrt function. I want to find the factors for the best bounds of the matrix multiplication and this was the only way that I thought to implement it.
The error I am getting is:
invalid prefix in selected component "Ada.Numerics.Generic_Complex_Elementary_Functions"
Thanks a lot for any help.
--Update
Full Code as requested:
with Ada.Text_IO;use Ada.Text_IO;
with Ada.Integer_Text_IO;
with Ada.Numerics.Generic_Complex_Elementary_Functions;
with Ada.Numerics.Generic_Elementary_Functions;
with Ada.Numerics.Complex_Elementary_Functions;
with Ada.Numerics.Generic_Complex_Types;
procedure Main is
dataFile : File_Type;
resultFile : File_Type;
value : Integer;
I : Integer := 0;
J : Integer;
currentSpread : Integer;
arrayBounds : Integer;
g : Integer;
begin
Ada.Text_IO.Open(File => dataFile, Mode => Ada.Text_IO.In_File, Name =>"C:\Users\Jeffrey\Desktop\data.txt");
while not End_Of_File(dataFile) loop
Ada.Integer_Text_IO.Get(File => dataFile, Item => value);
Ada.Integer_Text_IO.Put(Item => value);
Ada.Text_IO.New_Line;
I := I + 1;
end loop;
Ada.Integer_Text_IO.Put(I);
I := I/2;
J := 1;
currentSpread := I;
g := Ada.Numerics.Generic_Complex_Elementary_Functions.Sqrt(I);
while J < g loop
if(I mod J = 0) THEN
if(currentSpread > ((I/J - J)/2)) THEN
currentSpread := ((I/J - J)/2);
arrayBounds := J;
end if;
end if;
J := J + 1;
end loop;
declare
type newArray is array(Integer range <>, Integer range<>) of Integer;
X : Integer := J;
Y : Integer := I/J;
Arr1 : newArray(1..Y, 1..X);
Arr2 : newArray(1..X, 1..Y);
finAnswer : newArray(1..X, 1..X);
begin
for z in 1 .. X loop
for k in 1 .. Y loop
Ada.Integer_Text_IO.Get(File => dataFile, Item => value);
Arr1(z, k) := value;
end loop;
end loop;
for z in 1 .. Y loop
for k in 1 .. X loop
Ada.Integer_Text_IO.Get(File => dataFile, Item => value);
Arr2(z, k) := value;
end loop;
end loop;
for l in 1 .. X loop
for m in 1 .. Y loop
for n in 1 .. X loop
finAnswer(l, n) := finAnswer(l, n) + Arr1(l, n)* Arr2(n, m);
end loop;
end loop;
end loop;
end;
Ada.Text_IO.Close(File => dataFile);
end Main;
I am using the square root exclusively to figure out the factors of a number nothing else. How I have it set up now is it will go up to the square root and then it will take the smallest spread of the factors. I do not care about rounding errors or anything else if it isn't a perfect square it can round either way.
Thanks.
Generic_Complex_Elementary_Functions is a generic package. It cannot be used directly. That is why the compiler gives you an error on this line:
Ada.Numerics.Generic_Complex_Elementary_Functions.Sqrt(I);
To use it, you have to instantiate the generic Generic_Complex_Types with the floating-point type you want to use, and then instantiate Generic_Complex_Elementary_Functions with an instance of Generic_Complex_Types. Fortunately, you don't have to go through all that if you're willing to use the built-in type Float; the language provides Ada.Numerics.Complex_Elementary_Functions for you, that uses Float as the floating-point type, or Ada.Numerics.Long_Complex_Elementary_Functions that uses Long_Float if your compiler vendors support it.
However, I don't think you want to use Complex anything. That deals with complex numbers, and I doubt that you want to use those. Use Ada.Numerics.Elementary_Functions (or Long_Elementary_Functions), which deal with real numbers.
Finally, even this isn't going to work:
Ada.Numerics.Elementary_Functions.Sqrt(I)
if I is an integer, because the argument type needs to be a Float. You'll have to use a type conversion.
Ada.Numerics.Elementary_Functions.Sqrt(Float(I))

Maple: Why I can not plot my function which is definrd by proc?

So I created a proc that returns a value. (sqrt analog that is correct for numbers from (2.1) and up). I can evaluate it for any given number but I cannot plot it. Why and how to fix it?
code (converted to 1-d math input):
>
restart:
with(plottools):
val := 248;
sqr := proc (sqrtFrom, iterations) answer := 0; ampl := 0; number := sqrtFrom; for k to iterations do answer := 10*answer; number := sqrtFrom*10^ampl; for i from 0 while i < number do answer := answer+1; i := answer^2 end do; answer := answer-1; difr := -1; while difr < 0 do ampl := ampl+1; difr := sqrtFrom*10^ampl-100*answer^2 end do end do; return evalf(answer/10^(iterations-1)) end proc;
>
evalf(sqrt(val));
sqr(val, 10);
plot(sqr(x, 10), x = 3 .. 5);
>
You need eval quotes. Try
plot('sqr'(x,10), x = 3..5 );
The error you get is because sqr is being called prematurely with x as an argument, and it can't do that.
Alternatively, you can modify sqr itself to return unevaluated if it gets non-numeric arguments (which is how sqrt works).

Resources