distributing graph nodes into buckets - algorithm

I have a adjacency matrix nxn. Each node of the graph has m outgoing edges and I want to distribute these nodes into b buckets.
Each bucket should hold a minimum of l and a maximum of u nodes (uxb >= n). Each node inside the bucket should have at least one outgoing edge to another node inside the bucket.
I feel that I am missing the best angle to solve this.
How would you approach this?

Start by separating the graph into connected components this can be done in O(n) time and memory by performing a depth-first or breadth-first search.
If any nodes are not connected to another node then a solution is not possible.
Start from the leaves of each DFS/BFS tree (i.e. nodes connected to only one other node) and split each connected component into pairs (or triplets) of adjacent nodes. Each pair (or triplet) should go into the next bucket with the fewest number of nodes in it.
o o
/ \ |
o o o o | | | | | |
| / \ / | | | | | | |
o o o o | | | | | |
\ \ / / |____| |____| |____|
--o---- Bucket 1 Bucket 2 Bucket 3
Remove 2 nodes from the left leaf.
o o
/ \ |
a o o o |a | | | | |
| / \ / | || | | | | |
a o o o |a | | | | |
\ \ / / |____| |____| |____|
--o---- Bucket 1 Bucket 2 Bucket 3
Remove 2 nodes from the right leaf.
o b
/ \ |
o o b |a | |b | | |
/ \ / | || | || | | |
o o o |a | |b | | |
\ / / |____| |____| |____|
o---- Bucket 1 Bucket 2 Bucket 3
Then remove the final degree 1 vertex and its neighbour:
o
/ \
o o |a | |b | |c |
/ \ / || | || | || |
o o c |a | |b | |c |
\ / / |____| |____| |____|
c---- Bucket 1 Bucket 2 Bucket 3
This creates a new degree 1 vertex in the remaining sub-graph so remove that and its adjacent vertex:
o
/ \
d o |a d | |b | |c |
/ \ / || | | || | || |
d o |a d | |b | |c |
|____| |____| |____|
Bucket 1 Bucket 2 Bucket 3
There are only 3 vertices left, if it will fit in a bucket then put it into the bucket - otherwise move a pair from the bucket with the smallest number of items to the bucket with the next lowest number of items and add the triplet in its place.
e
\
e |a d | |e e | |c b |
/ || | | |\ / | || | |
e |a d | | e | |c b |
|____| |____| |____|
Bucket 1 Bucket 2 Bucket 3
The only issue will be when you get star-like connected components
o o
\ /
o--o--o
/ \
o o
Then the entire connected component will need to go into the same bucket as you cannot split the graph by removing a pair of triplet of adjacent vertices without having single disjoint vertices remaining. This you can check for by testing whether if you remove a pair there are other adjacent vertices that were degree one and if so add them to the pair.

Related

A NFA accepting ;anguages whose final digit didn't appear before

Give a non-deterministic finite automata(NFA) which accepts the following language:
The set of strings over the alphabet {0,1,...,9} such that the final digit has not appeared before.
I have encountered this problem on introduction to automata theory languages and computation page 67 Exercise 2.3.4
When the alphabet is {0,1}, which is the simplest non-trivial situation, we can get a simplest NFA like this:
The simplest non-trivial situation
So further you can get an NFA like this:
enter image description here
An easy way to get an NFA for this is to consider each of the 10 cases separately. Consider the case of all strings in the language whose last digit is 0. Such strings contain no other 0s; a regular expression for them is (1+2+3+4+5+6+7+8+9)*0. An NFA for them looks sort of like
1,2,3,4,5,6,8,9
/--\
| /
V /
o----->A0--0-->[B0]
We can imagine 9 others with states Ax, Bx, where Bx is accepting for each x, and Ax loops to itself on every symbol besides x, and to Bx on symbol x.
We can then glue all of these together by introducing a new initial state S which has an empty/lambda transition to the Ax states. The final NFA would have:
one initial state S
empty/lambda/epsilon transitions from S to states A0, A1, A2, A3, A4, A5, A6, A7, A8 and A9
transitions from A0 to B0 on 0, A1 to B1 on 1, A2 to B2 on 2, and so on
all missing transitions from states A0, A1, A2, and so on, back to those same states
In fact, why not copy/paste the above and just write the whole thing down?
1,2,3,4,5,6,7,8,9
/--\
| /
V /
/----->A0--0-->[B0]
/
| 0,2,3,4,5,6,7,8,9
| /--\
| | /
| V /
| /----->A1--1-->[B1]
|/
| 0,1,3,4,5,6,7,8,9
| /--\
| | /
| V /
| /----->A2--2-->[B2]
|/
| 0,1,2,4,5,6,7,8,9
| /--\
| | /
| V /
| /----->A3--3-->[B3]
|/
| 0,1,2,3,5,6,7,8,9
| /--\
| | /
| V /
| /----->A4--4-->[B4]
|/
/ 0,1,2,3,4,6,7,8,9
S-< /--\
\ | /
|\ V /
| \----->A5--5-->[B5]
|
| 0,1,2,3,4,5,7,8,9
| /--\
| | /
|\ V /
| \----->A6--6-->[B6]
|
| 0,1,2,3,4,5,6,8,9
| /--\
| | /
|\ V /
| \----->A7--7-->[B7]
|
| 0,1,2,3,4,5,6,7,9
| /--\
| | /
|\ V /
| \----->A8--8-->[B8]
|
| 0,1,2,3,4,5,6,7,8
| /--\
| | /
\ V /
\----->A9--9-->[B9]
Is this the simplest NFA or DFA for this language? Almost surely not. But it should work.

Detect early tie in Connect 4

I am looking for an algorithm to detect an early tie in a Connect 4 game. As of now, I already check if the board is full and no wins have been detected but I would like to know as soon as the game can be deduced a tie.
For example, consider this game, where player B just played at position Row-5, Column-0:
|
v
5 | B | | | | | | |
4 | A | B | A | B | A | B | A |
3 | A | B | A | B | A | B | A |
2 | B | A | B | A | B | A | B |
1 | B | A | B | A | B | A | B |
0 | A | B | A | B | A | B | A |
0 1 2 3 4 5 6
Then, the game is not considered a tie, because there is still a way for player B to win. Though if player A plays at Row-5, Column-1:
|
v
5 | B | A | | | | | |
4 | A | B | A | B | A | B | A |
3 | A | B | A | B | A | B | A |
2 | B | A | B | A | B | A | B |
1 | B | A | B | A | B | A | B |
0 | A | B | A | B | A | B | A |
0 1 2 3 4 5 6
At this point, either player has no way to win: it going to be a tie. I would like the algorithm to notify the user of this right away.
Check all possible runs of 4-in-a-row on the board, horizontal, vertical and diagonal. If all of them contain at least one A and at least one B then it's going to be a tie. If there is even one that is made up of a combination of empty and A or empty and B (assuming there are no rows of 4-in-a-row A or 4-in-a-row B, in which case you already have a win), then a win by A or B is still possible.
You probably already have code to check for a win, so just adapt it to check for 4-in-a-row of A or empty, or 4-in-a-row of B or empty instead of 4-in-a-row of A, or 4-in-a-row of B. If it fails to detect a possible win then a tie is inevitable.
One wrinkle is when there are a small number of empty spaces on the board. In this case you need to work out how many remaining moves A and B have and only allow them that many number of empties in the calculation, e.g. check for 4-in-a-row of A and a maximum of 2 empties. For example if there are 5 empty spaces left and it's B's turn then A has 2 moves left and B has 3.
One case it won't handle is if there is a single empty column left - there might be enough space for one player to stack 4 in a row but they can't because the players have to alternate.

Special sliding puzzle - Algorithm to find minimum distance

I just stumbled upon a strange (and very annoying game) that I wanted to solve programmatically. It reminds a bit of Rubik's cube, but 2 dimensional. I'm struggling a bit on how to approach this...
There is a 9x9 square with some circles placed into the inner squares. For instance, one get's the following picture:
A B C D E F G H I
-------------------------------------
9 | | | O | | | O | | | | J
-------------------------------------
8 | | | O | | O | | O | | | K
-------------------------------------
7 | | | | O | | | O | O | | L
-------------------------------------
6 | | | O | | | | O | | | M
-------------------------------------
5 | | | O | | | | | | | N
-------------------------------------
4 | | | | O | | O | O | | | O
-------------------------------------
3 | | | | | O | | O | | | P
-------------------------------------
2 | | | | O | | | | | | Q
-------------------------------------
1 | | | O | | | | | | | R
-------------------------------------
0 Z Y X W V U T S
One can use the numbers and letters arround the square to shift entire "rows" or "columns" to either left/right or up/down. Circles that would leave the game area to the right would reappear on the left and vise-versa, same accounts for top/bottom.
The goal is to rearrange the circles to a given pattern with a maximum amount of moves. For instance, one should rearrange the circles in the above picture to reflect the below picture in maximum 17 moves:
A B C D E F G H I
-------------------------------------
9 | | | | | | | | | | J
-------------------------------------
8 | | | O | O | O | O | O | | | K
-------------------------------------
7 | | | O | | | | O | | | L
-------------------------------------
6 | | | O | | | | O | | | M
-------------------------------------
5 | | | O | | | | O | | | N
-------------------------------------
4 | | | O | | | | O | | | O
-------------------------------------
3 | | | O | O | O | O | O | | | P
-------------------------------------
2 | | | | | | | | | | Q
-------------------------------------
1 | | | | | | | | | | R
-------------------------------------
0 Z Y X W V U T S
I would like to feed the starting and the end position of the circles to a program that delivers the shortest path possible. I'm struggling a bit to find an approach that doesn't just try all possible moves until a given maximum number of moves is reached.
Also it doesn't seem to be that easy to modify the approach that's being used to solve a Rubik's cube for instance...
Well, I thought it was a very interesting problem, and maybe somebody here has an illuminating idea.
UPDATE:
Just trying all the possible moves doesn't really seem realistic after a first try. There are just too many permutations. I think this could be really hard to solve...if possible at all.

Fitch-Style Proof

Hi I'm having trouble solving a Fitch Style Proof and I was hoping someone would be able to help me.
Premises:
A ^ (B v C)
B => D
C => E
Goal:
~E => D
(1) A /\ (B \/ C) premise
(2) B -> D premise
(3) C -> E premise
.--------------------------------------------.
(4) | ~E assumption |
(5) | B \/ C /\ elimination of 1 |
| .--------------------------------------. |
(6) | | B assumption | |
(7) | | D -> elimination 2 | |
| '--------------------------------------' |
| .--------------------------------------. |
(8) | | C assumption | |
(9) | | E -> elimination 3 | |
(10) | | cont contradiction | |
(11) | | D ! elimination 10 | |
| '--------------------------------------' |
(12) | D \/ elimination 5, 6-7, 8-11 |
'--------------------------------------------'
(13) ~E -> D -> introduction 4-12

Direct-­mapped instruction cache VS fully associative instruction cache using LRU replacement

For caches of small size, a direct-­mapped instruction cache can sometimes outperform a fully associative instruction cache using LRU replacement.
Could anyone explain how this would be possible with an example access pattern?
This can happen for caches of small size. Let's compare caches of size 2.
In my example, the directly-mapped "DM" cache will use row A for odd addresses, and row B for even addresses.
The LRU cache will use the least recently used row to store values on a miss.
The access pattern I suggest is 13243142 (repeated as many times as one wants).
Here's a breakdown of how botch caching algorithms will behave:
H - hits
M - misses
----- time ------>>>>>
Accessed: 1 | 3 | 2 | 4 | 3 | 1 | 4 | 2
\ \ \ \ \ \ \ \
LRU A ? | ? | 3 | 3 | 4 | 4 | 1 | 1 | 2 |
B ? | 1 | 1 | 2 | 2 | 3 | 3 | 4 | 4 |
M M M M M M M M
DM A ? | 1 | 3 | 3 | 3 | 3 | 1 | 1 | 1 |
B ? | ? | ? | 2 | 4 | 4 | 4 | 4 | 2 |
M M M M H M H M
That gives 8 misses for the LRU, and 6 for directly-mapped. Let's see what happens if this pattern gets repeated forever:
----- time ------>>>>>
Accessed: 1 | 3 | 2 | 4 | 3 | 1 | 4 | 2
\ \ \ \ \ \ \ \
LRU A | 2 | 3 | 3 | 4 | 4 | 1 | 1 | 2 |
B | 1 | 1 | 2 | 2 | 3 | 3 | 4 | 4 |
M M M M M M M M
DM A | 1 | 3 | 3 | 3 | 3 | 1 | 1 | 1 |
B | 2 | 2 | 2 | 4 | 4 | 4 | 4 | 2 |
H M H M H M H M
So the directly-mapped cache will have 50% of hits, which outperforms 0% hits of LRU.
This works this way because:
Any address repeated in this pattern has not been accessed for previous 2 accesses (and both these were different), so LRU cache will always miss.
The DM cache will sometimes miss, as the pattern is designed so that it utilizes what has been stored the last time the corresponding row was used.
Therefore once can build similar patterns for larger cache sizes, but the larger the cache size, the longer such pattern would need to be. This corresponds to the intuition that for larger caches it would be harder to exploit them this way.

Resources