Hallo,

 I now understand the reasoning for using the boolean matrix
so that each unary constraint corresponds to a certain resource
and to the starting times of the resource.

but thaw it all make sense now I still don't get the result
I expect. There are no different resources assigned to the task
though different resources can do the task faster since they
can work in parallel,
and another problem is that when I specify constraints
for what resources can do a certain task I get no solution
again.

I attached a small sample that behaves like my program
maybe someone with more experience can help me.

thanks.
#ifndef AllocTime_h__
#define AllocTime_h__

#include <gecode/driver.hh>
#include <gecode/minimodel.hh>
#include <gecode/scheduling.hh>

#define GE_USE_GIST

#ifdef GE_USE_GIST
#include <gecode/gist.hh>
#endif

using namespace Gecode;

/*
 * each resource can do certain tasks,
 * some tasks can be done only after another tasks
 * each resource can do a task at a time
 * each resource has a availability interval
 */
class AllocTime : public MinimizeScript {
public:
        enum {
                SEARCH_DFS,
                SEARCH_BAB,
                SEARCH_RESTART
        };

private:
        const static int nrResources = 21;
        const static int nrTasks = 5;

        IntVarArray resources;
        IntVarArray start_times;
        IntVarArray end_times;

        IntVar z;
public:
        AllocTime(const Options & options) : MinimizeScript() {
                // only some resources can be assigned to certain tasks
                int _resources[5][7] = {
                        {  0,  1,  2,  3,  4,  5,  6 },
                        {  0,  1,  2,  3,  4,  5,  6 },
                        {  7,  8,  9, 10, 11, 12, 13 },
                        {  7,  8,  9, 10, 11, 12, 13 },
                        { 14, 15, 16, 17, 18, 19, 20 } };
                resources = IntVarArray(*this, nrTasks, 0, nrResources - 1);
                for(int i=0; i<nrTasks; i++) {
                        dom(*this, resources[i], IntArgs(7, _resources[i]));
                }

                const int maxTime = 660 * 7; // max interval * nr days
                start_times = IntVarArray(*this, nrTasks, 0, maxTime);
                end_times = IntVarArray(*this, nrTasks, 0, maxTime);
                z = IntVar(*this, 0, maxTime);

                int _durations[5] = {12, 60, 60, 60, 60};
                IntArgs durations(nrTasks, _durations);

                for(int i=0; i<nrTasks; i++) {
                        rel(*this, end_times[i] == start_times[i] + 
durations[i]);
                }

                // tasks have order
                for(int i=1; i<nrTasks; i++) {
                        rel(*this, end_times[0], IRT_LQ, start_times[i]);
                }
                                                
                BoolVarArgs _m(*this, nrTasks*nrResources, 0, 1);
                Matrix<BoolVarArgs> m(_m, nrTasks, nrResources);
                for (int j=0; j<nrTasks; j++) {
                        channel(*this, m.col(j), resources[j]);
                }
                for (int i=0; i<nrResources; i++) {
                        for (int j=0; j<nrTasks; j++) {
                                IntSet v = getTimeIntervals(i);
                                dom(*this, start_times[j], v, m(j, i));
                        }
                        unary(*this, start_times, durations, m.row(i));
                }
                
                for (int j=0; j<nrTasks; j++) {
                        linear(*this, m.col(j), IRT_EQ, 1); // each task is 
scheduled on exactly one resource
                }
                
                // we minimize the total time
                max(*this, end_times, z, options.icl());

                branch(*this, resources, INT_VAR_NONE, INT_VAL_MIN);
                branch(*this, start_times, INT_VAR_NONE, INT_VAL_MIN);
                branch(*this, end_times, INT_VAR_NONE, INT_VAL_MIN);
        }

        virtual IntVar cost(void) const {
                return z;
        }

        virtual void print(std::ostream& os) const {
                os << "cost: " << z << std::endl;
                os << "nr tasks: " << nrTasks << std::endl;
                for(int i = 0; i < nrTasks; i++) {
                        os << i << ": s" << start_times[i] << " e" << 
end_times[i] << " res: " << resources[i] << std::endl;
                }
        }

private:
        // each resource has a availability period, based on that we calculate 
the starting intervals
        IntSet getTimeIntervals(int resource) {
                int intervals[21][2][2] =
              { {{ 60 , 360 }, { 420 , 660 } },
                                {{ 720 , 1020 }, { 1080 , 1320 }},
                                {{ 1380 , 1680 }, { 1740 , 1980 }},
                                {{ 2040 , 2340 }, { 2400 , 2640 }},
                                {{ 2700 , 3000 }, { 3060 , 3300 }},
                                {{ }, { }},
                                {{ }, { }},
                                {{ 60 , 360 }, { 420 , 660 }},
                                {{ 720 , 1020 }, { 1080 , 1320 }},
                                {{ 1380 ,  1680 }, { 1740 , 1980 }},
                                {{ 2040 , 2340 }, { 2400 , 2640 }},
                                {{ 2700 , 3000 }, { 3060 , 3300 }},
                                {{ }, { }},
                                {{ }, { }},
                                {{ 0 , 300 }, { 360 , 600 }},
                                {{ 660 , 960 }, { 1020 , 1260 }},
                                {{ 1320 , 1620 }, { 1680 , 1920 }},
                                {{ 1980 , 2280 }, { 2340 , 2580 }},
                                {{ 2640 , 2940 }, { 3000 , 3240 }},
                                {{ 3360 , 3600 }, {}},
                                {{ }, { }} };
                int s[] = { 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 
2, 2, 1, 0 };

                if(s[resource] == 0) {
                        return IntSet::empty;
                }
                else {
                        return IntSet(intervals[resource], s[resource]);
                }
        }

public:
        AllocTime(bool share, AllocTime& s) : MinimizeScript(share,s) {
                resources.update(*this, share, s.resources);
                start_times.update(*this, share, s.start_times);
                end_times.update(*this, share, s.end_times);

                z.update(*this, share, s.z);
        }

        virtual Space* copy(bool share) {
                return new AllocTime(share,*this);
        }

#ifdef GE_USE_GIST
public:
        virtual void compare(const Space& s, std::ostream& os) const {
                const AllocTime& aa = static_cast<const AllocTime&>(s);
                os << Gist::Comparator::compare("z", z, aa.z) << std::endl;
                for(int i=0; i<this->nrTasks; i++) {
                        std::string msg = "r";
                        os << Gist::Comparator::compare(msg, resources[i], 
aa.resources[i]) << ", ";
                }
                os << std::endl;
                for(int i=0; i<this->nrTasks; i++) {
                        std::string msg = "t";
                        os << Gist::Comparator::compare(msg, start_times[i], 
aa.start_times[i]) << ", ";
                }
                os << std::endl;
        }

#endif
};

#endif // AllocTime_h__
_______________________________________________
Gecode users mailing list
[email protected]
https://www.gecode.org/mailman/listinfo/gecode-users

Reply via email to