Skip to content

Commit

Permalink
Wrap (time, node) in CPM so that heapq works with mixed node types
Browse files Browse the repository at this point in the history
We wrap it in a class that compares only on time so that heapq do not
care if several node types occur.
(Was an issue in examples.jsp.run_dp.run_dp_of_rcpsp)
  • Loading branch information
nhuet committed Oct 17, 2024
1 parent 70bb52a commit 24efca7
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 8 deletions.
22 changes: 17 additions & 5 deletions discrete_optimization/rcpsp/solvers/cpm.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# LICENSE file in the root directory of this source tree.

import logging
from collections.abc import Hashable
from dataclasses import dataclass
from heapq import heappop, heappush
from typing import Any

Expand Down Expand Up @@ -44,6 +46,15 @@ def __str__(self):
return str({k: getattr(self, k) for k in self.__dict__.keys()})


@dataclass
class TimedNode:
time: int
node: Hashable

def __lt__(self, other: "TimedNode"):
return self.time < other.time


class CpmRcpspSolver(RcpspSolver):
problem: RcpspProblem

Expand Down Expand Up @@ -101,10 +112,11 @@ def run_classic_cpm(self):
for n in current_pred
if n not in done_forward and current_pred[n]["nb"] == 0
}
queue = [(0, n) for n in available_activities]
queue = [TimedNode(time=0, node=n) for n in available_activities]
forward = True
while queue:
time, node = heappop(queue)
timednode = heappop(queue)
time, node = timednode.time, timednode.node
if forward and node in done_forward:
continue
elif not forward and node in done_backward:
Expand Down Expand Up @@ -138,14 +150,14 @@ def run_classic_cpm(self):
if forward:
if all(self.map_node[n]._ESD is not None for n in pred):
max_esd = max([self.map_node[n]._EFD for n in pred])
heappush(queue, (max_esd, next_node))
heappush(queue, TimedNode(time=max_esd, node=next_node))
else:
if all(self.map_node[n]._LSD is not None for n in pred):
max_esd = min([self.map_node[n]._LSD for n in pred])
heappush(queue, (-max_esd, next_node))
heappush(queue, TimedNode(time=-max_esd, node=next_node))
if node == self.sink:
forward = False
heappush(queue, (-self.map_node[node]._EFD, node))
heappush(queue, TimedNode(time=-self.map_node[node]._EFD, node=node))

critical_path = [self.sink]
cur_node = self.sink
Expand Down
4 changes: 1 addition & 3 deletions examples/jsp/run_dp.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
from discrete_optimization.generic_tools.callbacks.early_stoppers import (
NbIterationStopper,
)
from discrete_optimization.generic_tools.cp_tools import ParametersCp
from discrete_optimization.jsp.parser import get_data_available, parse_file
from discrete_optimization.jsp.problem import JobShopProblem
from discrete_optimization.jsp.solvers.cpsat import CpSatJspSolver
from discrete_optimization.jsp.solvers.dp import DpJspSolver
from discrete_optimization.jsp.utils import transform_jsp_to_rcpsp
Expand Down Expand Up @@ -118,4 +116,4 @@ def run_dp_of_rcpsp():


if __name__ == "__main__":
run_dp_jsp_ws()
run_dp_of_rcpsp()

0 comments on commit 24efca7

Please sign in to comment.