Compare commits
No commits in common. "07d3ce14e796e15e66dd40c8d8f12bf99738eec4" and "44a7d89ef957833b30537c034e628785dd8f8ea4" have entirely different histories.
07d3ce14e7
...
44a7d89ef9
3 changed files with 13 additions and 35 deletions
|
@ -75,7 +75,6 @@ def assigner_taches(root_task: Category | Task, group_count: int):
|
||||||
multiplicity[t_id] = task.nb_groups
|
multiplicity[t_id] = task.nb_groups
|
||||||
repart: list[list[TaskId]] = partition(
|
repart: list[list[TaskId]] = partition(
|
||||||
bin_count=group_count,
|
bin_count=group_count,
|
||||||
tasks=all_tasks,
|
|
||||||
costs=costs,
|
costs=costs,
|
||||||
multiplicity=multiplicity,
|
multiplicity=multiplicity,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
""" Implements Multiway number partitioning greedy algorithm """
|
""" Implements Multiway number partitioning greedy algorithm """
|
||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
import logging
|
|
||||||
from sortedcontainers import SortedList
|
from sortedcontainers import SortedList
|
||||||
from .config import Task
|
|
||||||
|
|
||||||
__all__ = ["TaskId", "partition"]
|
__all__ = ["TaskId", "partition"]
|
||||||
|
|
||||||
TaskId = t.NewType("TaskId", int)
|
TaskId = t.NewType("TaskId", int)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class PartitionException(Exception):
|
class PartitionException(Exception):
|
||||||
"""An exception occurring during partitioning"""
|
"""An exception occurring during partitioning"""
|
||||||
|
@ -40,10 +36,7 @@ class Bin:
|
||||||
|
|
||||||
|
|
||||||
def partition(
|
def partition(
|
||||||
bin_count: int,
|
bin_count: int, costs: dict[TaskId, int], multiplicity: dict[TaskId, int]
|
||||||
tasks: list[Task],
|
|
||||||
costs: dict[TaskId, int],
|
|
||||||
multiplicity: dict[TaskId, int],
|
|
||||||
) -> list[list[TaskId]]:
|
) -> list[list[TaskId]]:
|
||||||
"""Partitions the tasks, each with cost `costs[i]`, into `bin_count` bins. Each
|
"""Partitions the tasks, each with cost `costs[i]`, into `bin_count` bins. Each
|
||||||
task has multiplicity `multiplicity[i]`, copies of the same task being mutually
|
task has multiplicity `multiplicity[i]`, copies of the same task being mutually
|
||||||
|
@ -57,36 +50,22 @@ def partition(
|
||||||
ordered_tasks.sort(key=lambda x: costs[x], reverse=True)
|
ordered_tasks.sort(key=lambda x: costs[x], reverse=True)
|
||||||
|
|
||||||
for task in ordered_tasks:
|
for task in ordered_tasks:
|
||||||
possible_bins: list[int] = []
|
least_full: Bin
|
||||||
min_possible: t.Optional[int] = None
|
least_full_pos: int
|
||||||
for pos, cur_bin in enumerate(bins):
|
for pos, cur_bin in enumerate(bins):
|
||||||
if min_possible is not None and cur_bin.cost > min_possible:
|
|
||||||
break
|
|
||||||
if task not in cur_bin:
|
if task not in cur_bin:
|
||||||
if min_possible is None:
|
least_full = cur_bin
|
||||||
min_possible = cur_bin.cost
|
least_full_pos = pos
|
||||||
possible_bins.append(pos)
|
break
|
||||||
if not possible_bins:
|
else:
|
||||||
raise UnsolvableConflict(
|
raise UnsolvableConflict(
|
||||||
"Pas assez de groupes pour affecter la tâche "
|
"Pas assez de groupes pour affecter la tâche "
|
||||||
+ f"{tasks[task].qualified_name} {multiplicity[task]} fois."
|
+ f"{task} {multiplicity[task]} fois."
|
||||||
)
|
)
|
||||||
|
|
||||||
# Pick one of the groups -- maximize distance to other tasks
|
del bins[least_full_pos]
|
||||||
closest_assigned = []
|
least_full.add(task, costs[task])
|
||||||
for cur_bin_id in possible_bins:
|
bins.add(least_full)
|
||||||
cur_bin = bins[cur_bin_id]
|
|
||||||
if cur_bin.elts:
|
|
||||||
closest_assigned.append(min((abs(elt - task) for elt in cur_bin.elts)))
|
|
||||||
else:
|
|
||||||
closest_assigned.append(len(costs) + 1)
|
|
||||||
|
|
||||||
assign_to_bin_id, _ = max(enumerate(closest_assigned), key=lambda x: x[1])
|
|
||||||
assign_to_bin = bins[possible_bins[assign_to_bin_id]]
|
|
||||||
|
|
||||||
del bins[assign_to_bin_id]
|
|
||||||
assign_to_bin.add(task, costs[task])
|
|
||||||
bins.add(assign_to_bin)
|
|
||||||
|
|
||||||
out: list[list[TaskId]] = []
|
out: list[list[TaskId]] = []
|
||||||
for cur_bin in bins:
|
for cur_bin in bins:
|
||||||
|
|
|
@ -124,11 +124,11 @@ taches:
|
||||||
taches:
|
taches:
|
||||||
- nom: Nettoyer salles de bain étage
|
- nom: Nettoyer salles de bain étage
|
||||||
descr: Nettoyer les salles de bain du 1er étage du gîte principal
|
descr: Nettoyer les salles de bain du 1er étage du gîte principal
|
||||||
penible: 25
|
penible: 20
|
||||||
notes: "Remplir les seaux de produit dans la salle plonge"
|
notes: "Remplir les seaux de produit dans la salle plonge"
|
||||||
- nom: Nettoyer salles de bain RdC
|
- nom: Nettoyer salles de bain RdC
|
||||||
descr: Nettoyer les salles de bain du rez-de-chaussée du gîte principal
|
descr: Nettoyer les salles de bain du rez-de-chaussée du gîte principal
|
||||||
penible: 20
|
penible: 15
|
||||||
notes: "Remplir les seaux de produit dans la salle plonge"
|
notes: "Remplir les seaux de produit dans la salle plonge"
|
||||||
- nom: Serpillère RdC
|
- nom: Serpillère RdC
|
||||||
penible: 15
|
penible: 15
|
||||||
|
|
Loading…
Reference in a new issue