Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
I
ilp_keyboard_layout_optimization
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Björn Ludwig
ilp_keyboard_layout_optimization
Commits
67ba0ce1
Unverified
Commit
67ba0ce1
authored
3 years ago
by
Björn Ludwig
Browse files
Options
Downloads
Patches
Plain Diff
refactor(ilp): switch from keys to positions
parent
9928abd4
No related branches found
Branches containing commit
No related tags found
1 merge request
!1
Introduce Chars
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/ilp_keyboard_layout_optimization/ilp.py
+39
-48
39 additions, 48 deletions
src/ilp_keyboard_layout_optimization/ilp.py
with
39 additions
and
48 deletions
src/ilp_keyboard_layout_optimization/ilp.py
+
39
−
48
View file @
67ba0ce1
...
@@ -2,16 +2,6 @@
...
@@ -2,16 +2,6 @@
from
itertools
import
chain
,
permutations
,
product
from
itertools
import
chain
,
permutations
,
product
from
typing
import
Iterable
from
typing
import
Iterable
from
.type_aliases
import
(
CharKeyPair
,
CharKeyQuadruple
,
CharTuple
,
KeyTuple
,
LinCosts
,
LinVars
,
QuadCosts
,
QuadVars
,
)
from
pyscipopt
import
Model
,
quicksum
from
pyscipopt
import
Model
,
quicksum
from
.data_aquisition.chars
import
Chars
from
.data_aquisition.chars
import
Chars
...
@@ -30,52 +20,52 @@ class KeyboardOptimization:
...
@@ -30,52 +20,52 @@ class KeyboardOptimization:
"""
Instances of this class represent instances of the keyboard layout QAP
"""
Instances of this class represent instances of the keyboard layout QAP
The IP variant of an optimization of character to key assignments can be modeled
The IP variant of an optimization of character to key assignments can be modeled
as a so
called quadratic assignment problem (QAP). The task is to assign a set of
as a so
-
called quadratic assignment problem (QAP). The task is to assign a set of
characters to a set of keys on a keyboard. The way in which they should be
characters to a set of keys on a keyboard. The way in which they should be
arranged has to meet certain criteria such as for instance: characters that are
arranged has to meet certain criteria such as for instance: characters that are
often typed after one another should not be assigned to
key
s, that are supposed
often typed after one another should not be assigned to
position
s, that are supposed
to be pressed by the same finger.
to be pressed by the same finger.
Parameters
Parameters
----------
----------
chars : CharTuple
chars : CharTuple
the (special) characters to be assign
the (special) characters to be assign
keys: Key
Tuple
poss: Pos
Tuple
the
key
s to which we want to assign the (special) characters
the
position
s to which we want to assign the (special) characters
"""
"""
chars
:
Char
Tuple
chars
:
Char
s
keys
:
Key
Tuple
poss
:
Pos
Tuple
def
__init__
(
self
,
chars
:
Chars
,
poss
:
PosTuple
):
def
__init__
(
self
,
chars
:
Chars
,
poss
:
PosTuple
):
assert
len
(
chars
.
monos
)
==
len
(
poss
)
assert
len
(
chars
.
monos
)
==
len
(
poss
)
self
.
chars
=
chars
self
.
chars
=
chars
self
.
key
s
=
key
s
self
.
pos
s
=
pos
s
self
.
char_
key
_assigns
:
LinVars
=
{}
self
.
char_
pos
_assigns
:
LinVars
=
{}
self
.
quad_char_
key
_assigns
:
QuadVars
=
{}
self
.
quad_char_
pos
_assigns
:
QuadVars
=
{}
self
.
char_
key
_costs
:
LinCosts
=
{}
self
.
char_
pos
_costs
:
LinCosts
=
{}
self
.
quad_char_
key
_costs
:
QuadCosts
=
{}
self
.
quad_char_
pos
_costs
:
QuadCosts
=
{}
self
.
model
:
Model
=
Model
(
"
Keyboard Layout Optimization
"
)
self
.
model
:
Model
=
Model
(
"
Keyboard Layout Optimization
"
)
def
set_up_model
(
self
,
char_key_costs
:
LinCosts
,
quad_char_key_costs
:
QuadCosts
):
def
set_up_model
(
self
,
char_key_costs
:
LinCosts
,
quad_char_key_costs
:
QuadCosts
):
"""
Set up all the variables and initialize the costs for the SCIP model
"""
"""
Set up all the variables and initialize the costs for the SCIP model
"""
for
(
char
,
key
)
in
self
.
char_key_assigns_keys
:
for
(
char
,
key
)
in
self
.
char_key_assigns_keys
:
self
.
char_
key
_assigns
[
char
,
key
]
=
self
.
model
.
addVar
(
self
.
char_
pos
_assigns
[
char
,
key
]
=
self
.
model
.
addVar
(
name
=
f
"
{
key
}
=
{
char
}
"
,
vtype
=
"
B
"
name
=
f
"
{
key
}
=
{
char
}
"
,
vtype
=
"
B
"
)
)
for
(
char
,
char_2
,
key
,
key_2
)
in
self
.
quad_char_key_assigns_keys
:
for
(
char
,
char_2
,
key
,
key_2
)
in
self
.
quad_char_key_assigns_keys
:
self
.
quad_char_
key
_assigns
[
char
,
char_2
,
key
,
key_2
]
=
self
.
model
.
addVar
(
self
.
quad_char_
pos
_assigns
[
char
,
char_2
,
key
,
key_2
]
=
self
.
model
.
addVar
(
name
=
f
"
{
key
}
=
{
char
}
_and_
{
key_2
}
=
{
char_2
}
"
,
vtype
=
"
C
"
,
lb
=
0
,
ub
=
1
name
=
f
"
{
key
}
=
{
char
}
_and_
{
key_2
}
=
{
char_2
}
"
,
vtype
=
"
C
"
,
lb
=
0
,
ub
=
1
)
)
assert
len
(
quad_char_key_costs
)
==
len
(
self
.
quad_char_
key
_assigns
)
assert
len
(
quad_char_key_costs
)
==
len
(
self
.
quad_char_
pos
_assigns
)
assert
len
(
char_key_costs
)
==
len
(
self
.
char_
key
_assigns
)
assert
len
(
char_key_costs
)
==
len
(
self
.
char_
pos
_assigns
)
self
.
char_
key
_costs
=
char_key_costs
self
.
char_
pos
_costs
=
char_key_costs
self
.
quad_char_
key
_costs
=
quad_char_key_costs
self
.
quad_char_
pos
_costs
=
quad_char_key_costs
constr
=
{}
constr
=
{}
for
char
in
self
.
chars
.
monos
:
for
char
in
self
.
chars
.
monos
:
self
.
model
.
addCons
(
self
.
model
.
addCons
(
quicksum
(
self
.
char_
key
_assigns
[
char
,
key
]
for
key
in
self
.
key
s
)
==
1
,
quicksum
(
self
.
char_
pos
_assigns
[
char
,
key
]
for
key
in
self
.
pos
s
)
==
1
,
f
"
AllCharacterAssignedOnce(
{
char
}
)
"
,
f
"
AllCharacterAssignedOnce(
{
char
}
)
"
,
)
)
for
(
key
,
key_2
)
in
self
.
key_pairs
:
for
(
key
,
key_2
)
in
self
.
key_pairs
:
...
@@ -85,7 +75,7 @@ class KeyboardOptimization:
...
@@ -85,7 +75,7 @@ class KeyboardOptimization:
for
char_2
in
self
.
chars
.
monos
for
char_2
in
self
.
chars
.
monos
if
char_2
!=
char
if
char_2
!=
char
)
)
<=
self
.
char_
key
_assigns
[
char
,
key
],
<=
self
.
char_
pos
_assigns
[
char
,
key
],
f
"
QuadCharacterAssignedLEQThanPosition(
{
char
}
,
{
key
}
,
{
key_2
}
)
"
,
f
"
QuadCharacterAssignedLEQThanPosition(
{
char
}
,
{
key
}
,
{
key_2
}
)
"
,
)
)
self
.
model
.
addCons
(
self
.
model
.
addCons
(
...
@@ -94,7 +84,7 @@ class KeyboardOptimization:
...
@@ -94,7 +84,7 @@ class KeyboardOptimization:
for
char_2
in
self
.
chars
.
monos
for
char_2
in
self
.
chars
.
monos
if
char_2
!=
char
if
char_2
!=
char
)
)
<=
self
.
char_
key
_assigns
[
char
,
key
],
<=
self
.
char_
pos
_assigns
[
char
,
key
],
f
"
QuadCharacterAssignedLEQThanSecondPosition(
{
char
}
,
{
key_2
}
,
{
key
}
)
"
,
f
"
QuadCharacterAssignedLEQThanSecondPosition(
{
char
}
,
{
key_2
}
,
{
key
}
)
"
,
)
)
for
char_2
in
self
.
chars
.
monos
:
for
char_2
in
self
.
chars
.
monos
:
...
@@ -102,35 +92,36 @@ class KeyboardOptimization:
...
@@ -102,35 +92,36 @@ class KeyboardOptimization:
if
char_2
!=
char
:
if
char_2
!=
char
:
self
.
model
.
addCons
(
self
.
model
.
addCons
(
quicksum
(
quicksum
(
self
.
quad_char_
key
_assigns
[
char
,
char_2
,
key
,
key_2
]
self
.
quad_char_
pos
_assigns
[
char
,
char_2
,
key
,
key_2
]
for
key_2
in
self
.
key
s
for
key_2
in
self
.
pos
s
if
key_2
!=
key
if
key_2
!=
key
)
)
<=
self
.
char_
key
_assigns
[
char
,
key
],
<=
self
.
char_
pos
_assigns
[
char
,
key
],
f
"
QuadCharacterAssignedLEQThanCharacter(
{
char
}
,
{
char_2
}
,
"
f
"
QuadCharacterAssignedLEQThanCharacter(
{
char
}
,
{
char_2
}
,
"
f
"
{
key
}
)
"
,
f
"
{
key
}
)
"
,
)
)
self
.
model
.
addCons
(
self
.
model
.
addCons
(
quicksum
(
quicksum
(
self
.
quad_char_
key
_assigns
[
char_2
,
char
,
key_2
,
key
]
self
.
quad_char_
pos
_assigns
[
char_2
,
char
,
key_2
,
key
]
for
key_2
in
self
.
key
s
for
key_2
in
self
.
pos
s
if
key_2
!=
key
if
key_2
!=
key
)
)
<=
self
.
char_
key
_assigns
[
char
,
key
],
<=
self
.
char_
pos
_assigns
[
char
,
key
],
f
"
QuadCharacterAssignedLEQThanSecondCharacter(
{
char_2
}
,
"
f
"
QuadCharacterAssignedLEQThanSecondCharacter(
{
char_2
}
,
"
f
"
{
char
}
,
{
key
}
)
"
,
f
"
{
char
}
,
{
key
}
)
"
,
)
)
for
(
char
,
char_2
,
key
,
key_2
)
in
self
.
quad_char_key_assigns_keys
:
for
(
char
,
char_2
,
key
,
key_2
)
in
self
.
quad_char_key_assigns_keys
:
self
.
model
.
addCons
(
self
.
model
.
addCons
(
self
.
char_
key
_assigns
[
char
,
key
]
+
self
.
char_
key
_assigns
[
char_2
,
key_2
]
self
.
char_
pos
_assigns
[
char
,
key
]
+
self
.
char_
pos
_assigns
[
char_2
,
key_2
]
<=
1
+
self
.
quad_char_
key
_assigns
[
char
,
char_2
,
key
,
key_2
],
<=
1
+
self
.
quad_char_
pos
_assigns
[
char
,
char_2
,
key
,
key_2
],
f
"
IntegrableQuadAssign(
{
char
}
,
{
key_2
}
,
{
key
}
)
"
,
f
"
IntegrableQuadAssign(
{
char
}
,
{
key_2
}
,
{
key
}
)
"
,
)
)
for
key
in
self
.
key
s
:
for
key
in
self
.
pos
s
:
constr
[
key
]
=
self
.
model
.
addCons
(
constr
[
key
]
=
self
.
model
.
addCons
(
quicksum
(
self
.
char_key_assigns
[
char
,
key
]
for
char
in
self
.
chars
)
==
1
,
quicksum
(
self
.
char_pos_assigns
[
char
,
key
]
for
char
in
self
.
chars
.
monos
)
==
1
,
f
"
AllPositionsAssignedOnce(
{
key
}
)
"
,
f
"
AllPositionsAssignedOnce(
{
key
}
)
"
,
)
)
...
@@ -138,14 +129,14 @@ class KeyboardOptimization:
...
@@ -138,14 +129,14 @@ class KeyboardOptimization:
quicksum
(
quicksum
(
costs
*
assigns
costs
*
assigns
for
(
costs
,
assigns
)
in
zip
(
for
(
costs
,
assigns
)
in
zip
(
self
.
char_
key
_costs
.
values
(),
self
.
char_
key
_assigns
.
values
()
self
.
char_
pos
_costs
.
values
(),
self
.
char_
pos
_assigns
.
values
()
)
)
)
)
+
quicksum
(
+
quicksum
(
costs
*
assigns
costs
*
assigns
for
(
costs
,
assigns
)
in
zip
(
for
(
costs
,
assigns
)
in
zip
(
self
.
quad_char_
key
_costs
.
values
(),
self
.
quad_char_
pos
_costs
.
values
(),
self
.
quad_char_
key
_assigns
.
values
(),
self
.
quad_char_
pos
_assigns
.
values
(),
)
)
),
),
"
minimize
"
,
"
minimize
"
,
...
@@ -169,10 +160,10 @@ class KeyboardOptimization:
...
@@ -169,10 +160,10 @@ class KeyboardOptimization:
for
(
char
,
key
)
in
self
.
char_key_assigns_keys
:
for
(
char
,
key
)
in
self
.
char_key_assigns_keys
:
print
(
print
(
f
"
(
{
char
}
,
{
key
}
):
"
f
"
(
{
char
}
,
{
key
}
):
"
f
"
{
self
.
model
.
getVal
(
self
.
char_
key
_assigns
[
char
,
key
])
}
,
"
f
"
{
self
.
model
.
getVal
(
self
.
char_
pos
_assigns
[
char
,
key
])
}
,
"
f
"
cost:
{
self
.
char_
key
_costs
[
char
,
key
]
}
"
f
"
cost:
{
self
.
char_
pos
_costs
[
char
,
key
]
}
"
)
)
if
self
.
model
.
getVal
(
self
.
char_
key
_assigns
[
char
,
key
])
==
1
:
if
self
.
model
.
getVal
(
self
.
char_
pos
_assigns
[
char
,
key
])
==
1
:
solution_assignments
.
append
((
char
,
key
))
solution_assignments
.
append
((
char
,
key
))
assert
"
(
'
u
'
,
'
left_pinky_home
'
)
"
in
str
(
solution_assignments
)
assert
"
(
'
u
'
,
'
left_pinky_home
'
)
"
in
str
(
solution_assignments
)
...
@@ -192,7 +183,7 @@ class KeyboardOptimization:
...
@@ -192,7 +183,7 @@ class KeyboardOptimization:
@property
@property
def
char_key_assigns_keys
(
self
)
->
Iterable
[
CharPosPair
]:
def
char_key_assigns_keys
(
self
)
->
Iterable
[
CharPosPair
]:
"""
An iterator for the pairs of (special) characters and corresponding keys
"""
"""
An iterator for the pairs of (special) characters and corresponding keys
"""
return
product
(
self
.
chars
,
self
.
key
s
)
return
product
(
self
.
chars
.
monos
,
self
.
pos
s
)
@property
@property
def
quad_char_key_assigns_keys
(
self
)
->
Iterable
[
CharPosQuadruple
]:
def
quad_char_key_assigns_keys
(
self
)
->
Iterable
[
CharPosQuadruple
]:
...
@@ -208,4 +199,4 @@ class KeyboardOptimization:
...
@@ -208,4 +199,4 @@ class KeyboardOptimization:
@property
@property
def
key_pairs
(
self
)
->
Iterable
:
def
key_pairs
(
self
)
->
Iterable
:
"""
An iterator for all pairs of keys that are possible
"""
"""
An iterator for all pairs of keys that are possible
"""
return
permutations
(
self
.
key
s
,
2
)
return
permutations
(
self
.
pos
s
,
2
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment