Skip to content

Commit

Permalink
All Random approach; new LNS; order by number of hard constraints; Di…
Browse files Browse the repository at this point in the history
…vision bug-fix;
  • Loading branch information
ADDALemos committed Jun 3, 2019
1 parent c86b673 commit 7c8d902
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 12 deletions.
5 changes: 3 additions & 2 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,10 @@ int main(int argc, char **argv) {


if (!quiet) std::cout << "Starting Reading File: " << argv[1] << std::endl;
Instance *instance = readInputXML("/Volumes/MAC/ClionProjects/timetabler/data/input/ITC-2019/muni-fsps-spr17.xml");
Instance *instance = readInputXML(argv[1]);
printProblemStats(instance);


if (!quiet) std::cout << getTimeSpent() << std::endl;
/*if (!quiet) std::cout << "Compacting " << std::endl;
instance->compact();
Expand All @@ -83,7 +84,7 @@ int main(int argc, char **argv) {
genSingleShot(instance, runner, argv[4]);
std::exit(42); */

auto *s = new LocalSearch(4, .6, instance, 3600);
auto *s = new LocalSearch(10000, .6, instance, 360000);
s->GRASP();
if (!quiet) std::cout << "Solution Found: Writing output file" << std::endl;
writeOutputXML("/Volumes/MAC/ClionProjects/timetabler/data/output/ITC-2019/" + instance->getName() +
Expand Down
15 changes: 10 additions & 5 deletions solver/LSDivided.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,18 @@ class LSDivided {
}
} else {
for (int k = 0; k < instance->getClasses()[i]->getHard().size(); ++k) {
for (int l = 0; l < instance->getClasses()[i]->getHard()[k]->getClasses().size(); ++l) {
if (div[j].find(instance->getClasses()[i]->getHard()[k]->getClasses()[l]) !=
for (int l0 = 0; l0 < instance->getClasses()[i]->getHard()[k]->getClasses().size(); ++l0) {
if (div[j].find(instance->getClasses()[i]->getHard()[k]->getClasses()[l0]) !=
div[j].end()) {
isHere = true;
div[j].insert(instance->getClasses()[i]->getHard()[k]->getClasses()[l]);
std::cout << j << " " << instance->getClasses()[i]->getHard()[k]->getClasses()[l]
<< std::endl;
for (int l = 0;
l < instance->getClasses()[i]->getHard()[k]->getClasses().size(); ++l) {
div[j].insert(instance->getClasses()[i]->getHard()[k]->getClasses()[l]);
std::cout << j << " "
<< instance->getClasses()[i]->getHard()[k]->getClasses()[l]
<< std::endl;
}
break;
}
}

Expand Down
243 changes: 238 additions & 5 deletions solver/LocalSearch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,82 @@ void LocalSearch::LNS() {
}


void LocalSearch::allRandom() {
int a = 0;
while (a < instance->getClasses().size()) {
std::default_random_engine generatorC(seedHandler());
std::uniform_int_distribution<int> distributionC(0,
instance->getClasses().size() -
1);
int c = distributionC(generatorC);
std::default_random_engine generatorR(seedHandler());
std::uniform_int_distribution<int> distributionR(0,
instance->getClasses()[c]->getPossibleRooms().size() -
1);
std::default_random_engine generatorT(seedHandler());
std::uniform_int_distribution<int> distributionT(0,
instance->getClasses()[c]->getLectures().size() -
1);
int t = distributionT(generatorT);
int r =
distributionR(generatorR);
if (instance->getClasses()[c]->getPossibleRooms().size() > 0) {
if (isAllocable(c,
instance->getClasses()[c]->getLectures()[t]->getWeeks(),
instance->getClasses()[c]->getLectures()[t]->getDays(),
instance->getClasses()[c]->getLectures()[t]->getStart(),
instance->getClasses()[c]->getLectures()[t]->getLenght(),
instance->getClasses()[c]->getPossibleRoomPair(
r).first.getId()) == 0) {
current[c] = new Solution(c, instance->getClasses()[c]->getLectures()[t]->getStart(),
instance->getClasses()[c]->getPossibleRoomPair(
r).first.getId(),
instance->getClasses()[c]->getLectures()[t]->getWeeks(),
instance->getClasses()[c]->getLectures()[t]->getDays(),
instance->getClasses()[c]->getLectures()[t]->getLenght(), 0, 0);
}
} else {
if (isAllocable(c,
instance->getClasses()[c]->getLectures()[t]->getWeeks(),
instance->getClasses()[c]->getLectures()[t]->getDays(),
instance->getClasses()[c]->getLectures()[t]->getStart(),
instance->getClasses()[c]->getLectures()[t]->getLenght(),
-1) == 0) {
current[c] = new Solution(c, instance->getClasses()[c]->getLectures()[t]->getStart(),
-1,
instance->getClasses()[c]->getLectures()[t]->getWeeks(),
instance->getClasses()[c]->getLectures()[t]->getDays(),
instance->getClasses()[c]->getLectures()[t]->getLenght(), 0, 0);
} else {
currentV += INT_MAX;
}
}
a++;
}


}



void LocalSearch::GRASP() {
lsDivided = new LSDivided(instance, false);
lsDivided->init();
greedyStu();
printTime();
for (int i = 0; i < MAX_ITERATIONS && getTimeSpent() <= time; i++) {
init();
printTime();
Greedy();
Greedy1();
printTime();
store();
printStatus(i);
Local();
Local1();
//allRandom();
store();
printStatus(i);
printTime();



}
printFinal();
Expand Down Expand Up @@ -80,7 +140,7 @@ void LocalSearch::init() {
currentV = 0;
tabu.clear();
}

//remove all

void LocalSearch::store() {
if (eval()) {
Expand Down Expand Up @@ -117,11 +177,13 @@ void LocalSearch::Greedy1() {
while ((instance->getClasses().size() - alreadyDone) != allocation) {

int maxCost = INT_MAX;
bool maxCostB = false;
for (int part = 0; part < lsDivided->div.size(); part++) {
for (std::set<int>::iterator it = lsDivided->div[part].begin(); it != lsDivided->div[part].end(); ++it) {
int i = instance->getClass(*it)->getOrderID();
if ((instance->getClasses()[i]->getPossibleRooms().size() +
instance->getClasses()[i]->getLectures().size()) > sizeWindow) {
maxCostB = true;
if (current[instance->getClasses()[i]->getOrderID()] == nullptr) {
if (instance->getClasses()[i]->getPossibleRooms().size() > 0) {
std::default_random_engine generatorR(seedHandler());
Expand Down Expand Up @@ -163,6 +225,10 @@ void LocalSearch::Greedy1() {
}
}
}
if (!maxCostB) {
maxCost--;
maxCostB = false;
}


//std::cout<<tabu.size()<<std::endl;
Expand Down Expand Up @@ -306,6 +372,8 @@ void LocalSearch::Greedy() {
for (int part = 0; part < lsDivided->div.size(); part++) {
for (std::set<int>::iterator it = lsDivided->div[part].begin(); it != lsDivided->div[part].end(); ++it) {
int i = instance->getClass(*it)->getOrderID();
if (maxCons < instance->getClasses()[i]->getHard().size())
maxCost = instance->getClasses()[i]->getHard().size();
if ((instance->getClasses()[i]->getPossibleRooms().size() +
instance->getClasses()[i]->getLectures().size()) == wind) {
futureAlloc++;
Expand Down Expand Up @@ -569,7 +637,7 @@ int LocalSearch::checkUpdate(int maxCost, int id, int time, const std::pair<Room
}


void LocalSearch::Local() {
void LocalSearch::Local1() {

int cost = 0;
int old = 0;
Expand Down Expand Up @@ -604,6 +672,7 @@ void LocalSearch::Local() {
current[instance->getClass(
instance->getClasses()[i]->getHard()[j]->getClasses()[k])->getOrderID()] = sp2;
currentV -= INT_MAX;
//bigSwamp=true;
break;
}
}
Expand Down Expand Up @@ -661,6 +730,170 @@ void LocalSearch::Local() {

}

void LocalSearch::Local2() {
std::vector<int> remo1;
std::vector<Solution *> oldSol;

for (int i = 0; i < instance->getClasses().size(); ++i) {
if (current[instance->getClasses()[i]->getOrderID()] == nullptr) {
for (int l = 0; l < this->instance->getClasses()[i]->getPossibleRooms().size(); ++l) {
for (int m = 0; m < this->instance->getClasses()[i]->getLectures().size(); ++m) {
int remo = 0;
while ((remo = isAllocable(i, instance->getClasses()[i]->getLectures()[l]->getWeeks(),
instance->getClasses()[i]->getLectures()[l]->getDays(),
instance->getClasses()[i]->getLectures()[l]->getStart(),
instance->getClasses()[i]->getLectures()[l]->getLenght(),
instance->getClasses()[i]->getPossibleRoomPair(l).first.getId())) !=
0) {
remo1.push_back(remo);
oldSol.push_back(current[instance->getClasses()[remo]->getOrderID()]);
current[instance->getClasses()[remo]->getOrderID()] = nullptr;
}
}
}

}
}
int maxCost = INT_MAX;
for (int j = 0; j < remo1.size(); ++j) {
std::default_random_engine generatorR(seedHandler());
std::uniform_int_distribution<int> distributionR(0,
instance->getClasses()[remo1[j]]->getPossibleRooms().size() -
1);
std::default_random_engine generatorT(seedHandler());
std::uniform_int_distribution<int> distributionT(0,
instance->getClasses()[remo1[j]]->getLectures().size() -
1);
int it = 0;
int t = distributionT(generatorT), r = distributionR(generatorR);
while (checkUpdate(maxCost, remo1[j], t, instance->getClasses()[remo1[j]]->getPossibleRoomPair(r)) != 0 &&
it <= instance->getClasses()[remo1[j]]->getPossibleRooms().size() *
instance->getClasses()[remo1[j]]->getLectures().size()) {

r = distributionR(generatorR);

t = distributionT(generatorT);
it++;

}

}
while (!tabu.empty()) {
std::default_random_engine generator(seedHandler());
std::uniform_int_distribution<int> distribution(0, tabu.size() - 1);
int l = distribution(generator);
if (current[instance->getClasses()[tabu[l]->getLecture()]->getOrderID()] != nullptr) {
tabu.erase(tabu.begin() + l);
} else {
int co = assign(tabu[l]);
if (co == 0) {
//std::cout<<*tabu[l]<<" A"<<instance->getClasses()[tabu[l]->getLecture()]->getId()<<" "<<(instance->getClasses()[tabu[l]->getLecture()]->getPossibleRooms().size() +
// instance->getClasses()[tabu[l]->getLecture()]->getLectures().size() == wind)<<std::endl;
currentV -= INT_MAX;
}
}
}
}

void LocalSearch::Local() {

int cost = 0;
int old = 0;
bool bigmove = true;
std::cout << "LNS: " << getTimeSpent() << std::endl;
while (bigmove) {
bool bigSwamp = false;
for (int i = 0; i < instance->getClasses().size(); ++i) {
if (current[instance->getClasses()[i]->getOrderID()] == nullptr) {
for (int j = 0; j < instance->getClasses()[i]->getHard().size(); ++j) {
std::vector<Solution *> t;
std::vector<std::vector<Solution *>> p2;
std::vector<Solution *> p1;
for (int k = 0; k < instance->getClasses()[i]->getHard()[j]->getClasses().size(); ++k) {
if (current[instance->getClass(
instance->getClasses()[i]->getHard()[j]->getClasses()[k])->getOrderID()] != nullptr) {
p1 = findPossibleMove(i);
if (p1.size() == 0) {
continue;
}
t.push_back(current[instance->getClass(
instance->getClasses()[i]->getHard()[j]->getClasses()[k])->getOrderID()]);
current[instance->getClass(
instance->getClasses()[i]->getHard()[j]->getClasses()[k])->getOrderID()] = nullptr;

p2.push_back(findPossibleMove(instance->getClass(
instance->getClasses()[i]->getHard()[j]->getClasses()[k])->getOrderID()));


/*while(n<instance->getClasses()[i]->getPossibleRooms().size()*instance->getClasses()[i]->getLectures().size()) {
tryMove(i, n);
tryMove(instance->getClass(
instance->getClasses()[i]->getHard()[j]->getClasses()[k])->getOrderID(), 0);
if (current[instance->getClass(
instance->getClasses()[i]->getHard()[j]->getClasses()[k])->getOrderID()] !=
nullptr && current[instance->getClasses()[i]->getOrderID()] != nullptr) {
currentV -= INT_MAX;
bigSwamp = true;
break;
}
current[instance->getClass(instance->getClasses()[i]->getHard()[j]->getClasses()[k])->getOrderID()]= t;
current[i]= nullptr;
n++;
}*/


}


}
for (std::vector<Solution *> temp: p2) {
for (Solution *sp1: p1) {
Solution *s = nullptr;
for (Solution *sp2: temp) {
current[instance->getClasses()[i]->getOrderID()] = sp1;
if (isAllocable(sp2->getLecture(), sp2->getSolWeek(), sp2->getSolDays(),
sp2->getSolStart(), sp2->getDuration(), sp2->getSolRoom())) {
current[sp2->getLecture()] = sp2;
s = sp2;
currentV -= INT_MAX;
//bigSwamp=true;
break;
}
}
if (current[instance->getClasses()[i]->getOrderID()] != nullptr &&
s !=
nullptr)
break;

}

}
int x = 0;
for (std::vector<Solution *> temp: p2) {
if (temp.size() > 0) {
if (current[temp[0]->getLecture()] == nullptr)
current[temp[0]->getLecture()] = t[x];
}
x++;
}


if (current[instance->getClasses()[i]->getOrderID()] != nullptr) {
break;
}
}
}
}


if (!bigSwamp)
bigmove = false;
}
std::cout << "LNS-END: " << getTimeSpent() << std::endl;


}

int
LocalSearch::isAllocable(int lectureID, std::string week, std::string day, int start, int duration, int roomID) {
Expand Down
8 changes: 8 additions & 0 deletions solver/LocalSearch.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extern double getTimeSpent();

class LocalSearch {
protected:
int maxCons = 0;
int MAX_ITERATIONS = 5;
LSDivided *lsDivided;
int time;
Expand Down Expand Up @@ -52,6 +53,8 @@ class LocalSearch {

protected:

void allRandom();

virtual void init();

void tryMove(int i, int i1);
Expand All @@ -70,6 +73,11 @@ class LocalSearch {

virtual void Local();

virtual void Local1();

void Local2();


virtual int
isAllocable(int lectureID, std::string week, std::string day, int start, int duration, int roomID);

Expand Down

0 comments on commit 7c8d902

Please sign in to comment.