Source code for job_shop_lib.graphs._build_disjunctive_graph
"""Module for building the disjunctive graph of a job shop instance.The disjunctive graph is created by first adding nodes representing eachoperation in the jobs, along with two special nodes: a source $S$ and a sink$T$. Each operation node is linked to the next operation in its job sequenceby **conjunctive edges**, forming a path from the source to the sink. Theseedges represent the order in which operations of a single job must beperformed.Additionally, the graph includes **disjunctive edges** between operationsthat use the same machine but belong to different jobs. These edges arebidirectional, indicating that either of the connected operations can beperformed first. The disjunctive edges thus represent the scheduling choicesavailable: the order in which operations sharing a machine can be processed.Solving the Job Shop Scheduling problem involves choosing a direction foreach disjunctive edge such that the overall processing time is minimized."""importitertoolsfromjob_shop_libimportJobShopInstancefromjob_shop_lib.graphsimportJobShopGraph,EdgeType,NodeType,Node
[docs]defbuild_disjunctive_graph(instance:JobShopInstance)->JobShopGraph:"""Builds and returns a disjunctive graph for the given job shop instance. This function creates a complete disjunctive graph from a JobShopInstance. It starts by initializing a JobShopGraph object and proceeds by adding disjunctive edges between operations using the same machine, conjunctive edges between successive operations in the same job, and finally, special source and sink nodes with their respective edges to and from all other operations. Edges have a "type" attribute indicating whether they are disjunctive or conjunctive. Args: instance (JobShopInstance): The job shop instance for which to build the graph. Returns: JobShopGraph: A JobShopGraph object representing the disjunctive graph of the job shop scheduling problem. """graph=JobShopGraph(instance)add_disjunctive_edges(graph)add_conjunctive_edges(graph)add_source_sink_nodes(graph)add_source_sink_edges(graph)returngraph
[docs]defadd_disjunctive_edges(graph:JobShopGraph)->None:"""Adds disjunctive edges to the graph."""formachineingraph.nodes_by_machine:fornode1,node2initertools.combinations(machine,2):graph.add_edge(node1,node2,type=EdgeType.DISJUNCTIVE,)graph.add_edge(node2,node1,type=EdgeType.DISJUNCTIVE,)
[docs]defadd_conjunctive_edges(graph:JobShopGraph)->None:"""Adds conjunctive edges to the graph."""forjob_operationsingraph.nodes_by_job:foriinrange(1,len(job_operations)):graph.add_edge(job_operations[i-1],job_operations[i],type=EdgeType.CONJUNCTIVE,)
[docs]defadd_source_sink_nodes(graph:JobShopGraph)->None:"""Adds source and sink nodes to the graph."""source=Node(node_type=NodeType.SOURCE)sink=Node(node_type=NodeType.SINK)graph.add_node(source)graph.add_node(sink)
[docs]defadd_source_sink_edges(graph:JobShopGraph)->None:"""Adds edges between source and sink nodes and operations."""source=graph.nodes_by_type[NodeType.SOURCE][0]sink=graph.nodes_by_type[NodeType.SINK][0]forjob_operationsingraph.nodes_by_job:graph.add_edge(source,job_operations[0],type=EdgeType.CONJUNCTIVE)graph.add_edge(job_operations[-1],sink,type=EdgeType.CONJUNCTIVE)