Skip to content

Commit

Permalink
Hungarian handles jobs with missing or disordered steps
Browse files Browse the repository at this point in the history
The steps are re-ordered and the missing steps are assigned a very large
cost so the optimization rejects them.
  • Loading branch information
JamesBremner committed Mar 6, 2017
1 parent 9ba3fcc commit 98fa66b
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 30 deletions.
38 changes: 19 additions & 19 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ void TestSchedule3()
J.Add(
"Wash",
3 );
J.Add(
"Mend",
3 );
// J.Add(
// "Mend",
// 3 );
S.Add( J );

cJob J2("Francine", cJob::eType::anyone );
Expand All @@ -139,9 +139,9 @@ void TestSchedule3()
J2.Add(
"Wash",
3 );
J2.Add(
"Mend",
3 );
// J2.Add(
// "Mend",
// 3 );

S.Add( J2 );

Expand All @@ -155,24 +155,24 @@ void TestSchedule3()
J3.Add(
"Wash",
2 );
J3.Add(
"Mend",
3 );
// J3.Add(
// "Mend",
// 3 );

S.Add( J3 );

cJob J4("Xavier", cJob::eType::anyone );
// J4.Add(
// "Clean",
// 3) ;
// J4.Add(
// "Sweep",
// 3 );
// J4.Add(
// "Wash",
// 2 );
J4.Add(
"Clean",
3) ;
J4.Add(
"Sweep",
3 );
J4.Add(
"Wash",
2 );
J4.Add(
"Mend",
"XMend",
3 );

S.Add( J4 );
Expand Down
14 changes: 11 additions & 3 deletions src/cSchedule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,16 @@ void cJob::Add(
myStep.push_back( cStep( "", machine, time ) );
myStep.back().Previous( previous );
}

void cJob::Steps( vector< cStep >& vStep )
vector< cStep > cJob::Steps()
{
vector< cStep > vs;
for( auto& s : myStep )
{
vs.push_back( s );
}
return vs;
}
void cJob::AddSteps( vector< cStep >& vStep )
{
for( auto& s : myStep )
{
Expand All @@ -89,7 +97,7 @@ void cSchedule::Steps( vector< cStep >& vStep )
vStep.clear();
for( auto& j : myJob )
{
j.Steps( vStep );
j.AddSteps( vStep );
}
}
cStep& cSchedule::FindStep( int id )
Expand Down
24 changes: 21 additions & 3 deletions src/cSchedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class cStep
json::Object json();

/** Name of machine used to process step */
string Machine()
string Machine() const
{
return myMachine;
}
Expand Down Expand Up @@ -113,6 +113,11 @@ class cStep
return myStart + myTime;
}

void Print()
{
cout << myMachine << " ";
}

private:
string myName;
string myMachine;
Expand Down Expand Up @@ -153,8 +158,21 @@ class cJob
/** Job in JSON format */
json::Object json();

/** All the steps in a job, copied into a vector */
void Steps( vector< cStep >& vStep ) ;
/** Steps in the job
@return new vector containing steps in this job
These are copies of the steps in the job,
with the same ID as the originals
*/
vector< cStep > Steps();

/** All the steps in a job, copies added to a vector */
void AddSteps( vector< cStep >& vStep ) ;

void SetSteps( vector< cStep >& vStep )
{
myStep = vStep;
}

/** Find step with id */
cStep& FindStep( int id );
Expand Down
58 changes: 54 additions & 4 deletions src/cShop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
#include <vector>
#include <set>
#include <cstdlib>

#include <cfloat>
#include <algorithm>

#include "cSchedule.h"
#include "cShop.h"
Expand Down Expand Up @@ -45,9 +46,14 @@ float cShop::Manufacture( cSchedule& S )
class cHungarianCostMatrix
{
public:
cHungarianCostMatrix( cSchedule& S )
cHungarianCostMatrix( cSchedule& S, cShop& shop )
: myS ( S )
, myShop( shop )
{
// Ensure all jobs have steps for every machine in machine order
// arranged in the same, alphabetical order
AddMissingSteps();

N = S.CountJobs();

for( auto& worker : S )
Expand Down Expand Up @@ -144,6 +150,9 @@ class cHungarianCostMatrix

void Step3()
{
cout << "step3\n";
Print();

int CountTasksAssigned = 0;
for( int row = 0; row < N; row++ )
{
Expand Down Expand Up @@ -211,6 +220,46 @@ class cHungarianCostMatrix
return Cost;
}

void AddMissingSteps()
{

for( auto& job : myS )
{
vector< cStep > vStep;
vector< cStep > vNew;
job.AddSteps( vStep );

for( auto& s : vStep )
s.Print();
cout << "\n";

for( auto& machine : myShop )
{

auto sit = find_if( vStep.begin(),
vStep.end(),
[&]( const cStep& s )
{
return ( s.Machine() == machine.Name() );
});
if( sit == vStep.end() )
{
// the job had no step specify the cost of running on this machine
// so add one with a huge cost
vNew.push_back( cStep("",machine.Name(),FLT_MAX ));
}
else
{
vNew.push_back( *sit );
}
}
for( auto& s : vNew )
s.Print();
cout << "\n";
job.SetSteps( vNew );
}
}

void Print()
{
for( int row = 0; row < N; row++ )
Expand All @@ -222,8 +271,9 @@ class cHungarianCostMatrix
cout << "\n";
}
}

private:
cSchedule& myS;
cShop& myShop;
int N;
vector< cStep > M;
};
Expand All @@ -236,7 +286,7 @@ float cShop::Hungarian( cSchedule& S )
throw std::runtime_error(
"Hungarian algorithm needs same number of workers and tasks");

cHungarianCostMatrix H( S );
cHungarianCostMatrix H( S, *this );
H.SubtractRowMinimums();
if( H.IsZeroInEveryColumn() )
{
Expand Down
17 changes: 16 additions & 1 deletion src/cShop.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,18 @@ class cMachine
float myBusyUntil;
};

/** Shop containing the machines reuired by jobs */
/** Shop containing the machines required by jobs */

class cShop
{
public:
/** construct with all machines mentioned
@parasm[in] S the schedule where the macines are mentioned
The machines are constructed as they are found in the jobs found in the schedule.
The machines are stored in a set, keyed by their names,
so one machine is construted for each unique name found
and they are stored in alphabetica order.
*/
cShop( cSchedule& S );

Expand All @@ -61,12 +66,22 @@ class cShop
For this, every cJob must be type anyone
and each step in the job models the cost of assigning the job to a different machine
Jobs without steps mentioning a machine are assumed to be too expensive to run there.
https://en.wikipedia.org/wiki/Hungarian_algorithm
*/
float Hungarian( cSchedule& S );

set< cMachine >::const_iterator begin()
{
return myMachine.begin();
}
set< cMachine >::const_iterator end()
{
return myMachine.end();
}

private:
set < cMachine > myMachine;
};
Expand Down

0 comments on commit 98fa66b

Please sign in to comment.