Làm thế nào để đưa ra một thuật toán để sắp xếp (thay đổi kích thước) các cửa sổ trên màn hình để chiếm nhiều không gian nhất có thể?


20

Tôi muốn viết một chương trình đơn giản chấp nhận một bộ cửa sổ (chiều rộng + chiều cao) và độ phân giải màn hình và đưa ra sự sắp xếp các cửa sổ đó trên màn hình sao cho các cửa sổ chiếm nhiều không gian nhất. Do đó, có thể thay đổi kích thước cửa sổ, trong khi duy trì output size >= initial sizevà tỷ lệ khung hình. Vì vậy, đối với cửa sổ , tôi muốn thuật toán trả về một tuple .tôi(x,y,wtôidth,hetôight)

Tôi tin rằng đây có thể là một biến thể của Knapsack 2D. Tôi đã thử xem qua các kết quả trên web nhưng chúng hầu hết có nhiều nền tảng (và không có triển khai) khiến tôi khó theo dõi.

Tôi ít quan tâm đến thuật toán nhanh nhất có thể, nhưng nhiều hơn về thứ gì đó thiết thực cho nhu cầu cụ thể của tôi.


1
Nếu bạn đang thay đổi kích thước cửa sổ, bạn không "duy trì kích thước ban đầu", chỉ là tỷ lệ khung hình của nó, tôi đoán vậy.
Emre

1
Bạn có thể thay đổi kích thước một cửa sổ để che màn hình, vấn đề là gì?

2
Tôi thứ hai nhận xét của Saeed. Bạn cần các ràng buộc bổ sung như kích thước tối thiểu mục tiêu tối thiểu hóa tổng số lần truy xuất nếu bạn muốn loại trừ các giải pháp tầm thường. Nota bene: nhà toán học dường như gọi ốp lát vấn đề tessellations .
Raphael

1
Có thể tốt hơn để nói, bạn muốn tối đa hóa diện tích cửa sổ có thể xem tối thiểu và tối thiểu hóa diện tích cửa sổ có thể xem tối đa, nhưng xung đột có được phép hay không? Vui lòng chỉnh sửa câu hỏi của bạn để làm cho nó không có lỗi, suy nghĩ về tuyên bố vấn đề hiện tại là không dễ dàng.

2
Wtối thiểuwWStôize(w)W

Câu trả lời:


9

Mặc dù câu hỏi của bạn không nói lên điều đó, tôi cho rằng bạn không muốn các cửa sổ trùng nhau.

Một cách tiếp cận cho vấn đề này là sử dụng một bộ giải hạn chế như Choco . Người ta chỉ cần viết ra các ràng buộc mã hóa vấn đề của bạn, điều chỉnh bộ giải để hành động theo cách thông minh, và sau đó để nó chạy. Điều này có nghĩa là tất cả những suy nghĩ bạn cần làm sẽ được dành cho việc tìm ra một cách tốt để mã hóa vấn đề, chứ không phải nghĩ ra một thuật toán và thực hiện lập trình và điều chỉnh. Đây là một câu trả lời một phần để giúp bạn bắt đầu.

Giả sử rằng kích thước màn hình bằng .xmmộtx×ymmộtx

Đối với mỗi cửa sổ, , bạn sẽ có một bộ biến và các ràng buộcx i , y i , h i , w iWtôixtôi,ytôi,htôi,wtôi

  • xtôi,ytôi,htôi,wtôi0
  • xtôi+wtôixmmộtx
  • ytôi+htôiymmộtx
  • Có lẽ cũng có một số hạn chế về kích thước tối thiểu của các cửa sổ, ví dụ: và vv.htôi100
  • Ràng buộc về khía cạnh: Nếu tỷ lệ khung hình là 3: 4, thì ràng buộc đó có thể là , trong đó là một số thuật ngữ lỗi nhỏ khác không cho phép không hoàn hảo kích thước cửa sổ, nếu không bạn sẽ hạn chế vấn đề.ε4htôi-ε3wtôi4htôi+εε

Bây giờ bạn cần phải chăm sóc chồng chéo cửa sổ. Đối với mỗi cặp cửa sổ, , trong đó , bạn sẽ tạo ra các ràng buộc như sau, điều này cho thấy không có góc nào của xuất hiện trong . Đối với , tạo ràng buộc: i j W j W i ( x , y ) { ( x j , y j ) , ( x j + w j , y j ) , ( x j , y j + h j ) , ( x j + w j , y j + h jWtôi,WjtôijWjWtôi(x,y){(xj,yj),(xj+wj,yj),(xj,yj+hj),(xj+wj,yj+hj)}

  • ¬(xtôixxtôi+wjytôiyytôi+hj) .

Các ràng buộc được chỉ định cho đến nay chỉ mô tả các cửa sổ không chồng lấp không tràn ra các cạnh của màn hình, đáp ứng một số hạn chế kích thước tối thiểu và duy trì tỷ lệ khung hình của chúng.

Để có được sự phù hợp tốt, bạn cần chỉ định một số liệu nắm bắt ý nghĩa của việc bố trí tốt. Một khả năng là giả định rằng bạn muốn giữ cho các cửa sổ có kích thước gần bằng nhau và / hoặc bạn muốn giảm thiểu "khoảng trắng". Tôi không nghĩ rằng điều này có thể được chỉ định bằng Choco, nhưng có thể với một giải pháp ràng buộc khác (người khác có thể giúp đỡ ở đây).

Choco cho phép một người tối đa hóa wrt đến một hàm mục tiêu được chỉ định dưới dạng một biến duy nhất. Dựa trên ý tưởng này, bạn có thể tối đa hóa những điều sau đây:

  • Σtôi(htôi+wtôi)

bằng cách viết một ràng buộc và nói với Choco để tối đa hóa .coSt= =Σtôi(htôi+wtôi)coSt


Điều này có vẻ đầy hứa hẹn và tôi chắc chắn sẽ chơi với Choco để xem cách thức hoạt động của nó và nhanh như thế nào.
daniel.jackson

Nhưng tại sao cụm từ đó nói chung? Tôi nghĩ rằng bạn có thể diễn đạt các ràng buộc là bất đẳng thức tuyến tính, có nghĩa là những gì bạn có là một chương trình tuyến tính vanilla.
Suresh

@Suresh: Hãy thoải mái xây dựng. Tôi không thấy ngay lập tức.
Dave Clarke

1

Tôi bắt đầu viết một nguyên mẫu cho một giải pháp vũ phu, hy vọng rằng có thể được tối ưu hóa đến mức nó sẽ thực tế.

Đầu tiên, một số định nghĩa: Đặt là tập hợp của tất cả các cửa sổ. Mỗi cửa sổ bao gồm cho tọa độ x, y và chiều rộng và chiều cao. Một cửa sổ được khởi tạo với chiều rộng và chiều cao tối thiểu.Wwxw,yw,ww,hw

Đầu vào của thuật toán là màn hình, , có chiều rộng và chiều cao và danh sách các cửa sổ.S

Nó hoạt động đại khái như vậy:

void fit(W, S, i, n, result)
    if i == n
        if S.score() < result.score()
            result = S
        return

    w = W[i]
    foreach x, y in S.coordinates()
        set w position to (x, y)
        while S.put(w) # check that w doesn't overlap with S's other windows and add it
            fit(W, S, i+1, n, result)
            S.windows.pop()
            w.grow()
        w.restoresize()

Có một vài điều cần được cải thiện:

  • S.coordinates()là rất chậm ngay bây giờ. Nó lặp lại tất cả các điểm trong S.width x S.heightvà kiểm tra xem mỗi điểm có ở một trong các cửa sổ của S không.

  • S.put()kiểm tra xem tham số của nó có trùng với phần còn lại của cửa sổ S hay không bằng cách thực hiện kiểm tra được đề cập trong câu trả lời của Dave. Có lẽ điều này có thể được cải thiện bằng cách sử dụng cây khoảng ?

  • S.score()ΣwS.wtôindowS(hwww)

  • W

Tôi hiện đang cố gắng tìm ra một cấu trúc dữ liệu phù hợp để thể hiện màn hình và các cửa sổ của nó, nó cần hỗ trợ các truy vấn này:

  • trả về một danh sách các tọa độ trong đó một cửa sổ đã cho có thể được định vị mà không bị chồng chéo với các cửa sổ khác
  • chèn cửa sổ ở vị trí x, y (đã được xác minh rằng nó không trùng nhau)
  • trả lại tất cả các cửa sổ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.