&
Đây là bitwise-AND
Các Bitwise-VÀ hành so sánh từng bit của toán hạng đầu tiên của mình vào bit tương ứng của nó toán hạng thứ hai. Nếu cả hai bit là 1, chút kết quả tương ứng được thiết lập để 1. Nếu không, tương ứng chút kết quả được thiết lập để 0.
Trong khi >>
này là các nhà điều hành phải thay đổi
Các toán tử dịch chuyển phải (>>) dịch chuyển toán hạng nhất của nó ngay bằng số bit được chỉ định bởi toán hạng thứ hai của nó.
Nói như vậy, chúng ta hãy xem biểu thức sau đây
if (((i >> j) & 1) != 1) continue;
và cố gắng tìm hiểu nó.
Ban đầu, điều này i >> j
sẽ dịch chuyển các bit của i
bởi j
vị trí.
Ví dụ, hãy để chúng tôi có nhiệm vụ sau đây:
int number = 5;
Các đại diện nhị phân của number
là:
0000 0000 0000 0000 0000 0000 0000 0101
Nếu chúng ta xác định một số nguyên mới như:
int shiftNumbersBitByOne = a >> 1;
Sau đó, biểu diễn nhị phân của shiftNumbersBitByOne
sẽ là:
0000 0000 0000 0000 0000 0000 0000 0010
Sau đó, kết quả của thao tác này và 1, chúng tôi áp dụng toán tử bitwise AND.
Chính xác nhà điều hành này là gì?
Mặc dù thực tế là định nghĩa rõ ràng, một ví dụ sẽ làm cho nó rõ ràng hơn.
Lết rằng chúng ta có những con số nhị phân a
và b
, sau đó là kết quả của a&b
như sau:
a = 0001 0100 1010 0001 1000 1010 1101 0011
b = 0010 1100 1111 0111 0011 1010 1011 0111
a & b = 0000 0100 1010 0001 0000 1010 1001 0011
Điều đó đang được nói, đi vào hoạt động này (i >> j) & 1
chúng tôi áp dụng Bitwise-VÀ hành giữa kết quả của i >> j
và biểu diễn nhị phân của 1
0000 0000 0000 0000 0000 0000 0000 0001
Khi kết quả của (i >> j) & 1
sẽ là 1?
này sẽ xảy ra khi và chỉ khi chữ số cuối cùng của i >> j
là 1.
Cập nhật
Trên chúng ta giải quyết các cách phần - Tôi không có ý tưởng làm thế nào họ làm việc. Bây giờ chúng tôi sẽ giải quyết số lý do tại sao một phần - lý do tại sao họ có mã số.
Hãy xác định vấn đề của chúng tôi, vấn đề về Knapsack. Theo wikipedia
Các bài toán xếp ba lô hay vấn đề ba lô là một vấn đề trong tổ hợp tối ưu hóa: Cho một tập các hạng mục, mỗi một khối lượng và giá trị, xác định số lượng của từng hạng mục để đưa vào một bộ sưu tập rất rằng tổng trọng lượng nhỏ hơn hoặc bằng một giới hạn nhất định và tổng giá trị càng lớn càng tốt.
Theo trên, nó là đơn giản mà
// This is the total weight limit.
public double Capacity { get; set; }
và
// This is an array with all the given items.
public Item[] Items { get; set; }
Bên cạnh đó, dựa trên mã của bạn, chúng ta có thể suy ra rằng mỗi mục có một giá trị và trọng lượng mà có thể được truy cập tương ứng là item.v
và item.w
. Tôi đề nghị bạn đổi tên này thành giá trị và trọng lượng tương ứng, để mã của bạn trở nên có ý nghĩa hơn.
Rõ ràng, điều này int size = Items.Length;
là số lượng các mặt hàng có sẵn.
Toàn bộ vấn đề về việc tại sao một phần bắt đầu ở đây:
var permutations = (long)Math.Pow(2,size);
các permutations
là gì? permutations
đại diện cho điều gì?
Trước khi chúng tôi trả lời câu hỏi này, hãy suy nghĩ về cách chúng tôi có thể đại diện cho mục nào của bộ sưu tập các mục sẽ được sử dụng trong giải pháp cuối cùng. Tôi cho rằng chúng ta có thể biểu diễn điều này với một số n-bit với điều kiện là chúng ta có n mục. Làm thế nào là có thể? Nếu mỗi bit trong số n bit tham chiếu đến một trong các mục n, thì hiển nhiên là chúng ta có thể làm như vậy. Giá trị của n- th bit sẽ là 0, nếu n- th mục sẽ không được đưa vào giải pháp cuối cùng. Trong khi giá trị của nó sẽ là 1, nếu nó sẽ được bao gồm.
Điều đó đang được nói là khá rõ ràng những gì hoán vị đại diện. Nó đại diện cho tất cả các kết hợp có thể có của các mục trong giải pháp cuối cùng. Điều này là rõ ràng, bởi vì mỗi bit có thể có 2 giá trị, hoặc là 0 hoặc 1. Cho rằng chúng ta có n-bit, số lượng các kết hợp có thể là 2^n.
Thực ra, vì lý do này thuật toán này là lực lượng vũ phu thuật toán (chúng tôi thực hiện tìm kiếm toàn diện). Chúng tôi truy cập tất cả các kết hợp có thể để tìm ra kết hợp tốt nhất. Trong vòng lặp sau:
for (int i = 0; i<permutations; i++)
{
// ...
}
bạn lặp qua tất cả các kết hợp có thể.
kết hợp Sau đó foreach, bạn lặp qua các mục bộ sưu tập:
for (int j = 0; j < size; j++)
{
// Here you check if the item in position j
// is included in the current combination.
// If it is not, you go to the next value of the loop's variable
// and you make the same check.
if(((i>>j)&1)!=1)
continue;
// The j-th item is included in the current combination.
// Hence we add it's
// value to the total value accumulator and it's weight to
// the total weight accumulator.
total += Items[j].v;
weight += Items[j].w;
}
Bây giờ nếu weight
là ít hơn so với giá trị giới hạn và tổng giá trị lớn hơn tổng giá trị tốt nhất hiện nay, chúng tôi chọn này kết hợp như hiện tại tốt nhất:
bestPosition = i;
bestValue = total;
Cuối cùng, có vòng lặp qua tất cả các kết hợp có sẵn, chúng tôi sẽ có kết hợp tốt nhất.
Sau khi đã tìm thấy kết hợp tốt nhất, chúng tôi phải lặp qua các mục để xem chúng được bao gồm trong kết hợp này.
// The include is a list that will hold the items of the best combination.
var include = new List<Item>();
// We loop through all the available items
for (int j = 0; j<size; j++)
{
// If the items is included in the best combination,
// add this item to the include list.
if (((bestPosition>>j) & 1)==1)
include.Add(Items[j]);
}
Dường như câu hỏi của bạn phù hợp hơn với trang web [Code Review] (http://codereview.stackexchange.com/) vì nó hoạt động và bạn không bị ảnh hưởng bởi nó. –
this: '((i >> j) & 1)! = 1' thực hiện chính xác chú thích trước khi nó nói: nó sẽ kiểm tra nếu bit' j'th (bắt đầu bằng 0) trong 'i' được đặt (hoặc tốt hơn không được đặt trong trường hợp này) - nó sẽ loại bỏ các bit 'j' cuối cùng trong' i' bằng cách dịch chuyển chúng * ra * và sau đó bitwise-và '&' với '..000001' và xem đây có phải là' 1' không – Carsten
Tôi có thể thêm rằng nó là * nhị phân truy cập * kỹ thuật cho generatin tất cả các kết hợp, vì vậy chúng tôi phải sử dụng hoạt động bitwise này –