Error : Unable to use a value of type optim.problemdef.OptimizationVariable as an index.
Show older comments
Hello !
I am working on a problem-based optimization task where I need to assign 4 subtasks to 4 different nodes. My approach involves defining an optimization variable as a vector with integer elements ranging from 1 to 4, each representing the node assigned to a subtask.
Here's a snippet of my current setup:
numSubtasks = 4;
numNodes = 4;
taskAssignmentVector = optimvar('taskAssignmentVector', numSubtasks, 'Type', 'integer', 'LowerBound', 1, 'UpperBound', numSubtasks);
My goal is to reshape this vector into a 4x4 binary assignment matrix within the optimization framework. Each row of this matrix should correspond to a subtask, and each column to a node, with '1' indicating the assignment.
I attempted to implement this by creating a function to generate the assignment matrix based on the vector, but I'm facing challenges in using the optimization variable as an index, leading to errors.
AssignedMatrix = zeros(numSubtasks, numNodes);
for s = 1:numSubtasks
nodeAssigned = taskAssignmentVector(s); % Node assigned for each subtask
AssignedMatrix(s, nodeAssigned) = 1;
end
Could you please advise on the best approach to reshape this vector into a matrix form within the problem-based optimization framework? I am looking for a way to link the task assignments in the vector with a binary matrix that I can use in my objective function and constraints.
Thank you for your assistance!
Answers (1)
It sounds like the better approach would be to have the 4x4 binary matrix AssignedMatrix be the fundamental unknown optimization variable.
AssignedMatrix = optimvar('AssignedMatrix', [4,4], 'Type', 'integer', 'LowerBound', 0, 'UpperBound', 0);
Once you've done so, the taskAssignmentVector is easily expressed as a linear expression of the AssignedMatrix:
prob=optimproblem;
prob.Constraints.OneToOne1=sum(AssignedMatrix,1)==1;
prob.Constraints.OneToOne2=sum(AssignedMatrix,2)==1;
taskAssignmentVector=AssignedMatrix*(1:4)';
69 Comments
Maria
on 7 Dec 2023
i want to ask if should i use AssignmentMatrix in my objective function then what is the utility of taskAssignmentVector .
You can still use taskAssignmentVector in your objective function and constraints, if it is more directly useful than AssignmentMatrix. It is simply that you will be using it as an OptimizationExpression rather than an OptimizationVariable.
Maria
on 7 Dec 2023
Matt J
on 7 Dec 2023
Yes, you can.
Maria
on 7 Dec 2023
Matt J
on 7 Dec 2023
function satisfactionRate = objectiveFunction(assignmentMatrix, QoS_values)
taskAssignmentVector=AssignedMatrix*(1:4)';
maxTime = calculateMaxOffloadingTime(taskAssignmentVector);
satisfactionRate = (maxTime <= QoS_values); % 1 if constraint is satisfied, 0 otherwise
end
If you are invoking nonlinear functions in your objective and constraints, then you need to be using fcn2optimexpr. I believe we had a leisurely discussion about that here,
Convert your function to an optimization expression if it has optimization variables (like assignmentMatrix) as inputs:
Maria
on 8 Dec 2023
It would help if you provided a complete piece of code that we can all run and study, even if it contains a fake, simplified version of low-level routines like calculateOffloadingTime() etc...
(In fact, it would be better if those could be simplified).
Torsten
on 8 Dec 2023
It's necessary to know how "assignmentMatrix" is used in the function "calculateOffloadingTime". From the error message, it can not even be concluded that "assignmentMatrix" is the reason for the error you encounter.
And where do you get all the input parameters to "calculateOffloadingTime" from ? Since you don't pass them to "calculateMaxOffloadingTime", "calculateMaxOffloadingTime" must be a nested function. Is this the case in your code ?
Maria
on 9 Dec 2023
Matt J
on 9 Dec 2023
But the function expecting this matrix requires exactly one node per task for its calculations.
Modify that function, so that if the requirement is not satisfied, the function bails out with an appropriate value.
Matt J
on 9 Dec 2023
My main issue is ensuring that the 'assignmentMatrix' only takes one value (either 0 or 1) in each position at any given time. Specifically, I need each task (row in the matrix) to be assigned to exactly one node (column in the matrix) .
Yes, you told us that, but I'm telling you you need to change that. Wrap your functions, if need be, with an if statement or an outer function that tests the 1 node-per-task constraint. If it is not satisfied, bail out of the routine with a value of inf.
Torsten
on 9 Dec 2023
My main issue is ensuring that the 'assignmentMatrix' only takes one value (either 0 or 1) in each position at any given time. Specifically, I need each task (row in the matrix) to be assigned to exactly one node (column in the matrix) .
If I understand you correctly, you start with a feasible assignment matrix, define its entries as integers bounded by 0 and 1 and impose the constraint that all the rows sum to 1, but you still get infeasible assignment matrices during the solution process ?
Matt J
on 9 Dec 2023
but you still get infeasible assignment matrices during the solution process ?
That's not surprising. With most of the solvers, linear equality constraints (except for bounds) are not satisfied at all iterations.
Maria
on 10 Dec 2023
Matt J
on 10 Dec 2023
Your ceq is in fact a linear constraint, and should be implemented using the Aeq,beq input arguments. The problems you describe might diminish if you do so.
[bestChromosome, bestFitness, exitflag, output] = ga(@myFitnessFunction, numGenes, [], [], [], [], lb, ub, @nonlcon, options);
It's strange that you don't call "ga" with an intcon array since your assignmentMatrix variables are integers.
Maria
on 11 Dec 2023
Torsten
on 11 Dec 2023
The variable positions in the big vector of unknowns where the variables of the assignmentMatrix are located have to be reported to "ga" in the array "intcon" (2nd last input array in the call to "ga").
Further at the positions where the variables for the assignmentMatrix are located, the vectors lb and ub for the lower and upper bounds on the variables have to be set to 0 and 1, respectively.
Maria
on 11 Dec 2023
Torsten
on 11 Dec 2023
Sorry, but I won't dive into your code to search for technical errors and/or errors in terms of the problem background.
The above changes (use of "intcon" and defining "lb" and "ub" appropriately) should be easy to implement and are necessary to work with assignmentMatrix as a binary matrix. If the code does not work as expected thereafter, please tell us the error message or an explicit description of the problem you encounter.
Maria
on 11 Dec 2023
Torsten
on 12 Dec 2023
Is it really necessary to use "ga" to solve your problem ? I remember from your former questions that it was possible to use "intlinprog" for a solution. Is it impossible to handle your inequality constraint(s) differently ?
Maria
on 12 Dec 2023
Torsten
on 12 Dec 2023
There are some unmotivated lines of code outside functions in your m-file "calculateOffloadingTime_Test.m".
required_cycles = randi([min_value, max_value], num_vehicles, N);
completion_time = t_completion_dep;
uplink_time_up = Queue_times + New_uplink_time;
completion_time_up = t_completion_dep_updated + t_completion_indep_updated;
Offloading_time_subtask = Downlink_time + completion_time;
Total_energy_consumption = squeeze(sum(sum(Energy_Total_UAV, 1, 'omitnan'), 3, 'omitnan'));
% Total energy consumed by every UAV
E_totale = sum(Total_energy_consumption) + Total_HAPS_energy_consumption ;
are not part of functions and appear somewhere in between. Could you make the necessary changes so that the code is correct and can be executed ?
Maria
on 12 Dec 2023
Matt J
on 12 Dec 2023
So implementing the equality constraints for the elements of "assignmentMatrix" in Aeq and beq as you suggested then allows using the intcon array for them in the call to "ga" ?
In recent Matlab, yes. In older versions, no equality constraints are supported, even linear ones, when intcon is used. The posting did not specify the Matlab release we are talking about, so I don't know what would be applicable here.
Maria
on 12 Dec 2023
OK, well regardless, Torsten is right that you should formulate this with intlinprog if you can and, judging by the code output in your first comment, it looks like it can be. ga may make it easy for you to express your constraints with flexibility and comfort, but as you've seen, ga is a much less efficient and reliable solver than intlinprog, when the latter applies.
Maria
on 12 Dec 2023
If you include your optimization model and we are able to understand the essence of it without too much effort and you explain where you see problems using "intlinprog", we might be able to comment.
See it as if you make a power point presentation of your work (I guess this point will soon be reached also for you). The audience doesn't want to be bored by details, but only wants to digest the essence of the model and the problems you encounter.
Maria
on 14 Dec 2023
Matt J
on 14 Dec 2023
If you are trying to maximize totalSatisfaction, you would need to have,
fitness = -totalSatisfaction;
Maria
on 14 Dec 2023
I would recommend an alternative objective function. It is only an approximation of the original, but it is more continuous and therefore, I predict, easier to optimize.
function fitness = myFitnessFunction(x)
%reshape
assignmentMatrix = reshape(x, [numSubtasks, numNodes, num_vehicles]);
assignmentMatrix = permute(assignmentMatrix, [2, 1, 3]);
% Loop through each vehicle
[Offloading_time_subtask,E_totale] = calculateOffloadingTime(...);
maxOffloadingTimes=max(Offloading_time_subtask,[],[1,2]);
fitness= sum( max( QoS_values(:) - maxOffloadingTimes(:), 0) );
end
Maria
on 14 Dec 2023
Matt J
on 14 Dec 2023
The output is showing a 'Best' value that seems to represent the penalty rather than the fitness.
If the optimal fitness is zero, that would make sense!
Maria
on 14 Dec 2023
Matt J
on 14 Dec 2023
Well, you could write your own OutputFcn or PlotFcn to suit the display to your liking.
Torsten
on 14 Dec 2023
Or you can compute it after you got the results from "ga".
Maria
on 14 Dec 2023
Torsten
on 14 Dec 2023
I don't know how "ga" works - so I can't give advice here.
Does the solution returned satisfy the constraints ? Is it improved in comparison to your initial guess (if you supplied any) ?
Maria
on 15 Dec 2023
I meant the solutions you got in general. Does the solution returned satisfy the constraints ? Is it improved in comparison to your initial guess (if you supplied any) ?
Do you start ga with a feasible solution ? Or is it not possible in ga to supply initial values for the solution vector ?
Maria
on 15 Dec 2023
Matt J
on 15 Dec 2023
I, for one, do not understand what the "Log Absolute Change" plot is plotting. It would be easier to understand if we could just see the Best Fitness value plotted from one generation to the next.
Matt J
on 15 Dec 2023
Then I don't know why you think the fitness function remains the same. The plot shows improvement at every step.
Maria
on 15 Dec 2023
Matt J
on 15 Dec 2023
But we changed your objective function. It no longer has that property.
Torsten
on 15 Dec 2023
I don't see why the fitness value returned by
fitness= sum( max( QoS_values(:) - maxOffloadingTimes(:), 0) );
is normalized between 0 and 1.
The totalSatisfaction value was, I think.
Matt J
on 15 Dec 2023
But, you could write a PlotFcn that plots both the original fitness function and my version together, so you can see how well they correlate...
Maria
on 20 Dec 2023
Matt J
on 20 Dec 2023
Does the cost function decrease at all?
Maria
on 20 Dec 2023
Matt J
on 20 Dec 2023
Then, if the cost function has improved, it cannot be correct to say " the solutions from ILP are inferior to this initial assignment".
Maria
on 20 Dec 2023
Matt J
on 20 Dec 2023
I'll ask again, did the cost function decrease? If so, it improved.
Matt J
on 20 Dec 2023
So, when you say it didn't improve, you're talking about something else besides the minimization.
Maria
on 20 Dec 2023
Matt J
on 20 Dec 2023
Two remarks,
(1) You are not using my alternative objective function. I recommended that function because it is continuous and might be easier to optimize.
(2) Your call to solve() does not specify an initialAssignment as an initial point. Therefore, the optimization does not know what it is supposed to try to improve upon.
Categories
Find more on Surrogate Optimization in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


