creating office shelf
This commit is contained in:
parent
3461ab5570
commit
06d1d3474a
34 changed files with 551 additions and 0 deletions
BIN
OfficeShelf/20_Multiplexboden.FCStd
Normal file
BIN
OfficeShelf/20_Multiplexboden.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/20_OfficeShelf.FCStd
Normal file
BIN
OfficeShelf/20_OfficeShelf.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/20_Regalboden.FCStd
Normal file
BIN
OfficeShelf/20_Regalboden.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/20_RegalbodenQuerstuetzen.FCStd
Normal file
BIN
OfficeShelf/20_RegalbodenQuerstuetzen.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/20_StuetzkreuzHinten.FCStd
Normal file
BIN
OfficeShelf/20_StuetzkreuzHinten.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/20_StuetzkreuzSeite.FCStd
Normal file
BIN
OfficeShelf/20_StuetzkreuzSeite.FCStd
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x40_I-Typ_Nut8/359mm.FCStd
Normal file
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x40_I-Typ_Nut8/359mm.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x40_I-Typ_Nut8/415mm.FCStd
Normal file
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x40_I-Typ_Nut8/415mm.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x40_I-Typ_Nut8/580mm.FCStd
Normal file
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x40_I-Typ_Nut8/580mm.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x40_I-Typ_Nut8/660mm.FCStd
Normal file
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x40_I-Typ_Nut8/660mm.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x40_I-Typ_Nut8/757mm.FCStd
Normal file
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x40_I-Typ_Nut8/757mm.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x40_I-Typ_Nut8/870mm.FCStd
Normal file
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x40_I-Typ_Nut8/870mm.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x80_I-Typ_Nut8/1980mm.FCStd
Normal file
BIN
OfficeShelf/Lib/Motedis/Aluprofil_40x80_I-Typ_Nut8/1980mm.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/Lib/Motedis/Winkel_40ITypNut8.FCStd
Normal file
BIN
OfficeShelf/Lib/Motedis/Winkel_40ITypNut8.FCStd
Normal file
Binary file not shown.
Binary file not shown.
BIN
OfficeShelf/Multiplexboden.FCStd
Normal file
BIN
OfficeShelf/Multiplexboden.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/OfficeShelf.FCStd
Normal file
BIN
OfficeShelf/OfficeShelf.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/Regalplatte.FCStd
Normal file
BIN
OfficeShelf/Regalplatte.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/StuetzkreuzHinten.FCStd
Normal file
BIN
OfficeShelf/StuetzkreuzHinten.FCStd
Normal file
Binary file not shown.
BIN
OfficeShelf/StuetzkreuzSeite.FCStd
Normal file
BIN
OfficeShelf/StuetzkreuzSeite.FCStd
Normal file
Binary file not shown.
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()
|
||||
74
OfficeShelf/zuschnitt_cpp/zuscnitt/.gitignore
vendored
Normal file
74
OfficeShelf/zuschnitt_cpp/zuscnitt/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# This file is used to ignore files which are generated
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
*~
|
||||
*.autosave
|
||||
*.a
|
||||
*.core
|
||||
*.moc
|
||||
*.o
|
||||
*.obj
|
||||
*.orig
|
||||
*.rej
|
||||
*.so
|
||||
*.so.*
|
||||
*_pch.h.cpp
|
||||
*_resource.rc
|
||||
*.qm
|
||||
.#*
|
||||
*.*#
|
||||
core
|
||||
!core/
|
||||
tags
|
||||
.DS_Store
|
||||
.directory
|
||||
*.debug
|
||||
Makefile*
|
||||
*.prl
|
||||
*.app
|
||||
moc_*.cpp
|
||||
ui_*.h
|
||||
qrc_*.cpp
|
||||
Thumbs.db
|
||||
*.res
|
||||
*.rc
|
||||
/.qmake.cache
|
||||
/.qmake.stash
|
||||
|
||||
# qtcreator generated files
|
||||
*.pro.user*
|
||||
CMakeLists.txt.user*
|
||||
|
||||
# xemacs temporary files
|
||||
*.flc
|
||||
|
||||
# Vim temporary files
|
||||
.*.swp
|
||||
|
||||
# Visual Studio generated files
|
||||
*.ib_pdb_index
|
||||
*.idb
|
||||
*.ilk
|
||||
*.pdb
|
||||
*.sln
|
||||
*.suo
|
||||
*.vcproj
|
||||
*vcproj.*.*.user
|
||||
*.ncb
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.vcxproj
|
||||
*vcxproj.*
|
||||
|
||||
# MinGW generated files
|
||||
*.Debug
|
||||
*.Release
|
||||
|
||||
# Python byte code
|
||||
*.pyc
|
||||
|
||||
# Binaries
|
||||
# --------
|
||||
*.dll
|
||||
*.exe
|
||||
|
||||
14
OfficeShelf/zuschnitt_cpp/zuscnitt/CMakeLists.txt
Normal file
14
OfficeShelf/zuschnitt_cpp/zuscnitt/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(zuscnitt LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "-O3")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-O3")
|
||||
|
||||
add_executable(zuscnitt main.cpp)
|
||||
|
||||
install(TARGETS zuscnitt
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
287
OfficeShelf/zuschnitt_cpp/zuscnitt/main.cpp
Normal file
287
OfficeShelf/zuschnitt_cpp/zuscnitt/main.cpp
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
#include <cassert>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
bool intvectcontains(const std::vector<int> &heystack, int needle) {
|
||||
for (auto i: heystack) {
|
||||
if (i == needle) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
class Cut {
|
||||
|
||||
public:
|
||||
Cut(int l) {
|
||||
this->Length = l;
|
||||
}
|
||||
|
||||
int length() const {
|
||||
return this->Length;
|
||||
}
|
||||
|
||||
private:
|
||||
Cut(Cut &); // deny copying
|
||||
int Length = 0;
|
||||
};
|
||||
|
||||
|
||||
class CutableRod {
|
||||
public:
|
||||
CutableRod() {
|
||||
this->Length = 6000;
|
||||
this->CutThickness = 9;
|
||||
this->Remainder = this->Length;
|
||||
}
|
||||
|
||||
CutableRod(CutableRod &other) {
|
||||
this->Length = other.Length;
|
||||
this->CutThickness = other.CutThickness;
|
||||
this->Remainder = other.Remainder;
|
||||
for (auto c : other.Cuts) {
|
||||
this->Cuts.push_back(c);
|
||||
}
|
||||
}
|
||||
|
||||
void addCut(std::shared_ptr<const Cut> cut) {
|
||||
assert(this->canAddCut(cut));
|
||||
this->Cuts.push_back(cut);
|
||||
this->Remainder -= cut->length();
|
||||
this->Remainder -= this->CutThickness;
|
||||
}
|
||||
|
||||
bool canAddCut(std::shared_ptr<const Cut> cut) {
|
||||
return this->Remainder >= cut->length();
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<const Cut>> cuts() {
|
||||
return this->Cuts;
|
||||
}
|
||||
|
||||
int remainder() {
|
||||
return this->Remainder;
|
||||
}
|
||||
|
||||
int variety(void) {
|
||||
std::vector<int> lengths;
|
||||
for (auto cut : this->Cuts) {
|
||||
if (!intvectcontains(lengths, cut->length()))
|
||||
lengths.push_back(cut->length());
|
||||
}
|
||||
return lengths.size();
|
||||
}
|
||||
|
||||
private:
|
||||
int Length = 0;
|
||||
int CutThickness = 0;
|
||||
int Remainder = 0;
|
||||
std::vector<std::shared_ptr<const Cut>> Cuts;
|
||||
};
|
||||
|
||||
|
||||
class CutSolution {
|
||||
public:
|
||||
CutSolution() {
|
||||
}
|
||||
|
||||
CutSolution(CutSolution &other) {
|
||||
for (auto r_other: other.Rods) {
|
||||
auto r_copy = std::make_shared<CutableRod>(*r_other);
|
||||
this->Rods.push_back(r_copy);
|
||||
}
|
||||
}
|
||||
|
||||
void addCut(std::shared_ptr<const Cut> cut) {
|
||||
|
||||
// add rod if empty
|
||||
if (this->Rods.empty()) {
|
||||
auto new_rod = std::make_shared<CutableRod>();
|
||||
this->Rods.push_back(new_rod);
|
||||
}
|
||||
|
||||
// add rod if cannot add cut
|
||||
if (!this->Rods.back()->canAddCut(cut)) {
|
||||
auto new_rod = std::make_shared<CutableRod>();
|
||||
this->Rods.push_back(new_rod);
|
||||
}
|
||||
|
||||
// add cut to last rod
|
||||
this->Rods.back()->addCut(cut);
|
||||
}
|
||||
|
||||
bool isBetterThan(const CutSolution &other) {
|
||||
|
||||
// compare rod amount
|
||||
int my_r = this->rods();
|
||||
int other_r = other.rods();
|
||||
if (my_r != other_r) {
|
||||
return my_r < other_r;
|
||||
|
||||
// compare remainder amount
|
||||
} else {
|
||||
int my_r = this->remainder();
|
||||
int other_r = other.remainder();
|
||||
if (my_r != other_r) {
|
||||
return my_r < other_r;
|
||||
|
||||
// compare variety amount
|
||||
} else {
|
||||
int my_v = this->variety();
|
||||
int other_v = other.variety();
|
||||
if (my_v != other_v) {
|
||||
return my_v < other_v;
|
||||
|
||||
// both solutions are equal
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print(bool shortform=false) {
|
||||
if (!shortform) {
|
||||
std::cout << std::endl << "Solution" << std::endl;
|
||||
for (auto it = this->Rods.begin(); it != this->Rods.end(); ++it) {
|
||||
int pos = std::distance(this->Rods.begin(), it);
|
||||
std::cout << "Rod " << pos << ": ";
|
||||
for (auto c: (*it)->cuts()) {
|
||||
std::cout << c->length() << " ";
|
||||
}
|
||||
std::cout << "(-" << (*it)->remainder() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Rods=" << this->rods();
|
||||
std::cout << ", Remainder=" << this->remainder();
|
||||
std::cout << ", Variety=" << this->variety();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
int remainder() const {
|
||||
int ret = 0;
|
||||
for (auto r: this->Rods) {
|
||||
ret += r->remainder();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rods() const {
|
||||
return (int) this->Rods.size();
|
||||
}
|
||||
|
||||
int variety() const {
|
||||
int ret = 0;
|
||||
for (auto r: this->Rods) {
|
||||
int v = r->variety();
|
||||
if (v > 1) ret += v;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<CutableRod>> Rods;
|
||||
};
|
||||
|
||||
|
||||
class CutRequest {
|
||||
public:
|
||||
CutRequest() {}
|
||||
|
||||
void add(int amount, int length) {
|
||||
for (int i=0; i < amount; ++i) {
|
||||
auto c = std::make_shared<Cut>(length);
|
||||
this->Cuts.push_back(c);
|
||||
}
|
||||
}
|
||||
|
||||
void arrangeCuts() {
|
||||
auto time_start = std::time(nullptr);
|
||||
auto solution = CutSolution();
|
||||
solution = this->arrangeCutIteration(solution, this->Cuts);
|
||||
solution.print();
|
||||
auto time_end = std::time(nullptr);
|
||||
std::cout << "Duration: " << (time_end - time_start) << std::endl;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<const Cut>> cuts() {
|
||||
return this->Cuts;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<const Cut>> Cuts;
|
||||
|
||||
CutSolution arrangeCutIteration(CutSolution ¤t_solution,
|
||||
std::vector<std::shared_ptr<const Cut>> remaining_cuts) {
|
||||
|
||||
if (remaining_cuts.empty()) return current_solution;
|
||||
CutSolution best_solution;
|
||||
bool ret_is_defined = false;
|
||||
|
||||
std::vector<int> tested_lengths;
|
||||
for (int idx_try=0; idx_try < remaining_cuts.size(); ++idx_try) {
|
||||
auto cut = remaining_cuts.at(idx_try);
|
||||
|
||||
// avaoid testing same length again
|
||||
// if (std::find(tested_lengths.begin(), tested_lengths.end(), cut->length()) != tested_lengths.end()) continue;
|
||||
if (intvectcontains(tested_lengths, cut->length())) continue;
|
||||
tested_lengths.push_back(cut->length());
|
||||
|
||||
// create temporary solution for trial
|
||||
CutSolution trysol(current_solution);
|
||||
|
||||
// add cut to temporary solution
|
||||
trysol.addCut(cut);
|
||||
|
||||
// create list of remaining other cuts
|
||||
std::vector<std::shared_ptr<const Cut>> remaining_cuts_without_try;
|
||||
remaining_cuts_without_try.clear();
|
||||
for (int idx_other=0; idx_other < remaining_cuts.size(); ++idx_other) {
|
||||
if (idx_other == idx_try) continue;
|
||||
|
||||
auto cut_other = remaining_cuts.at(idx_other);
|
||||
remaining_cuts_without_try.push_back(cut_other);
|
||||
}
|
||||
|
||||
// solve for tried remaining cuts
|
||||
trysol = this->arrangeCutIteration(trysol, remaining_cuts_without_try);
|
||||
|
||||
// keep best solution
|
||||
if (!ret_is_defined || trysol.isBetterThan(best_solution)) {
|
||||
best_solution = trysol;
|
||||
if (current_solution.rods() == 0) {
|
||||
std::cout << "Better Solution: ";
|
||||
best_solution.print(true);
|
||||
}
|
||||
ret_is_defined = true;
|
||||
}
|
||||
}
|
||||
|
||||
return best_solution;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
int main(void) {
|
||||
CutRequest cr;
|
||||
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();
|
||||
|
||||
// // manual solve
|
||||
// CutSolution cs;
|
||||
// for (auto c: cr.cuts()) {
|
||||
// cs.addCut(c);
|
||||
// }
|
||||
// cs.print();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue