2009-12-19 31 views
8

Tôi đang làm việc trên một ứng dụng mà tôi cần tự động lên lịch công việc cho các thành viên theo lịch trình luân phiên. Tôi không giỏi giải thích các quy tắc, vì vậy dưới đây là một số dữ liệu cần trợ giúp:Vấn đề về lập kế hoạch công việc

Vị trí: Chức vụ, với các quy tắc như Thứ Hai và Thứ Tư hàng tuần.
Danh mục: Một tập hợp các vị trí
Nhóm: Một nhóm vị trí khác. Không thể chỉ định các vị trí trong cùng một nhóm trong cùng một ngày
Thành viên: Người dùng được chỉ định cho các vị trí vào một ngày nhất định.

Đối với mỗi ngày trong tháng, các thành viên được chỉ định cho các vị trí (cả theo thứ tự tăng dần). Nếu một thành viên được gán cho một vị trí trong một thể loại, lần sau khi một vị trí trong cùng một danh mục xuất hiện, thành viên tiếp theo theo thứ tự bảng chữ cái (hoặc phần đầu của danh sách) được gán ví dụ.

Thành viên: M1, M2, M3, M4
Positions trong loại C1: P1, P2, P3
thành viên trong vị trí P1: M1, M2, M3, M4
thành viên trong vị trí P2: M1, M2, M3
Thành viên ở vị trí P2: M1, M3, M4

Nếu M1 được gán cho P1, nếu P2 đến tiếp theo, M2 sẽ được chỉ định. Một lớp phức tạp bổ sung được giới thiệu trong trường hợp nếu P3 đến tiếp theo, M3 sẽ được gán. Hệ thống phải theo dõi thực tế là M2 bị 'bỏ qua' và gán M2 tiếp theo nếu có, sau đó gán M4 tiếp theo hoặc chờ cho đến khi nó đến vị trí mà M2 khả dụng (điều này trở nên phức tạp hơn khi có nhiều 'bị bỏ qua ' các thành viên).

Thành viên cũng sẽ bị bỏ qua nếu anh ấy cho biết anh ấy sẽ không có mặt vào ngày đó. Hệ thống cần đặt ưu tiên vào các thành viên bị bỏ qua, bằng cách nào đó xác định chúng khi chúng xuất hiện và sau đó chuyển sang người hợp lý tiếp theo trong danh sách. Bỏ qua cũng áp dụng cho các nhóm do xung đột ngày.

Tôi đã có một giải pháp tạm thời [và lộn xộn] mà tôi không còn hiểu được nữa mặc dù tôi có nhiều nhận xét trong đó giải thích từng bước. Điểm yếu của nó là đối phó với các thành viên bị bỏ qua.

Nếu bạn định viết mã này, bạn sẽ làm thế nào? Tôi đang thực hiện điều này trong PHP nhưng mã giả cũng sẽ hoạt động.

+0

Có giờ cho các vị trí cần được xem xét không? Khi bạn nói các vị trí trong cùng một nhóm không thể được chỉ định trong cùng một ngày, bạn có nghĩa là chúng không thể được gán cho bất kỳ ai (nghĩa là chỉ một vị trí trong một nhóm có thể được điền vào một ngày nhất định) hoặc một người nào đó được chỉ định cho một vị trí trong một nhóm không thể được gán cho bất kỳ nhóm nào khác? – outis

+0

Tôi có nghĩa là ai đó có thể điền vào hai vị trí trong cùng một ngày trừ khi chúng xảy ra trong cùng một nhóm. – Zahymaka

Trả lời

6

Giải pháp của tôi: Bạn cần PriorityQueue (có sẵn trong PHP theo SplPriorityQueue). PriorityQueue cung cấp cho bạn các phần tử có mức độ ưu tiên giảm dần (được sắp xếp theo giá trị, giá trị nhỏ nhất có mức ưu tiên cao nhất).

Mỗi thành viên nhận được một giá trị được chỉ định.Giá trị này là một số ASCII với n chữ số (bạn có thể sử dụng 8 chữ số để thuận tiện), được lấp đầy với số không đến vị trí n. Sau đó, bạn thêm tên. Bạn cũng có thêm cho từng thành viên các vị trí có sẵn

Vì vậy, (n = 5):

  • giá trị M1: 99999Albert P1, P2, P3
  • giá trị M2: 99999Susi P1, P2
  • M3 giá trị : 99999Bob P1, P3

Điều này giúp dễ dàng sắp xếp thành viên theo mức độ ưu tiên và tên.

Chuẩn bị:

Ngày nắng. Bạn đang truy lục các vị trí được chỉ định và một danh mục cho một ngày nhất định. Mỗi thành viên được tải trên một danh sách dài. Mỗi thành viên không hiển thị trên công việc không được tải, nhưng được giảm giá trị của mình bằng hai trừ. Bob không có ở đây, vì vậy giá trị mới của nó là 99997Bob. Điều này có nghĩa là Bob sẽ tự động được chọn vào lần sau. Tất cả các thành viên khác nhận được giá trị của họ giảm trừ một.

Các vị trí được phân công cho một ngày cụ thể được ánh xạ (sử dụng SplObjectStorage):

P1-> M1, M2, M3, M4, vv P2-> vv

Bản đồ chỉ chứa các vị trí phải được chỉ định ngày này. Sau

Bộ lọc: Bạn phải tra cứu các nhóm và xóa bất kỳ vị trí nào trên bản đồ không thể được chỉ định trong ngày này. Mô tả nhóm của bạn hơi không rõ ràng.

Gán:

  • Bạn chọn vị trí để gán danh sách
  • Nhận các thành viên có thể điền vào vị trí
  • Remove thành viên có sẵn từ danh sách và đặt chúng vào PriorityQueue
  • Gán vị trí bằng cách trích xuất() từ PriorityQueue (gán đúng được thực hiện automaticially). Mỗi thành viên được chỉ định sẽ nhận được giá trị của nó tăng thêm một (Vì vậy, giảm và tăng mức độ ra nếu bạn đang ở đây và làm việc). Nếu bạn ở đây và không được chỉ định một vị trí vì bất kỳ lý do gì, bạn sẽ nhận được một hình phạt nhỏ. Nếu bạn không ở đây, bạn sẽ bị phạt hai.
  • Sau khi hoàn tất, hãy đặt lại các thành viên còn lại trong danh sách, xóa PQueue và tiếp tục với bài tập tiếp theo.

Hãy cẩn thận:

  • Bạn phải cẩn thận rằng luôn luôn có đủ người cho một vị trí.
+0

Tôi xếp thứ hai giải pháp xếp hàng có trọng số. Có lẽ đó là sự thiếu kiến ​​thức về PHP của tôi, nhưng tôi sẽ chỉ sử dụng một int cho ưu tiên. Sau đó, ưu tiên +1 khi chúng bị bỏ qua và ưu tiên -1 khi chúng được sử dụng. Sắp xếp hàng đợi theo thứ tự ưu tiên asc và tên asc và bạn có danh sách của bạn theo thứ tự phân công. Cuối cùng, làm việc trong danh sách trên xuống chỉ định hoặc bỏ qua mỗi công nhân cho mỗi ngày. –

+0

Tôi nghĩ rằng giải pháp concat được sử dụng vì việc triển khai php không cho phép nhiều điểm đánh dấu ưu tiên (trong trường hợp ưu tiên và tên của bạn). Tôi chắc chắn nó sẽ là tầm thường để mở rộng cho phép cho rằng mặc dù. Xem http://php.net/SplPriorityQueue. –

1

uff. tôi không theo bạn mô tả, nhưng trong tình huống tương tự tôi đã sử dụng sql để giải quyết loại vấn đề. nếu bạn đang sử dụng php tôi đoán bạn có sql có sẵn.

những gì tôi sẽ đề nghị làm là tìm cách lưu trữ thông tin này vào một tập hợp các bảng và sau đó tìm ra truy vấn sql cung cấp cho bạn câu trả lời mà bạn muốn. khá thường thì nó đơn giản hơn rất nhiều trong sql hơn là trong ngôn ngữ thủ tục. Ví dụ:

cho phần bị bỏ qua, bạn có thể có cột ghi lại thời điểm ai đó được chỉ định lần cuối và sau đó sắp xếp theo thứ tự đó (để bạn chọn người chưa được chỉ định trong một thời gian dài). cách khác, bạn có thể có số lần bị bỏ qua dưới dạng cột và thứ tự theo đó.

0

Điều tôi hiểu là có các thành viên 'm' và 'n'.

Danh mục: một nhóm vị trí - thành viên được chỉ định một vị trí trong danh mục không thể có vị trí khác?

Nhóm: nhóm vị trí - vị trí trong cùng một nhóm phải được chỉ định vào các ngày khác nhau.

Điều cuối cùng, Vị trí có danh sách các thành viên có thể điền vào.

Nhìn điều này từ quan điểm cấu trúc dữ liệu, đặt các thành viên vào danh sách được liên kết - mỗi thành viên phải có danh sách bổ sung [vị trí, ngày] mà cuối cùng họ được chỉ định. Sau đó, đối với mỗi vị trí, có một danh sách các tham chiếu đến các thành viên có thể điền vào vị trí đó. Triển khai các danh mục dưới dạng danh sách tham chiếu khác cho một vị trí theo danh mục của nó.

Bài tập thực tế: có bộ đếm ngày = 0 và lặp lại qua các vị trí. Đối với mỗi vị trí P, lặp qua các thành viên có thể điền vào nó. Một M thành viên có thể điền vào vị trí nếu:

  • Bất kỳ vị trí ông đã điền P2 không chia sẻ một loại với P.
  • Bất kỳ vị trí ông đã điền P2 với ngày = daycounter không chia sẻ một nhóm với P.

Nếu anh ta có thể điền vào vị trí, cặp [vị trí, ngày] được thêm vào thành viên và nút của thành viên được chuyển đến END của danh sách (đây là lý do tại sao tài liệu tham khảo là cần thiết - tất cả các tham chiếu vẫn hợp lệ ngay cả khi nút được di chuyển). Điều này đảm bảo rằng các thành viên 'bỏ qua' được ưu tiên cao nhất và các thành viên không đạt được được ưu tiên cao nhất tiếp theo.

Sau khi vị trí được điền, hãy chuyển đến vị trí tiếp theo. Nếu vị trí chia sẻ một nhóm với một vị trí đã được chỉ định, bỏ qua nó, lặp qua tất cả các vị trí cho đến khi bạn có thể gán nhiều vị trí nhất có thể vào ngày thứ 1. Sau đó, tăng bộ đếm ngày và lặp lại trong ngày 2. Điều này sẽ cung cấp cho bạn một bài tập tối đa (không chắc chắn về tối đa) cho tất cả các công việc.

Mẹo: khi di chuyển một thành viên vào cuối danh sách thành viên, để tránh phải duyệt qua danh sách, giữ tham chiếu đến kết thúc - cho vị trí tiếp theo, bạn cần phải bắt đầu lại từ đầu, vì vậy, không có điểm nào trải qua toàn bộ sự việc.

Các vấn đề liên quan