Import from internal git

This commit is contained in:
Laurent
2025-05-14 11:46:50 +02:00
parent 4e258f2afa
commit 55ccf5dae8
18 changed files with 2618 additions and 0 deletions

78
.gitignore vendored Normal file
View File

@@ -0,0 +1,78 @@
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
.idea/sonarlint.xml # see https://community.sonarsource.com/t/is-the-file-idea-idea-idea-sonarlint-xml-intended-to-be-under-source-control/121119
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

22
PertGraphGenerator.iml Normal file
View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/bin" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="file://$USER_HOME$/Downloads/jgrapht-1.5.2/lib" />
</CLASSES>
<JAVADOC />
<SOURCES />
<jarDirectory url="file://$USER_HOME$/Downloads/jgrapht-1.5.2/lib" recursive="false" />
</library>
</orderEntry>
</component>
</module>

204
graphs/AUTOSAVE.xml Normal file
View File

@@ -0,0 +1,204 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--Created with Graph Editor-->
<graph title="PERT : exemple 2" type="PERT">
<nodes>
<node id="1">
<x>94</x>
<y>278</y>
<radius>30</radius>
<label>1</label>
<color>#FFFFFF</color>
<start>0</start>
<end>0</end>
</node>
<node id="2">
<x>334</x>
<y>86</y>
<radius>30</radius>
<label>2</label>
<color>#FFFFFF</color>
<start>16</start>
<end>16</end>
</node>
<node id="3">
<x>249</x>
<y>367</y>
<radius>30</radius>
<label>3</label>
<color>#FFFFFF</color>
<start>8</start>
<end>18</end>
</node>
<node id="4">
<x>567</x>
<y>87</y>
<radius>30</radius>
<label>4</label>
<color>#FFFFFF</color>
<start>16</start>
<end>16</end>
</node>
<node id="5">
<x>315</x>
<y>524</y>
<radius>30</radius>
<label>5</label>
<color>#FFFFFF</color>
<start>8</start>
<end>18</end>
</node>
<node id="6">
<x>332</x>
<y>228</y>
<radius>30</radius>
<label>6</label>
<color>#FFFFFF</color>
<start>19</start>
<end>20</end>
</node>
<node id="7">
<x>425</x>
<y>383</y>
<radius>30</radius>
<label>7</label>
<color>#FFFFFF</color>
<start>19</start>
<end>22</end>
</node>
<node id="8">
<x>328</x>
<y>656</y>
<radius>30</radius>
<label>8</label>
<color>#FFFFFF</color>
<start>3</start>
<end>33</end>
</node>
<node id="9">
<x>625</x>
<y>373</y>
<radius>30</radius>
<label>9</label>
<color>#FFFFFF</color>
<start>23</start>
<end>23</end>
</node>
<node id="10">
<x>798</x>
<y>582</y>
<radius>30</radius>
<label>10</label>
<color>#FFFFFF</color>
<start>40</start>
<end>40</end>
</node>
</nodes>
<edges>
<edge>
<source>1</source>
<target>2</target>
<stroke>2</stroke>
<label>A/16</label>
<color>#0000FF</color>
</edge>
<edge>
<source>1</source>
<target>3</target>
<stroke>1</stroke>
<label>B/8</label>
<color>#000000</color>
</edge>
<edge>
<source>2</source>
<target>4</target>
<stroke>2</stroke>
<label>C/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>3</source>
<target>5</target>
<stroke>1</stroke>
<label>D/0</label>
<color>#FF0000</color>
</edge>
<edge>
<source>1</source>
<target>6</target>
<stroke>1</stroke>
<label>E/1</label>
<color>#000000</color>
</edge>
<edge>
<source>6</source>
<target>7</target>
<stroke>1</stroke>
<label>F/0</label>
<color>#FF0000</color>
</edge>
<edge>
<source>1</source>
<target>8</target>
<stroke>1</stroke>
<label>G/3</label>
<color>#000000</color>
</edge>
<edge>
<source>6</source>
<target>9</target>
<stroke>1</stroke>
<label>H/3</label>
<color>#000000</color>
</edge>
<edge>
<source>7</source>
<target>10</target>
<stroke>1</stroke>
<label>I/18</label>
<color>#000000</color>
</edge>
<edge>
<source>4</source>
<target>6</target>
<stroke>1</stroke>
<label>J/3</label>
<color>#000000</color>
</edge>
<edge>
<source>5</source>
<target>10</target>
<stroke>1</stroke>
<label>K/4</label>
<color>#000000</color>
</edge>
<edge>
<source>8</source>
<target>10</target>
<stroke>1</stroke>
<label>L/7</label>
<color>#000000</color>
</edge>
<edge>
<source>9</source>
<target>10</target>
<stroke>2</stroke>
<label>M/17</label>
<color>#0000FF</color>
</edge>
<edge>
<source>5</source>
<target>9</target>
<stroke>1</stroke>
<label>N/5</label>
<color>#000000</color>
</edge>
<edge>
<source>4</source>
<target>9</target>
<stroke>2</stroke>
<label>O/7</label>
<color>#0000FF</color>
</edge>
</edges>
</graph>

Binary file not shown.

548
graphs/big-graph.xml Normal file
View File

@@ -0,0 +1,548 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--Created with Graph Editor-->
<graph title="PERT : exemple 2" type="PERT">
<nodes>
<node id="0">
<x>148</x>
<y>568</y>
<radius>30</radius>
<label>1</label>
<color>#FFFFFF</color>
<start>0</start>
<end>0</end>
</node>
<node id="1">
<x>379</x>
<y>421</y>
<radius>30</radius>
<label>2</label>
<color>#FFFFFF</color>
<start>11</start>
<end>12</end>
</node>
<node id="2">
<x>699</x>
<y>235</y>
<radius>30</radius>
<label>3</label>
<color>#FFFFFF</color>
<start>28</start>
<end>31</end>
</node>
<node id="3">
<x>827</x>
<y>246</y>
<radius>30</radius>
<label>4</label>
<color>#FFFFFF</color>
<start>29</start>
<end>32</end>
</node>
<node id="4">
<x>408</x>
<y>554</y>
<radius>30</radius>
<label>5</label>
<color>#FFFFFF</color>
<start>6</start>
<end>6</end>
</node>
<node id="5">
<x>624</x>
<y>463</y>
<radius>30</radius>
<label>6</label>
<color>#FFFFFF</color>
<start>17</start>
<end>55</end>
</node>
<node id="6">
<x>569</x>
<y>660</y>
<radius>30</radius>
<label>7</label>
<color>#FFFFFF</color>
<start>25</start>
<end>25</end>
</node>
<node id="7">
<x>694</x>
<y>795</y>
<radius>30</radius>
<label>8</label>
<color>#FFFFFF</color>
<start>44</start>
<end>44</end>
</node>
<node id="8">
<x>718</x>
<y>564</y>
<radius>30</radius>
<label>9</label>
<color>#FFFFFF</color>
<start>28</start>
<end>50</end>
</node>
<node id="9">
<x>642</x>
<y>328</y>
<radius>30</radius>
<label>10</label>
<color>#FFFFFF</color>
<start>13</start>
<end>14</end>
</node>
<node id="10">
<x>962</x>
<y>-92</y>
<radius>30</radius>
<label>11</label>
<color>#FFFFFF</color>
<start>32</start>
<end>47</end>
</node>
<node id="11">
<x>1111</x>
<y>500</y>
<radius>30</radius>
<label>12</label>
<color>#FFFFFF</color>
<start>18</start>
<end>43</end>
</node>
<node id="12">
<x>961</x>
<y>-173</y>
<radius>30</radius>
<label>13</label>
<color>#FFFFFF</color>
<start>38</start>
<end>44</end>
</node>
<node id="13">
<x>1054</x>
<y>801</y>
<radius>30</radius>
<label>14</label>
<color>#FFFFFF</color>
<start>47</start>
<end>47</end>
</node>
<node id="14">
<x>990</x>
<y>147</y>
<radius>30</radius>
<label>15</label>
<color>#FFFFFF</color>
<start>39</start>
<end>54</end>
</node>
<node id="15">
<x>1241</x>
<y>443</y>
<radius>30</radius>
<label>16</label>
<color>#FFFFFF</color>
<start>59</start>
<end>59</end>
</node>
<node id="16">
<x>1184</x>
<y>143</y>
<radius>30</radius>
<label>17</label>
<color>#FFFFFF</color>
<start>59</start>
<end>74</end>
</node>
<node id="17">
<x>904</x>
<y>466</y>
<radius>30</radius>
<label>18</label>
<color>#FFFFFF</color>
<start>31</start>
<end>32</end>
</node>
<node id="18">
<x>923</x>
<y>689</y>
<radius>30</radius>
<label>19</label>
<color>#FFFFFF</color>
<start>46</start>
<end>47</end>
</node>
<node id="19">
<x>1135</x>
<y>248</y>
<radius>30</radius>
<label>20</label>
<color>#FFFFFF</color>
<start>29</start>
<end>62</end>
</node>
<node id="20">
<x>1354</x>
<y>193</y>
<radius>30</radius>
<label>21</label>
<color>#FFFFFF</color>
<start>52</start>
<end>58</end>
</node>
<node id="21">
<x>1485</x>
<y>536</y>
<radius>30</radius>
<label>22</label>
<color>#FFFFFF</color>
<start>61</start>
<end>62</end>
</node>
<node id="22">
<x>1413</x>
<y>393</y>
<radius>30</radius>
<label>23</label>
<color>#FFFFFF</color>
<start>60</start>
<end>66</end>
</node>
<node id="23">
<x>1621</x>
<y>-38</y>
<radius>30</radius>
<label>24</label>
<color>#FFFFFF</color>
<start>76</start>
<end>76</end>
</node>
<node id="24">
<x>1992</x>
<y>389</y>
<radius>30</radius>
<label>25</label>
<color>#FFFFFF</color>
<start>77</start>
<end>77</end>
</node>
</nodes>
<edges>
<edge>
<source>0</source>
<target>1</target>
<stroke>1</stroke>
<label>A/11</label>
<color>#000000</color>
</edge>
<edge>
<source>1</source>
<target>2</target>
<stroke>1</stroke>
<label>B/17</label>
<color>#000000</color>
</edge>
<edge>
<source>2</source>
<target>3</target>
<stroke>1</stroke>
<label>C/1</label>
<color>#000000</color>
</edge>
<edge>
<source>0</source>
<target>4</target>
<stroke>2</stroke>
<label>D/6</label>
<color>#FF0000</color>
</edge>
<edge>
<source>4</source>
<target>5</target>
<stroke>1</stroke>
<label>E/11</label>
<color>#000000</color>
</edge>
<edge>
<source>4</source>
<target>6</target>
<stroke>2</stroke>
<label>F/19</label>
<color>#FF0000</color>
</edge>
<edge>
<source>0</source>
<target>7</target>
<stroke>1</stroke>
<label>G/10</label>
<color>#000000</color>
</edge>
<edge>
<source>4</source>
<target>8</target>
<stroke>1</stroke>
<label>H/3</label>
<color>#000000</color>
</edge>
<edge>
<source>1</source>
<target>9</target>
<stroke>1</stroke>
<label>I/2</label>
<color>#000000</color>
</edge>
<edge>
<source>1</source>
<target>10</target>
<stroke>1</stroke>
<label>J/18</label>
<color>#000000</color>
</edge>
<edge>
<source>4</source>
<target>11</target>
<stroke>1</stroke>
<label>K/12</label>
<color>#000000</color>
</edge>
<edge>
<source>2</source>
<target>12</target>
<stroke>1</stroke>
<label>L/10</label>
<color>#000000</color>
</edge>
<edge>
<source>7</source>
<target>13</target>
<stroke>2</stroke>
<label>M/3</label>
<color>#FF0000</color>
</edge>
<edge>
<source>10</source>
<target>14</target>
<stroke>1</stroke>
<label>N/7</label>
<color>#000000</color>
</edge>
<edge>
<source>9</source>
<target>15</target>
<stroke>1</stroke>
<label>O/4</label>
<color>#000000</color>
</edge>
<edge>
<source>14</source>
<target>16</target>
<stroke>1</stroke>
<label>P/20</label>
<color>#000000</color>
</edge>
<edge>
<source>9</source>
<target>17</target>
<stroke>1</stroke>
<label>Q/18</label>
<color>#000000</color>
</edge>
<edge>
<source>4</source>
<target>18</target>
<stroke>1</stroke>
<label>R/19</label>
<color>#000000</color>
</edge>
<edge>
<source>11</source>
<target>19</target>
<stroke>1</stroke>
<label>S/4</label>
<color>#000000</color>
</edge>
<edge>
<source>11</source>
<target>20</target>
<stroke>1</stroke>
<label>T/15</label>
<color>#000000</color>
</edge>
<edge>
<source>18</source>
<target>21</target>
<stroke>1</stroke>
<label>U/15</label>
<color>#000000</color>
</edge>
<edge>
<source>20</source>
<target>22</target>
<stroke>1</stroke>
<label>V/8</label>
<color>#000000</color>
</edge>
<edge>
<source>16</source>
<target>23</target>
<stroke>1</stroke>
<label>W/2</label>
<color>#000000</color>
</edge>
<edge>
<source>22</source>
<target>24</target>
<stroke>1</stroke>
<label>X/11</label>
<color>#000000</color>
</edge>
<edge>
<source>3</source>
<target>10</target>
<stroke>1</stroke>
<label>Y/3</label>
<color>#000000</color>
</edge>
<edge>
<source>5</source>
<target>16</target>
<stroke>1</stroke>
<label>Z/19</label>
<color>#000000</color>
</edge>
<edge>
<source>6</source>
<target>7</target>
<stroke>2</stroke>
<label>AA/19</label>
<color>#FF0000</color>
</edge>
<edge>
<source>8</source>
<target>21</target>
<stroke>1</stroke>
<label>AB/12</label>
<color>#000000</color>
</edge>
<edge>
<source>12</source>
<target>20</target>
<stroke>1</stroke>
<label>AC/14</label>
<color>#000000</color>
</edge>
<edge>
<source>13</source>
<target>15</target>
<stroke>2</stroke>
<label>AD/12</label>
<color>#FF0000</color>
</edge>
<edge>
<source>15</source>
<target>23</target>
<stroke>2</stroke>
<label>AE/17</label>
<color>#FF0000</color>
</edge>
<edge>
<source>17</source>
<target>18</target>
<stroke>1</stroke>
<label>AF/15</label>
<color>#000000</color>
</edge>
<edge>
<source>19</source>
<target>24</target>
<stroke>1</stroke>
<label>AG/15</label>
<color>#000000</color>
</edge>
<edge>
<source>21</source>
<target>23</target>
<stroke>1</stroke>
<label>AH/14</label>
<color>#000000</color>
</edge>
<edge>
<source>23</source>
<target>24</target>
<stroke>2</stroke>
<label>AI/1</label>
<color>#FF0000</color>
</edge>
<edge>
<source>2</source>
<target>8</target>
<stroke>1</stroke>
<label>AJ/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>12</source>
<target>23</target>
<stroke>1</stroke>
<label>AK/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>0</source>
<target>12</target>
<stroke>1</stroke>
<label>AL/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>9</source>
<target>19</target>
<stroke>1</stroke>
<label>AM/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>13</source>
<target>24</target>
<stroke>1</stroke>
<label>AN/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>6</source>
<target>13</target>
<stroke>1</stroke>
<label>AO/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>3</source>
<target>19</target>
<stroke>1</stroke>
<label>AP/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>3</source>
<target>17</target>
<stroke>1</stroke>
<label>AQ/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>10</source>
<target>16</target>
<stroke>1</stroke>
<label>AR/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>15</source>
<target>22</target>
<stroke>1</stroke>
<label>AS/0</label>
<color>#0000FF</color>
</edge>
</edges>
</graph>

141
graphs/bug.xml Normal file
View File

@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--Created with Graph Editor-->
<graph title="PERT : exemple 2" type="PERT">
<nodes>
<node id="1">
<x>86</x>
<y>670</y>
<radius>30</radius>
<label>0</label>
<color>#FFFFFF</color>
<start>0</start>
<end>0</end>
</node>
<node id="2">
<x>347</x>
<y>503</y>
<radius>30</radius>
<label>1</label>
<color>#FFFFFF</color>
<start>14</start>
<end>14</end>
</node>
<node id="3">
<x>364</x>
<y>833</y>
<radius>30</radius>
<label>2</label>
<color>#FFFFFF</color>
<start>14</start>
<end>14</end>
</node>
<node id="4">
<x>654</x>
<y>758</y>
<radius>30</radius>
<label>3</label>
<color>#FFFFFF</color>
<start>33</start>
<end>33</end>
</node>
<node id="5">
<x>639</x>
<y>492</y>
<radius>30</radius>
<label>4</label>
<color>#FFFFFF</color>
<start>22</start>
<end>22</end>
</node>
<node id="6">
<x>903</x>
<y>565</y>
<radius>30</radius>
<label>5</label>
<color>#FFFFFF</color>
<start>41</start>
<end>41</end>
</node>
<node id="7">
<x>785</x>
<y>244</y>
<radius>30</radius>
<label>6</label>
<color>#FFFFFF</color>
<start>41</start>
<end>41</end>
</node>
</nodes>
<edges>
<edge>
<source>1</source>
<target>2</target>
<stroke>2</stroke>
<label>A/14</label>
<color>#FF0000</color>
</edge>
<edge>
<source>1</source>
<target>3</target>
<stroke>1</stroke>
<label>B/8</label>
<color>#000000</color>
</edge>
<edge>
<source>3</source>
<target>4</target>
<stroke>2</stroke>
<label>C/19</label>
<color>#FF0000</color>
</edge>
<edge>
<source>2</source>
<target>5</target>
<stroke>2</stroke>
<label>D/8</label>
<color>#FF0000</color>
</edge>
<edge>
<source>4</source>
<target>6</target>
<stroke>2</stroke>
<label>E/8</label>
<color>#FF0000</color>
</edge>
<edge>
<source>2</source>
<target>7</target>
<stroke>1</stroke>
<label>F/1</label>
<color>#000000</color>
</edge>
<edge>
<source>5</source>
<target>7</target>
<stroke>2</stroke>
<label>G/19</label>
<color>#FF0000</color>
</edge>
<edge>
<source>6</source>
<target>7</target>
<stroke>2</stroke>
<label>H/0</label>
<color>#FF0000</color>
</edge>
<edge>
<source>2</source>
<target>4</target>
<stroke>1</stroke>
<label>I/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>2</source>
<target>3</target>
<stroke>1</stroke>
<label>J/0</label>
<color>#0000FF</color>
</edge>
</edges>
</graph>

318
graphs/first-graph-test.xml Normal file
View File

@@ -0,0 +1,318 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--Created with Graph Editor-->
<graph title="PERT : exemple 2" type="PERT">
<nodes>
<node id="1">
<x>0</x>
<y>0</y>
<radius>30</radius>
<label>1</label>
<color>#FFFFFF</color>
<start>0</start>
<end>0</end>
</node>
<node id="2">
<x>151</x>
<y>201</y>
<radius>30</radius>
<label>2</label>
<color>#FFFFFF</color>
<start>18</start>
<end>19</end>
</node>
<node id="3">
<x>151</x>
<y>301</y>
<radius>30</radius>
<label>3</label>
<color>#FFFFFF</color>
<start>18</start>
<end>25</end>
</node>
<node id="4">
<x>151</x>
<y>401</y>
<radius>30</radius>
<label>4</label>
<color>#FFFFFF</color>
<start>15</start>
<end>15</end>
</node>
<node id="5">
<x>151</x>
<y>501</y>
<radius>30</radius>
<label>5</label>
<color>#FFFFFF</color>
<start>15</start>
<end>15</end>
</node>
<node id="6">
<x>151</x>
<y>601</y>
<radius>30</radius>
<label>6</label>
<color>#FFFFFF</color>
<start>15</start>
<end>23</end>
</node>
<node id="7">
<x>151</x>
<y>701</y>
<radius>30</radius>
<label>7</label>
<color>#FFFFFF</color>
<start>18</start>
<end>19</end>
</node>
<node id="8">
<x>151</x>
<y>801</y>
<radius>30</radius>
<label>8</label>
<color>#FFFFFF</color>
<start>18</start>
<end>39</end>
</node>
<node id="9">
<x>151</x>
<y>901</y>
<radius>30</radius>
<label>9</label>
<color>#FFFFFF</color>
<start>37</start>
<end>38</end>
</node>
<node id="10">
<x>235</x>
<y>209</y>
<radius>30</radius>
<label>10</label>
<color>#FFFFFF</color>
<start>47</start>
<end>48</end>
</node>
<node id="11">
<x>235</x>
<y>309</y>
<radius>30</radius>
<label>11</label>
<color>#FFFFFF</color>
<start>34</start>
<end>34</end>
</node>
<node id="12">
<x>235</x>
<y>409</y>
<radius>30</radius>
<label>12</label>
<color>#FFFFFF</color>
<start>34</start>
<end>41</end>
</node>
<node id="13">
<x>322</x>
<y>212</y>
<radius>30</radius>
<label>13</label>
<color>#FFFFFF</color>
<start>51</start>
<end>51</end>
</node>
<node id="14">
<x>322</x>
<y>325</y>
<radius>30</radius>
<label>14</label>
<color>#FFFFFF</color>
<start>42</start>
<end>49</end>
</node>
<node id="15">
<x>322</x>
<y>439</y>
<radius>30</radius>
<label>15</label>
<color>#FFFFFF</color>
<start>59</start>
<end>59</end>
</node>
</nodes>
<edges>
<edge>
<source>1</source>
<target>2</target>
<stroke>1</stroke>
<label>A/18</label>
<color>#000000</color>
</edge>
<edge>
<source>2</source>
<target>3</target>
<stroke>1</stroke>
<label>B/0</label>
<color>#FF0000</color>
</edge>
<edge>
<source>1</source>
<target>4</target>
<stroke>2</stroke>
<label>C/15</label>
<color>#0000FF</color>
</edge>
<edge>
<source>4</source>
<target>5</target>
<stroke>2</stroke>
<label>D/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>5</source>
<target>6</target>
<stroke>1</stroke>
<label>E/0</label>
<color>#FF0000</color>
</edge>
<edge>
<source>2</source>
<target>7</target>
<stroke>1</stroke>
<label>F/0</label>
<color>#FF0000</color>
</edge>
<edge>
<source>4</source>
<target>8</target>
<stroke>1</stroke>
<label>G/3</label>
<color>#000000</color>
</edge>
<edge>
<source>4</source>
<target>9</target>
<stroke>1</stroke>
<label>H/18</label>
<color>#000000</color>
</edge>
<edge>
<source>9</source>
<target>10</target>
<stroke>1</stroke>
<label>I/10</label>
<color>#000000</color>
</edge>
<edge>
<source>5</source>
<target>11</target>
<stroke>2</stroke>
<label>J/19</label>
<color>#0000FF</color>
</edge>
<edge>
<source>4</source>
<target>12</target>
<stroke>1</stroke>
<label>K/16</label>
<color>#000000</color>
</edge>
<edge>
<source>11</source>
<target>13</target>
<stroke>2</stroke>
<label>L/17</label>
<color>#0000FF</color>
</edge>
<edge>
<source>11</source>
<target>14</target>
<stroke>1</stroke>
<label>M/8</label>
<color>#000000</color>
</edge>
<edge>
<source>1</source>
<target>15</target>
<stroke>1</stroke>
<label>N/4</label>
<color>#000000</color>
</edge>
<edge>
<source>3</source>
<target>12</target>
<stroke>1</stroke>
<label>O/16</label>
<color>#000000</color>
</edge>
<edge>
<source>6</source>
<target>12</target>
<stroke>1</stroke>
<label>P/18</label>
<color>#000000</color>
</edge>
<edge>
<source>7</source>
<target>12</target>
<stroke>1</stroke>
<label>Q/10</label>
<color>#000000</color>
</edge>
<edge>
<source>8</source>
<target>15</target>
<stroke>1</stroke>
<label>R/20</label>
<color>#000000</color>
</edge>
<edge>
<source>10</source>
<target>13</target>
<stroke>1</stroke>
<label>S/3</label>
<color>#000000</color>
</edge>
<edge>
<source>12</source>
<target>15</target>
<stroke>1</stroke>
<label>T/18</label>
<color>#000000</color>
</edge>
<edge>
<source>13</source>
<target>15</target>
<stroke>2</stroke>
<label>U/8</label>
<color>#0000FF</color>
</edge>
<edge>
<source>14</source>
<target>15</target>
<stroke>1</stroke>
<label>V/10</label>
<color>#000000</color>
</edge>
<edge>
<source>3</source>
<target>13</target>
<stroke>1</stroke>
<label>W/1</label>
<color>#000000</color>
</edge>
<edge>
<source>7</source>
<target>9</target>
<stroke>1</stroke>
<label>X/19</label>
<color>#000000</color>
</edge>
<edge>
<source>9</source>
<target>13</target>
<stroke>1</stroke>
<label>Y/7</label>
<color>#000000</color>
</edge>
</edges>
</graph>

View File

@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--Created with Graph Editor-->
<graph title="PERT : exemple 2" type="PERT">
<nodes>
<node id="1">
<x>161</x>
<y>249</y>
<radius>20</radius>
<label>1</label>
<color>#FFFFFF</color>
<start>0</start>
<end>0</end>
</node>
<node id="2">
<x>343</x>
<y>251</y>
<radius>20</radius>
<label>2</label>
<color>#FFFFFF</color>
<start>9</start>
<end>9</end>
</node>
<node id="3">
<x>253</x>
<y>104</y>
<radius>20</radius>
<label>3</label>
<color>#FFFFFF</color>
<start>3</start>
<end>16</end>
</node>
<node id="4">
<x>447</x>
<y>373</y>
<radius>20</radius>
<label>4</label>
<color>#FFFFFF</color>
<start>16</start>
<end>23</end>
</node>
<node id="5">
<x>471</x>
<y>110</y>
<radius>20</radius>
<label>5</label>
<color>#FFFFFF</color>
<start>13</start>
<end>24</end>
</node>
<node id="6">
<x>617</x>
<y>251</y>
<radius>20</radius>
<label>6</label>
<color>#FFFFFF</color>
<start>29</start>
<end>29</end>
</node>
</nodes>
<edges>
<edge>
<source>1</source>
<target>3</target>
<stroke>1</stroke>
<label>A/3</label>
<color>#000000</color>
</edge>
<edge>
<source>3</source>
<target>5</target>
<stroke>1</stroke>
<label>D/8</label>
<color>#000000</color>
</edge>
<edge>
<source>1</source>
<target>2</target>
<stroke>2</stroke>
<label>B/9</label>
<color>#FF0000</color>
</edge>
<edge>
<source>2</source>
<target>5</target>
<stroke>1</stroke>
<label>E/4</label>
<color>#000000</color>
</edge>
<edge>
<source>1</source>
<target>4</target>
<stroke>1</stroke>
<label>C/5</label>
<color>#000000</color>
</edge>
<edge>
<source>2</source>
<target>4</target>
<stroke>1</stroke>
<label>F/7</label>
<color>#000000</color>
</edge>
<edge>
<source>5</source>
<target>6</target>
<stroke>1</stroke>
<label>I/5</label>
<color>#000000</color>
</edge>
<edge>
<source>2</source>
<target>6</target>
<stroke>2</stroke>
<label>G/20</label>
<color>#FF0000</color>
</edge>
<edge>
<source>4</source>
<target>6</target>
<stroke>1</stroke>
<label>H/6</label>
<color>#000000</color>
</edge>
</edges>
</graph>

125
graphs/pert-ex73-saved.xml Normal file
View File

@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--Created with Graph Editor-->
<graph title="PERT : exemple 1" type="PERT">
<nodes>
<node id="1">
<x>161</x>
<y>249</y>
<radius>20</radius>
<label>1</label>
<color>#FFFFFF</color>
<start>0</start>
<end>0</end>
</node>
<node id="2">
<x>343</x>
<y>251</y>
<radius>20</radius>
<label>2</label>
<color>#FFFFFF</color>
<start>9</start>
<end>9</end>
</node>
<node id="3">
<x>253</x>
<y>104</y>
<radius>20</radius>
<label>3</label>
<color>#FFFFFF</color>
<start>3</start>
<end>16</end>
</node>
<node id="4">
<x>447</x>
<y>373</y>
<radius>20</radius>
<label>4</label>
<color>#FFFFFF</color>
<start>16</start>
<end>23</end>
</node>
<node id="5">
<x>471</x>
<y>110</y>
<radius>20</radius>
<label>5</label>
<color>#FFFFFF</color>
<start>13</start>
<end>24</end>
</node>
<node id="6">
<x>617</x>
<y>251</y>
<radius>20</radius>
<label>6</label>
<color>#FFFFFF</color>
<start>29</start>
<end>29</end>
</node>
</nodes>
<edges>
<edge>
<source>1</source>
<target>3</target>
<stroke>1</stroke>
<label>A/3</label>
<color>#000000</color>
</edge>
<edge>
<source>3</source>
<target>5</target>
<stroke>1</stroke>
<label>D/8</label>
<color>#000000</color>
</edge>
<edge>
<source>1</source>
<target>2</target>
<stroke>2</stroke>
<label>B/9</label>
<color>#0000FF</color>
</edge>
<edge>
<source>2</source>
<target>5</target>
<stroke>1</stroke>
<label>E/4</label>
<color>#000000</color>
</edge>
<edge>
<source>1</source>
<target>4</target>
<stroke>1</stroke>
<label>C/5</label>
<color>#000000</color>
</edge>
<edge>
<source>2</source>
<target>4</target>
<stroke>1</stroke>
<label>F/7</label>
<color>#000000</color>
</edge>
<edge>
<source>5</source>
<target>6</target>
<stroke>1</stroke>
<label>I/5</label>
<color>#000000</color>
</edge>
<edge>
<source>2</source>
<target>6</target>
<stroke>2</stroke>
<label>G/20</label>
<color>#0000FF</color>
</edge>
<edge>
<source>4</source>
<target>6</target>
<stroke>1</stroke>
<label>H/6</label>
<color>#000000</color>
</edge>
</edges>
</graph>

125
graphs/pert-ex73.xml Normal file
View File

@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--Created with Graph Editor-->
<graph title="Untitled" type="PERT">
<nodes>
<node id="1">
<x>161</x>
<y>249</y>
<radius>20</radius>
<label>1</label>
<color>#FFFFFF</color>
<start>0</start>
<end>0</end>
</node>
<node id="2">
<x>343</x>
<y>251</y>
<radius>20</radius>
<label>2</label>
<color>#FFFFFF</color>
<start>9</start>
<end>9</end>
</node>
<node id="3">
<x>253</x>
<y>104</y>
<radius>20</radius>
<label>3</label>
<color>#FFFFFF</color>
<start>3</start>
<end>16</end>
</node>
<node id="4">
<x>447</x>
<y>373</y>
<radius>20</radius>
<label>4</label>
<color>#FFFFFF</color>
<start>16</start>
<end>23</end>
</node>
<node id="5">
<x>471</x>
<y>110</y>
<radius>20</radius>
<label>5</label>
<color>#FFFFFF</color>
<start>13</start>
<end>24</end>
</node>
<node id="6">
<x>617</x>
<y>251</y>
<radius>20</radius>
<label>6</label>
<color>#FFFFFF</color>
<start>29</start>
<end>29</end>
</node>
</nodes>
<edges>
<edge>
<source>1</source>
<target>3</target>
<stroke>1</stroke>
<label>A/3</label>
<color>#000000</color>
</edge>
<edge>
<source>3</source>
<target>5</target>
<stroke>1</stroke>
<label>D/8</label>
<color>#000000</color>
</edge>
<edge>
<source>1</source>
<target>2</target>
<stroke>2</stroke>
<label>B/9</label>
<color>#000000</color>
</edge>
<edge>
<source>2</source>
<target>5</target>
<stroke>1</stroke>
<label>E/4</label>
<color>#000000</color>
</edge>
<edge>
<source>1</source>
<target>4</target>
<stroke>1</stroke>
<label>C/5</label>
<color>#000000</color>
</edge>
<edge>
<source>2</source>
<target>4</target>
<stroke>1</stroke>
<label>F/7</label>
<color>#000000</color>
</edge>
<edge>
<source>5</source>
<target>6</target>
<stroke>1</stroke>
<label>I/5</label>
<color>#000000</color>
</edge>
<edge>
<source>2</source>
<target>6</target>
<stroke>2</stroke>
<label>G/20</label>
<color>#000000</color>
</edge>
<edge>
<source>4</source>
<target>6</target>
<stroke>1</stroke>
<label>H/6</label>
<color>#000000</color>
</edge>
</edges>
</graph>

View File

@@ -0,0 +1,203 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--Created with Graph Editor-->
<graph title="PERT : exemple 2" type="PERT">
<nodes>
<node id="0">
<x>663</x>
<y>229</y>
<radius>30</radius>
<label>0</label>
<color>#FFFFFF</color>
<start>0</start>
<end>0</end>
</node>
<node id="1">
<x>429</x>
<y>427</y>
<radius>30</radius>
<label>1</label>
<color>#FFFFFF</color>
<start>6</start>
<end>6</end>
</node>
<node id="2">
<x>445</x>
<y>858</y>
<radius>30</radius>
<label>2</label>
<color>#FFFFFF</color>
<start>14</start>
<end>20</end>
</node>
<node id="3">
<x>584</x>
<y>413</y>
<radius>30</radius>
<label>3</label>
<color>#FFFFFF</color>
<start>11</start>
<end>11</end>
</node>
<node id="4">
<x>579</x>
<y>568</y>
<radius>30</radius>
<label>4</label>
<color>#FFFFFF</color>
<start>13</start>
<end>13</end>
</node>
<node id="5">
<x>495</x>
<y>687</y>
<radius>30</radius>
<label>5</label>
<color>#FFFFFF</color>
<start>21</start>
<end>21</end>
</node>
<node id="6">
<x>725</x>
<y>503</y>
<radius>30</radius>
<label>6</label>
<color>#FFFFFF</color>
<start>20</start>
<end>28</end>
</node>
<node id="7">
<x>662</x>
<y>726</y>
<radius>30</radius>
<label>7</label>
<color>#FFFFFF</color>
<start>28</start>
<end>28</end>
</node>
<node id="8">
<x>895</x>
<y>537</y>
<radius>30</radius>
<label>8</label>
<color>#FFFFFF</color>
<start>28</start>
<end>28</end>
</node>
<node id="9">
<x>955</x>
<y>730</y>
<radius>30</radius>
<label>9</label>
<color>#FFFFFF</color>
<start>28</start>
<end>28</end>
</node>
</nodes>
<edges>
<edge>
<source>0</source>
<target>1</target>
<stroke>2</stroke>
<label>A/6</label>
<color>#FF0000</color>
</edge>
<edge>
<source>1</source>
<target>2</target>
<stroke>1</stroke>
<label>B/8</label>
<color>#000000</color>
</edge>
<edge>
<source>0</source>
<target>3</target>
<stroke>1</stroke>
<label>C/11</label>
<color>#000000</color>
</edge>
<edge>
<source>3</source>
<target>4</target>
<stroke>2</stroke>
<label>D/2</label>
<color>#FF0000</color>
</edge>
<edge>
<source>1</source>
<target>5</target>
<stroke>2</stroke>
<label>E/15</label>
<color>#FF0000</color>
</edge>
<edge>
<source>0</source>
<target>6</target>
<stroke>1</stroke>
<label>F/20</label>
<color>#000000</color>
</edge>
<edge>
<source>4</source>
<target>7</target>
<stroke>2</stroke>
<label>G/15</label>
<color>#FF0000</color>
</edge>
<edge>
<source>0</source>
<target>8</target>
<stroke>1</stroke>
<label>H/6</label>
<color>#000000</color>
</edge>
<edge>
<source>2</source>
<target>9</target>
<stroke>1</stroke>
<label>I/8</label>
<color>#000000</color>
</edge>
<edge>
<source>5</source>
<target>7</target>
<stroke>2</stroke>
<label>J/7</label>
<color>#FF0000</color>
</edge>
<edge>
<source>6</source>
<target>7</target>
<stroke>1</stroke>
<label>K/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>7</source>
<target>8</target>
<stroke>2</stroke>
<label>L/0</label>
<color>#FF0000</color>
</edge>
<edge>
<source>8</source>
<target>9</target>
<stroke>2</stroke>
<label>M/0</label>
<color>#FF0000</color>
</edge>
<edge>
<source>4</source>
<target>5</target>
<stroke>1</stroke>
<label>N/0</label>
<color>#0000FF</color>
</edge>
<edge>
<source>6</source>
<target>8</target>
<stroke>1</stroke>
<label>O/0</label>
<color>#0000FF</color>
</edge>
</edges>
</graph>

View File

@@ -0,0 +1,234 @@
package pert;
import java.awt.Color;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.jgrapht.graph.SimpleDirectedGraph;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import utils.TimingInterceptor;
public class GraphEditorUtils {
/**
* Charge un diagramme de PERT au format GraphEditor XML.
* @param fileName le chemin d'accès du fichier à lire
* @return le graphe du diagramme de PERT
*/
public static SimpleDirectedGraph<PertNode, PertEdge> loadGraph(String fileName) {
return parseGraphXml(new File(fileName));
}
/**
* Sauvegarde le graphe d'un diagramme de PERT au format GraphEditor XML.
* @param fileName le chemin d'accès du fichier à écrire
* @param graphTitle le titre du graphe
* @param graph le graphe du diagramme de PERT
*/
public static void saveGraph(String fileName, String graphTitle, SimpleDirectedGraph<PertNode, PertEdge> graph) {
try(PrintStream out = new PrintStream(fileName)){
out.print(generateGraphXml(graphTitle, graph));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/*
* Méthodes utilitaires
*/
private static String generateGraphXml(String title, SimpleDirectedGraph<PertNode, PertEdge> graph) {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
xml += "<!--Created with Graph Editor-->\n";
xml += "<graph title=\"" + title + "\" type=\"PERT\">\n";
xml += "<nodes>\n";
for (PertNode PertNode: graph.vertexSet()) {
xml += " <node id=\""+ PertNode.getId() +"\">\n";
xml += " <x>" + PertNode.getX() + "</x>\n";
xml += " <y>" + PertNode.getY() + "</y>\n";
xml += " <radius>" + PertNode.getRadius() + "</radius>\n";
xml += " <label>" + PertNode.getLabel() + "</label>\n";
String colorHex = "#" + Integer.toHexString(PertNode.getColor().getRGB()).substring(2).toUpperCase();
xml += " <color>" + colorHex + "</color>\n";
xml += " <start>" + PertNode.getStart() + "</start>\n";
xml += " <end>" + PertNode.getEnd() + "</end>\n";
xml += " </node>\n";
}
xml += "</nodes>\n";
xml += "<edges>\n";
for (PertEdge edge: graph.edgeSet()) {
xml += " <edge>\n";
xml += " <source>" + graph.getEdgeSource(edge).getId() + "</source>\n";
xml += " <target>" + graph.getEdgeTarget(edge).getId() + "</target>\n";
xml += " <stroke>" + edge.getStroke() + "</stroke>\n";
xml += " <label>" + edge.getTask() + "/" + edge.getDuration() + "</label>\n";
String colorHex = "#" + Integer.toHexString(edge.getColor().getRGB()).substring(2).toUpperCase();
xml += " <color>" + colorHex + "</color>\n";
xml += " </edge>\n";
}
xml += "</edges>\n";
xml += "</graph>\n";
return xml;
}
private static SimpleDirectedGraph<PertNode, PertEdge> parseGraphXml(File file) {
DocumentBuilder builder;
Document doc;
SimpleDirectedGraph<PertNode, PertEdge> graph = new SimpleDirectedGraph<>(PertEdge.class);
try {
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
doc = builder.parse(file);
doc.getDocumentElement().normalize();
// <graph title="xxx" type="Undirected|Directed|PERT">
Element graphElement = doc.getDocumentElement();
if (!"graph".equals(graphElement.getNodeName())) return null;
String type = graphElement.getAttribute("type");
if (!"PERT".equals(type)) return null;
// <nodes> ... </nodes>
NodeList nodes = graphElement.getElementsByTagName("node");
Map<Integer, PertNode> graphNodes = new HashMap<>();
int maxId = 1;
for (int i = 0; i < nodes.getLength(); i++) {
// <node> ... </node>
org.w3c.dom.Node node = nodes.item(i);
if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
Element element = (Element) node;
int id = Integer.valueOf(element.getAttribute("id"));
maxId = Math.max(maxId, id);
int x = getIntegerTag(element, "x");
int y = getIntegerTag(element, "y");
int radius = getIntegerTag(element, "radius");
String label = getStringTag(element, "label");
String color = getStringTag(element, "color");
int start = getIntegerTag(element, "start");
int end = getIntegerTag(element, "end");
PertNode newNode = new PertNode(id, x, y, radius, label, hexToColor(color), start, end);
graph.addVertex(newNode);
graphNodes.put(id, newNode);
}
}
// <edges> ... </edges>
NodeList edges = graphElement.getElementsByTagName("edge");
for (int i = 0; i < edges.getLength(); i++) {
org.w3c.dom.Node node = edges.item(i);
if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
// <edge> ... </edge>
Element element = (Element) node;
int source = getIntegerTag(element, "source");
int target = getIntegerTag(element, "target");
int stroke = getIntegerTag(element, "stroke");
String label = getStringTag(element, "label");
int sep = label.indexOf("/");
String task = (sep == -1) ? label : label.substring(0, sep);
int duration = (sep == -1) ? 0 : Integer.valueOf(label.substring(sep+1));
boolean critical = (stroke == 2);
graph.addEdge(graphNodes.get(source), graphNodes.get(target), new PertEdge(task, duration, critical));
}
}
return graph;
} catch (ParserConfigurationException | SAXException | IOException | IllegalArgumentException e) {
e.printStackTrace();
return null;
}
}
private static int getIntegerTag(Element element, String tagName) {
NodeList nodes = element.getElementsByTagName(tagName);
if (nodes.getLength() == 0) return 0;
String content = nodes.item(0).getTextContent();
if (Pattern.matches("^ *[+-]?[0-9]+ *$", content)) {
return Integer.parseInt(content);
} else {
return 0;
}
}
private static String getStringTag(Element element, String tagName) {
NodeList nodes = element.getElementsByTagName(tagName);
if (nodes.getLength() == 0) return "";
return nodes.item(0).getTextContent();
}
private static Color hexToColor(String color) {
try {
if (color.charAt(0) == '#') {
color = color.substring(1, 7);
}
int[] col = new int[3];
for (int i = 0; i < 3; i++) {
col[i] = Integer.parseInt(color.substring(i * 2, (i * 2) + 2), 16);
}
return new Color(col[0], col[1], col[2]);
} catch (Exception e) {
return Color.black;
}
}
/*
* Exemples d'utilisation
*/
public static void main(String[] args) {
// Load a PERT graph from a GraphEditor XML file
TimingInterceptor ti = new TimingInterceptor();
SimpleDirectedGraph<PertNode, PertEdge> pert1 = loadGraph("graphs/pert-ex73.xml");
// Save PERT graph to GraphEditor XML file
saveGraph("graphs/pert-ex73-saved.xml", "PERT : exemple 1", pert1);
// Create ex73 PERT graph from scratch
/*SimpleDirectedGraph<PertNode, PertEdge> pert2 = new SimpleDirectedGraph<>(PertEdge.class);
PertNode[] nodes = {new PertNode(1, 161, 249, 20, "1", Color.WHITE, 0, 0),
new PertNode(2, 343, 251, 20, "2", Color.WHITE, 9, 9),
new PertNode(3, 253, 104, 20, "3", Color.WHITE, 3, 16),
new PertNode(4, 447, 373, 20, "4", Color.WHITE, 16, 23),
new PertNode(5, 471, 110, 20, "5", Color.WHITE, 13, 24),
new PertNode(6, 617, 251, 20, "6", Color.WHITE, 29, 29)};
for (PertNode node : nodes) {
pert2.addVertex(node);
}
pert2.addEdge(nodes[0], nodes[2], new PertEdge("A", 3, false));
pert2.addEdge(nodes[2], nodes[4], new PertEdge("D", 8, false));
pert2.addEdge(nodes[0], nodes[1], new PertEdge("B", 9, true));
pert2.addEdge(nodes[1], nodes[4], new PertEdge("E", 4, false));
pert2.addEdge(nodes[0], nodes[3], new PertEdge("C", 5, false));
pert2.addEdge(nodes[1], nodes[3], new PertEdge("F", 7, false));
pert2.addEdge(nodes[4], nodes[5], new PertEdge("I", 5, false));
pert2.addEdge(nodes[1], nodes[5], new PertEdge("G", 20, true));
pert2.addEdge(nodes[3], nodes[5], new PertEdge("H", 6, false));*/
/*
N = 1000, T = 2000, F = 1000 → 0.65 sec
N = 1000, T = 200000, F = 1000 → 1.29 sec
N = 1000, T = 490000, F = 1000 → 2.52 sec
*/
//PertGenerator generator = new PertGenerator(1000, 2000, 1000, 20);
//PertGenerator generator = new PertGenerator(1000, 200000, 1000, 20);
//PertGenerator generator = new PertGenerator(1000, 490000, 1000, 20);
PertGenerator generator = new PertGenerator(15, 21, 4, 20);
ti.measureAndDisplay("Exercice generation", generator::generatePertExercise);
// Save PERT graph to GraphEditor XML file
saveGraph("graphs/first-graph-test.xml", "PERT : exemple 2", generator.getGraph());
ti.measureAndDisplay("Precedences calculation", generator::getPrecedences);
//Map<String, Set<String>> prec = generator.getPrecedences();
//System.out.println(prec);
}
}

62
src/pert/PertEdge.java Normal file
View File

@@ -0,0 +1,62 @@
package pert;
import java.awt.Color;
import org.jgrapht.graph.DefaultEdge;
public class PertEdge extends DefaultEdge {
private static final long serialVersionUID = 1L;
private final String task; // Nom de la tâche
private int duration; // Durée de la tâche
private boolean critical; // Indique si la tâche est critique (true)
public PertEdge(String task) {
this(task, 0, false);
}
public PertEdge(String task, int duration, boolean critical) {
this.task = "".equals(task) ? "?" : task;
this.duration = Math.max(0, duration);
this.critical = critical;
}
public Color getColor() {
return critical ? Color.BLUE : (duration == 0) ? Color.red : Color.black;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = Math.max(0, duration);
}
public boolean getCritical() {
return this.critical;
}
public void setCritical(boolean critical) {
this.critical = critical;
}
public int getStroke() {
return critical ? 2 : 1;
}
public String getTask() {
return task;
}
@Override
public String toString()
{
return "(" + getSource() + " : " + getTarget() + " : " + getTask() + "/" + getDuration() + ")";
}
@Override
public boolean equals(Object o) {
return (o instanceof PertEdge) && task.equals(((PertEdge)o).getTask());
}
}

277
src/pert/PertGenerator.java Normal file
View File

@@ -0,0 +1,277 @@
package pert;
import java.awt.*;
import java.util.*;
import java.util.List;
import org.jgrapht.Graphs;
import org.jgrapht.graph.SimpleDirectedGraph;
public class PertGenerator {
private int maxNodesCount;
private int maxRegularTasksCounts;
private int maxDummyCount;
private int maxDuration;
private int currentNodesCount;
private int currentDummyCount;
private int duplicatedSuccessorPool;
private Map<Integer, PertNode> idMap;
private SimpleDirectedGraph<PertNode, PertEdge> graph;
/**
* Instancie un générateur d'exercices de diagrammes de PERT.
* @param nbNodes Nombre total de sommets
* @param nbTasks Nombre de tâches régulières
* @param nbDummyTasks Nombre de tâches fictives
* @param maxDuration Durée maximale d'une tâche régulière
*/
public PertGenerator(int nbNodes, int nbTasks, int nbDummyTasks, int maxDuration) {
if(!checkConsistency(nbNodes, nbTasks, nbDummyTasks))
throw new IllegalArgumentException("Inconsistent graph");
this.maxNodesCount = nbNodes;
this.maxRegularTasksCounts = nbTasks;
this.maxDummyCount = nbDummyTasks;
this.maxDuration = maxDuration;
this.currentNodesCount = 0;
this.currentDummyCount = 0;
this.duplicatedSuccessorPool = (maxRegularTasksCounts + maxDummyCount) - (maxNodesCount-1);
this.idMap = new HashMap<>(maxNodesCount, 1f);
this.graph = new SimpleDirectedGraph<>(PertEdge.class);
}
/**
* @return graphe JGraphT du diagramme de PERT généré
*/
public SimpleDirectedGraph<PertNode, PertEdge> getGraph() {
return this.graph;
}
/**
* @return dictionnaire associant à chaque tâche l'ensemble des tâches prédécesseurs
*/
public Map<String, Set<String>> getPrecedences() {
Map<String, Set<String>> prec = new HashMap<>();
Map<PertNode, Set<String>> memo = new HashMap<>();
for (PertEdge edge : this.graph.edgeSet()) {
if (edge.getDuration() == 0) continue;
prec.put(edge.getTask(), getPredecessorsOf(graph.getEdgeSource(edge), memo));
}
return prec;
}
private Set<String> getPredecessorsOf(PertNode node, Map<PertNode, Set<String>> memo) {
if (memo.containsKey(node)) return memo.get(node);
Set<String> res = new HashSet<>();
for (PertEdge prec : graph.incomingEdgesOf(node)) {
if (prec.getDuration() == 0) {
res.addAll(getPredecessorsOf(graph.getEdgeSource(prec), memo));
} else {
res.add(prec.getTask());
}
}
memo.put(node, res);
return res;
}
/**
* Génère un diagramme de PERT aléatoire satisfaisant les contraintes données
*/
public void generatePertExercise() {
generateNodes();
generateTasks();
computeDeadlines();
}
private void generateNodes(){
linkToPreviousNode(generateNode(0, 0));
int x = 75;
int y = 75;
while(currentNodesCount < maxNodesCount-2) {
int nbNodes = randomValue(1, maxNodesCount - currentNodesCount - 2);
if(nbNodes == 0 || currentNodesCount+nbNodes >= maxNodesCount-1) break;
x += 75+(currentNodesCount);
y = 100+(currentNodesCount);
for (int j = 0; j < nbNodes; j++) {
y += 100;
PertNode node = generateNode(x, y);
linkToPreviousNode(node);
}
}
while(currentNodesCount < maxNodesCount){
y += 100+(currentNodesCount);
PertNode node = generateNode(x, y);
linkToPreviousNode(node);
}
}
private PertNode generateNode(int x, int y){
PertNode node = new PertNode(currentNodesCount+1, x, y, 30, String.valueOf(currentNodesCount+1), Color.WHITE, 0, 0);
this.idMap.put(node.getId(), node);
graph.addVertex(node);
currentNodesCount += 1;
return node;
}
private void linkToPreviousNode(PertNode node){
if(node.getId() == 1) return;
int duration;
if(duplicatedSuccessorPool == 0){
PertNode previousNode = this.idMap.get(node.getId()-1);
duration = generateDuration(previousNode.getId() == 1 || node.getId() == maxNodesCount);
linkNodes(previousNode, node, new PertEdge(generateLabel(), duration, false));
return;
}
int previousId = randomValue(1, node.getId()-1);
PertNode previousNode = this.idMap.get(previousId);
if(Graphs.vertexHasSuccessors(graph, previousNode)) duplicatedSuccessorPool -= 1;
duration = generateDuration(previousNode.getId() == 1 || node.getId() == maxNodesCount);
linkNodes(previousNode, node, new PertEdge(generateLabel(), duration, false));
}
private void generateTasks() {
List<PertNode> nodes = new ArrayList<>(this.graph.vertexSet());
int tasksCount = getTasksCount();
//Give the dangling nodes a successor
for(PertNode node : nodes){
if(node.getId() == maxNodesCount || Graphs.vertexHasSuccessors(graph, node)) continue;
int secondNodeIndex = randomValue(node.getId()+1, currentNodesCount-1);
PertNode secondNode = nodes.get(secondNodeIndex);
boolean isOnBorder = node.getId() == 1 || secondNode.getId() == 1 || secondNode.getId() == maxNodesCount;
int duration = this.generateDuration(isOnBorder);
this.linkNodes(node, secondNode, new PertEdge(generateLabel(), duration, false));
tasksCount = getTasksCount();
}
//Add the remaining tasks
while(tasksCount < maxRegularTasksCounts + maxDummyCount){
int firstNodeIndex;
int secondNodeIndex;
if(tasksCount < maxDummyCount){
firstNodeIndex = randomValue(1, currentNodesCount-2);
} else {
//-1 to handle index notation then -1 to avoid selecting the last node
firstNodeIndex = randomValue(0, currentNodesCount-2);
}
secondNodeIndex = randomValue(firstNodeIndex+1, currentNodesCount-1);
PertNode node1 = nodes.get(firstNodeIndex);
PertNode node2 = nodes.get(secondNodeIndex);
if (graph.containsEdge(node1, node2)) continue;
boolean isOnBorder = node1.getId() == 1 || node2.getId() == 1 || node1.getId() == maxNodesCount || node2.getId() == maxNodesCount;
int duration = generateDuration(isOnBorder);
this.linkNodes(node1, node2, new PertEdge(generateLabel(), duration, false));
tasksCount = getTasksCount();
}
}
private void linkNodes(PertNode node1, PertNode node2, PertEdge edge){
if(node1.getId() > node2.getId()){
graph.addEdge(node2, node1, edge);
} else {
graph.addEdge(node1, node2, edge);
}
}
private void computeDeadlines(){
List<PertNode> nodes = new ArrayList<>(this.graph.vertexSet());
computeStarts(nodes);
computeEnds(nodes);
}
private void computeStarts(List<PertNode> nodes){
for (PertNode node : nodes) {
if(node.getId() == 1) continue;
Set<PertEdge> edges = graph.incomingEdgesOf(node);
PertEdge longestPath = Collections.max(edges, (a, b) -> {
int startOfA = graph.getEdgeSource(a).getStart();
int startOfB = graph.getEdgeSource(b).getStart();
return (startOfA + a.getDuration()) - (startOfB + b.getDuration());
});
int previousStart = graph.getEdgeSource(longestPath).getStart();
int currentStart = previousStart + longestPath.getDuration();
node.setStart(currentStart);
if(node.getId() == maxNodesCount) node.setEnd(node.getStart());
}
}
private void computeEnds(List<PertNode> nodes){
for (int i = nodes.size()-1; i >= 0; i--){
PertNode node = nodes.get(i);
if(node.getId() == maxNodesCount) continue;
Set<PertEdge> edges = graph.outgoingEdgesOf(node);
PertEdge shortestPath = Collections.max(edges, (a, b) -> {
int endOfA = graph.getEdgeTarget(a).getEnd();
int endOfB = graph.getEdgeTarget(b).getEnd();
return (endOfB - b.getDuration()) - (endOfA - a.getDuration());
});
int nextEnd = graph.getEdgeTarget(shortestPath).getEnd();
int currentEnd = nextEnd - shortestPath.getDuration();
node.setEnd(currentEnd);
PertNode target = graph.getEdgeTarget(shortestPath);
if (node.getStart() == target.getEnd() - shortestPath.getDuration()) {
shortestPath.setCritical(true);
}
if(node.getId() == 1) node.setEnd(0);
}
}
private int generateDuration(boolean onBorderLayer){
if(currentDummyCount < maxDummyCount && !onBorderLayer){
currentDummyCount++;
return 0;
}
return randomValue(1, maxDuration);
}
private int getTasksCount(){
return this.graph.edgeSet().size();
}
private String generateLabel(){
StringBuilder bob = new StringBuilder();
int rest = graph.edgeSet().size()+1;
while (rest > 0) {
rest--;
char digit = (char) ('A' + (rest % 26));
bob.append(digit);
rest /= 26;
}
return bob.reverse().toString();
}
private int randomValue(int start, int end){
if(start >= end) return end;
return (int)((Math.random() * ((end+1) - start)) + start);
}
private boolean checkConsistency(long nodes, long regularTasks, long dummyTasks){
long maxTasksCount = (nodes * (nodes - 1)) / 2;
long unusableDummies = (2*nodes)-3;
return nodes-1 <= regularTasks
&& regularTasks + dummyTasks <= maxTasksCount;
}
}

110
src/pert/PertNode.java Normal file
View File

@@ -0,0 +1,110 @@
package pert;
import java.awt.Color;
public class PertNode {
private final int id; // Identifiant unique
private int x;
private int y;
private int radius;
private String label;
private Color color;
private int start; // Date de début au plus tôt
private int end; // Date de fin au plus tard
public PertNode(int id) {
this(id, 0, 0, 20, Integer.toString(id), Color.WHITE, 0, 0);
}
public PertNode(int id, int x, int y, int radius, String label,
Color color, int start, int end) {
this.id = id;
this.x = Math.max(0, x);
this.y = Math.max(0, y);
this.radius = Math.max(20, radius);
this.label = "".equals(label) ? Integer.toString(id) : label;
this.color = color;
this.start = Math.max(0, start);
this.end = Math.max(0, end);
}
public int getId() {
return this.id;
}
public int getX() {
return this.x;
}
public void setX(int x) {
this.x = Math.max(0, x);
}
public int getY() {
return this.y;
}
public void setY(int y) {
this.y = Math.max(0, y);
}
public int getRadius() {
return this.radius;
}
public void setRadius(int radius) {
this.radius = Math.max(20, radius);
}
public String getLabel() {
return this.label;
}
public void setLabel(String label){
if(label != null) {
this.label = label;
}
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
if(color == null)
this.color = Color.WHITE;
else
this.color = color;
}
public int getStart() {
return this.start;
}
public void setStart(int start){
this.start = Math.max(0, start);
}
public int getEnd() {
return this.end;
}
public void setEnd(int end){
this.end = Math.max(0, end);
}
@Override
public String toString() {
String colorHex = "#" + Integer.toHexString(color.getRGB()).substring(2).toUpperCase();
return String.format("id=%d, l='%s', x=%d, y=%d, r=%d, c=%s, start=%d, end=%d", id, label, x, y, radius, colorHex, start, end);
}
@Override
public int hashCode() {
return id;
}
@Override
public boolean equals(Object o) {
return (o instanceof PertNode) && (id == ((PertNode)o).getId());
}
}

View File

@@ -0,0 +1,8 @@
package tests;
public class ConsistencyTests {
}

View File

@@ -0,0 +1,4 @@
package tests;
public class CriticalPathTests {
}

View File

@@ -0,0 +1,34 @@
package utils;
public class TimingInterceptor{
private int duration;
public void measureAndDisplay(String name, Runnable func){
measureExecutionTime(func);
displayExecutionTime(name);
reset();
}
private void measureExecutionTime(Runnable func) {
long start, end;
start = System.currentTimeMillis();
func.run();
end = System.currentTimeMillis();
this.duration = (int)(end - start);
}
private void displayExecutionTime(String name){
System.out.printf("""
###############################
Name : %s
Duration : %dms
###############################
""", name, this.duration);
}
private void reset() { this.duration = 0; }
}