views:

106

answers:

3

I have a list of devices and a bitmask of channels they are on (channels are numbered 0..3). There can be up to 256 devices.

For example:

Device1: 1 0 0 1 (on channels 0, 3)
Device2: 0 1 1 0 (on channels 1, 2)
Device3: 1 1 0 0 (on channels 2, 3)

I need to find a bitmask of channels which will result in the message to be received by all devices with a fewest possible unnecessary messages.

Correct result bitmasks for example data are 1 0 1 0 (channel 1 delivers to Device2 and channel 3 to Device1 and Device3) and 0 1 0 1 (channel 0 delivers to Device1 and channel 2 to Device2 and Device3), either one of them is OK.

Result bitmask 1 1 0 0 would be bad because Device3 would get the message twice.

+1  A: 

Take a look at backtrack search.

Pace
Looks promising, I will take a look.
Jaakko L.
+4  A: 

Since there may not be a perfect solution and we only have 16 possibilities for the result I would just use a brute force approach and iterate through all 16 possible masks, and see which one(s) is/are optimal (minimum number of repeated messages).

Paul R
+1 Exactly, iterating over 16 options is no brainer on any usual computation platform; you don't even need to go through all the 256 channels because if you have more than 16 channels some of them are bound to have the same bitmasks; just maintain a table that calculates the counts of different bitmasks in the device table and then optimize using that; 16 x 16 table row checks then suffice---fast
antti.huima
16 options isn't much, but wouldn't I need to iterate through all devices? There would be 16 * numOfDevices iterations to do to get all valid channel masks.This checking is something that might have to be done every 100 ms, so every 1 ms in execution time adds 1% CPU overhead.
Jaakko L.
Suppose you spend say 10 instruction clocks processing each device. That's 16 * 256 * 10 clocks = 40k clocks = 20 µs on a 2 GHz CPU. If you do this every 100 ms then it's a 0.02% CPU load.
Paul R
@Jaakko every device has one of the 16 masks, so it's enough to maintain a table int[16] where each entry counts the *NUMBER* of devices having that bitmask, i.e. if table[0xf]==3 then you have 3 devices with bitmask 1111. You can use that table instead of the actual device list when you do the optimization.
antti.huima
@antti.huima Thanks for clarifying, now I got your idea. Using an bitmask count array speeds things up a lot.
Jaakko L.
+1  A: 

You could add the number of 1's in each column to find out how many "receptions" will occur for a message on that channel. That way for any valid mask (that reaches all devices) you can easily add up the total number of messages received by all devices. You can then brute force all 16 possible masks seeing which ones will actually work and choosing the one that both works and has the lowest total number of receptions. Getting around the brute-force part is going to require operations on the entire matrix.

Oddly, if you actually had 256 devices you'd probably have to send on all channels anyway.

phkahler
Thanks, this is similar to what I first came up with. What I didn't think of, is that I could compare the valid masks to number of receptions per channel. I think this is a pretty fast solution, thanks.
Jaakko L.