creating office shelf
This commit is contained in:
parent
3461ab5570
commit
06d1d3474a
34 changed files with 551 additions and 0 deletions
176
OfficeShelf/zuschnitt.py
Normal file
176
OfficeShelf/zuschnitt.py
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
import time
|
||||
|
||||
|
||||
class LengthError(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
class Cut(object):
|
||||
|
||||
def __init__(self, l):
|
||||
self.Length = l
|
||||
|
||||
|
||||
class CutableRod(object):
|
||||
|
||||
def __init__(self):
|
||||
self.Length = 6000
|
||||
self.CutThickness = 0
|
||||
self.Remainder = self.Length
|
||||
self.Cuts = []
|
||||
|
||||
def addCut(self, cut):
|
||||
if not self.canAddCut(cut):
|
||||
raise LengthError("Cut.Length=%i, Remainder=%i" % (cut.Length, self.Remainder))
|
||||
self.Cuts.append(cut)
|
||||
self.Remainder -= cut.Length
|
||||
self.Remainder -= self.CutThickness
|
||||
|
||||
def copy(self):
|
||||
new_rod = CutableRod()
|
||||
new_rod.Length = self.Length
|
||||
new_rod.CutThickness = self.CutThickness
|
||||
new_rod.Remainder = self.Remainder
|
||||
for c in self.Cuts:
|
||||
new_rod.Cuts.append(c)
|
||||
return new_rod
|
||||
|
||||
def canAddCut(self, cut):
|
||||
return self.Remainder >= cut.Length
|
||||
|
||||
def variety(self):
|
||||
""" Amount of different cut lengths
|
||||
"""
|
||||
lengths = []
|
||||
for cut in self.Cuts:
|
||||
if cut.Length not in lengths:
|
||||
lengths.append(cut.Length)
|
||||
return len(lengths)
|
||||
|
||||
|
||||
class CutSolution(object):
|
||||
|
||||
def __init__(self):
|
||||
self.Rods = []
|
||||
|
||||
def isBetterThan(self, other):
|
||||
if self.rods() != other.rods():
|
||||
return self.rods() < other.rods()
|
||||
elif self.remainder() != other.remainder():
|
||||
return self.remainder() < other.remainder()
|
||||
elif self.variety() != other.variety():
|
||||
return self.variety() < other.variety()
|
||||
else:
|
||||
return False
|
||||
|
||||
def copy(self):
|
||||
new_solution = CutSolution()
|
||||
for r in self.Rods:
|
||||
new_solution.Rods.append(r.copy())
|
||||
return new_solution
|
||||
|
||||
def variety(self):
|
||||
variety = 0
|
||||
for r in self.Rods:
|
||||
v = r.variety()
|
||||
if v > 1:
|
||||
variety += v
|
||||
return variety
|
||||
|
||||
def rods(self):
|
||||
return len(self.Rods)
|
||||
|
||||
def remainder(self):
|
||||
remainder = 0
|
||||
for r in self.Rods:
|
||||
remainder += r.Remainder
|
||||
return remainder
|
||||
|
||||
def print(self, short=False):
|
||||
if not short:
|
||||
print("\nSolution")
|
||||
for idx_r in range(len(self.Rods)):
|
||||
r = self.Rods[idx_r]
|
||||
print("Rod ", idx_r, ": ", end="", sep="")
|
||||
for idx_c in range(len(r.Cuts)):
|
||||
c = r.Cuts[idx_c]
|
||||
print(c.Length, " ", end="", sep="")
|
||||
print("(-", r.Remainder, ")", sep="")
|
||||
|
||||
print("Rods=", self.rods(), ", Remainder=", self.remainder(), ", Variety=", self.variety(), sep="")
|
||||
|
||||
|
||||
class CutRequest(object):
|
||||
|
||||
def __init__(self):
|
||||
self.Cuts = []
|
||||
self.CreatedSolutions = []
|
||||
|
||||
|
||||
def add(self, amount, length):
|
||||
for i in range(amount):
|
||||
c = Cut(length)
|
||||
self.Cuts.append(c)
|
||||
|
||||
|
||||
def _iterate(self, current_solution, remaining_cuts):
|
||||
if len(remaining_cuts) == 0:
|
||||
return current_solution
|
||||
|
||||
best_solution = None
|
||||
|
||||
tested_lengths = []
|
||||
for idx_try in range(len(remaining_cuts)):
|
||||
cut = remaining_cuts[idx_try]
|
||||
|
||||
# avoid testing same length again
|
||||
if cut.Length in tested_lengths:
|
||||
continue
|
||||
tested_lengths.append(cut.Length)
|
||||
|
||||
# create temporary solution for trial
|
||||
trysol = CutSolution() if current_solution is None else current_solution.copy()
|
||||
|
||||
# add cut to temporary solution
|
||||
if len(trysol.Rods) == 0 or not trysol.Rods[-1].canAddCut(cut):
|
||||
trysol.Rods.append(CutableRod())
|
||||
trysol.Rods[-1].addCut(cut)
|
||||
|
||||
# create list of remaining other cuts
|
||||
remaining_cuts_without_try = []
|
||||
for idx_other in range(len(remaining_cuts)):
|
||||
if idx_other != idx_try:
|
||||
cut_other = remaining_cuts[idx_other]
|
||||
remaining_cuts_without_try.append(cut_other)
|
||||
|
||||
# solve for tried remaining cuts
|
||||
trysol = self._iterate(trysol, remaining_cuts_without_try)
|
||||
|
||||
# keep best solution
|
||||
if best_solution is None or trysol.isBetterThan(best_solution):
|
||||
best_solution = trysol
|
||||
if current_solution is None:
|
||||
print("Better Solution: ", end="")
|
||||
best_solution.print(True)
|
||||
|
||||
return best_solution
|
||||
|
||||
|
||||
def arrangeCuts(self):
|
||||
time_start = time.time()
|
||||
solution = self._iterate(None, self.Cuts)
|
||||
solution.print()
|
||||
time_stop = time.time()
|
||||
print("duration: %0.1f" % (time_stop - time_start))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
cr = CutRequest()
|
||||
cr.add(8, 660);
|
||||
cr.add(16, 620);
|
||||
cr.add(1, 905);
|
||||
cr.add(2, 442);
|
||||
cr.add(2, 848);
|
||||
cr.add(4, 414);
|
||||
cr.arrangeCuts()
|
||||
Loading…
Add table
Add a link
Reference in a new issue